From 308e6272e26f202c7f450fda992d2a86e788d659 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Oct 2018 03:31:11 +0200 Subject: [PATCH] Removed more excess files. --- src - Cópia/86box.h | 165 - src - Cópia/Makefile.local | 164 - src - Cópia/bugger.c | 365 - src - Cópia/bugger.h | 48 - src - Cópia/cdrom/cdrom.c | 3274 ------- src - Cópia/cdrom/cdrom.h | 193 - src - Cópia/cdrom/cdrom_dosbox.cpp | 655 -- src - Cópia/cdrom/cdrom_dosbox.h | 175 - src - Cópia/cdrom/cdrom_image.cc | 1107 --- src - Cópia/cdrom/cdrom_image.h | 26 - src - Cópia/cdrom/cdrom_null.c | 161 - src - Cópia/cdrom/cdrom_null.h | 28 - src - Cópia/config.c | 2174 ----- src - Cópia/config.h | 54 - src - Cópia/cpu/386.c | 284 - src - Cópia/cpu/386.h | 5 - src - Cópia/cpu/386_common.h | 266 - src - Cópia/cpu/386_dynarec.c | 937 -- src - Cópia/cpu/386_dynarec_ops.c | 73 - src - Cópia/cpu/386_ops.h | 1637 ---- src - Cópia/cpu/808x.c | 3324 ------- src - Cópia/cpu/codegen.c | 26 - src - Cópia/cpu/codegen.h | 411 - src - Cópia/cpu/codegen_ops.c | 597 -- src - Cópia/cpu/codegen_ops.h | 46 - src - Cópia/cpu/codegen_ops_arith.h | 1028 --- src - Cópia/cpu/codegen_ops_fpu.h | 645 -- src - Cópia/cpu/codegen_ops_jump.h | 270 - src - Cópia/cpu/codegen_ops_logic.h | 564 -- src - Cópia/cpu/codegen_ops_misc.h | 269 - src - Cópia/cpu/codegen_ops_mmx.h | 277 - src - Cópia/cpu/codegen_ops_mov.h | 656 -- src - Cópia/cpu/codegen_ops_shift.h | 125 - src - Cópia/cpu/codegen_ops_stack.h | 269 - src - Cópia/cpu/codegen_ops_x86-64.h | 6185 ------------- src - Cópia/cpu/codegen_ops_x86.h | 3992 --------- src - Cópia/cpu/codegen_ops_xchg.h | 93 - src - Cópia/cpu/codegen_timing_486.c | 420 - src - Cópia/cpu/codegen_timing_686.c | 1056 --- src - Cópia/cpu/codegen_timing_common.c | 684 -- src - Cópia/cpu/codegen_timing_common.h | 226 - src - Cópia/cpu/codegen_timing_pentium.c | 1322 --- src - Cópia/cpu/codegen_timing_winchip.c | 420 - src - Cópia/cpu/codegen_x86-64.c | 1195 --- src - Cópia/cpu/codegen_x86-64.h | 23 - src - Cópia/cpu/codegen_x86.c | 2179 ----- src - Cópia/cpu/codegen_x86.h | 42 - src - Cópia/cpu/cpu.c | 2277 ----- src - Cópia/cpu/cpu.h | 473 - src - Cópia/cpu/cpu_table.c | 455 - src - Cópia/cpu/x86.h | 107 - src - Cópia/cpu/x86_flags.h | 521 -- src - Cópia/cpu/x86_ops.h | 233 - src - Cópia/cpu/x86_ops_amd.h | 192 - src - Cópia/cpu/x86_ops_arith.h | 744 -- src - Cópia/cpu/x86_ops_atomic.h | 278 - src - Cópia/cpu/x86_ops_bcd.h | 113 - src - Cópia/cpu/x86_ops_bit.h | 312 - src - Cópia/cpu/x86_ops_bitscan.h | 143 - src - Cópia/cpu/x86_ops_call.h | 401 - src - Cópia/cpu/x86_ops_flag.h | 284 - src - Cópia/cpu/x86_ops_fpu.h | 85 - src - Cópia/cpu/x86_ops_i686.h | 508 -- src - Cópia/cpu/x86_ops_inc_dec.h | 89 - src - Cópia/cpu/x86_ops_int.h | 91 - src - Cópia/cpu/x86_ops_io.h | 146 - src - Cópia/cpu/x86_ops_jump.h | 358 - src - Cópia/cpu/x86_ops_misc.h | 941 -- src - Cópia/cpu/x86_ops_mmx.h | 48 - src - Cópia/cpu/x86_ops_mmx_arith.h | 625 -- src - Cópia/cpu/x86_ops_mmx_cmp.h | 205 - src - Cópia/cpu/x86_ops_mmx_logic.h | 91 - src - Cópia/cpu/x86_ops_mmx_mov.h | 161 - src - Cópia/cpu/x86_ops_mmx_pack.h | 324 - src - Cópia/cpu/x86_ops_mmx_shift.h | 452 - src - Cópia/cpu/x86_ops_mov.h | 757 -- src - Cópia/cpu/x86_ops_mov_ctrl.h | 304 - src - Cópia/cpu/x86_ops_mov_seg.h | 412 - src - Cópia/cpu/x86_ops_movx.h | 181 - src - Cópia/cpu/x86_ops_msr.h | 30 - src - Cópia/cpu/x86_ops_mul.h | 234 - src - Cópia/cpu/x86_ops_pmode.h | 439 - src - Cópia/cpu/x86_ops_prefix.h | 161 - src - Cópia/cpu/x86_ops_rep.h | 643 -- src - Cópia/cpu/x86_ops_ret.h | 261 - src - Cópia/cpu/x86_ops_set.h | 33 - src - Cópia/cpu/x86_ops_shift.h | 608 -- src - Cópia/cpu/x86_ops_stack.h | 517 -- src - Cópia/cpu/x86_ops_string.h | 477 - src - Cópia/cpu/x86_ops_xchg.h | 216 - src - Cópia/cpu/x86seg.c | 2555 ------ src - Cópia/cpu/x86seg.h | 18 - src - Cópia/cpu/x87.c | 77 - src - Cópia/cpu/x87.h | 8 - src - Cópia/cpu/x87_ops.h | 1775 ---- src - Cópia/cpu/x87_ops_arith.h | 431 - src - Cópia/cpu/x87_ops_loadstore.h | 488 - src - Cópia/cpu/x87_ops_misc.h | 861 -- src - Cópia/crcspeed/crc64speed.c | 275 - src - Cópia/crcspeed/crc64speed.h | 20 - src - Cópia/crcspeed/crcspeed.c | 281 - src - Cópia/crcspeed/crcspeed.h | 60 - src - Cópia/device.c | 478 - src - Cópia/device.h | 147 - src - Cópia/disk/hdc.c | 261 - src - Cópia/disk/hdc.h | 74 - src - Cópia/disk/hdc_esdi_at.c | 856 -- src - Cópia/disk/hdc_esdi_mca.c | 1107 --- src - Cópia/disk/hdc_ide.c | 3023 ------- src - Cópia/disk/hdc_ide.h | 93 - src - Cópia/disk/hdc_mfm_at.c | 769 -- src - Cópia/disk/hdc_mfm_xt.c | 949 -- src - Cópia/disk/hdc_xta.c | 1161 --- src - Cópia/disk/hdc_xtide.c | 284 - src - Cópia/disk/hdd.c | 150 - src - Cópia/disk/hdd.h | 132 - src - Cópia/disk/hdd_image.c | 525 -- src - Cópia/disk/hdd_table.c | 173 - src - Cópia/disk/zip.c | 2787 ------ src - Cópia/disk/zip.h | 156 - src - Cópia/dma.c | 917 -- src - Cópia/dma.h | 94 - src - Cópia/floppy/fdc.c | 2258 ----- src - Cópia/floppy/fdc.h | 196 - src - Cópia/floppy/fdd.c | 757 -- src - Cópia/floppy/fdd.h | 264 - src - Cópia/floppy/fdd_86f.c | 3884 -------- src - Cópia/floppy/fdd_86f.h | 89 - src - Cópia/floppy/fdd_common.c | 458 - src - Cópia/floppy/fdd_common.h | 53 - src - Cópia/floppy/fdd_fdi.c | 429 - src - Cópia/floppy/fdd_fdi.h | 49 - src - Cópia/floppy/fdd_imd.c | 872 -- src - Cópia/floppy/fdd_imd.h | 46 - src - Cópia/floppy/fdd_img.c | 1243 --- src - Cópia/floppy/fdd_img.h | 49 - src - Cópia/floppy/fdd_json.c | 719 -- src - Cópia/floppy/fdd_json.h | 56 - src - Cópia/floppy/fdd_td0.c | 1245 --- src - Cópia/floppy/fdd_td0.h | 46 - src - Cópia/floppy/fdi2raw.c | 2206 ----- src - Cópia/floppy/fdi2raw.h | 72 - src - Cópia/floppy/lzf/Changes | 136 - src - Cópia/floppy/lzf/LICENSE | 27 - src - Cópia/floppy/lzf/Makefile.in | 66 - src - Cópia/floppy/lzf/README | 29 - src - Cópia/floppy/lzf/config.h | 16 - src - Cópia/floppy/lzf/configure | 7871 ---------------- src - Cópia/floppy/lzf/configure.ac | 25 - src - Cópia/floppy/lzf/crc32.h | 65 - src - Cópia/floppy/lzf/install-sh | 251 - src - Cópia/floppy/lzf/lzf.c | 537 -- src - Cópia/floppy/lzf/lzf.h | 100 - src - Cópia/floppy/lzf/lzfP.h | 185 - src - Cópia/floppy/lzf/lzf_c.c | 293 - src - Cópia/floppy/lzf/lzf_d.c | 185 - src - Cópia/game/gameport.c | 334 - src - Cópia/game/gameport.h | 148 - .../game/joystick_ch_flightstick_pro.c | 132 - .../game/joystick_ch_flightstick_pro.h | 38 - src - Cópia/game/joystick_standard.c | 261 - src - Cópia/game/joystick_standard.h | 41 - src - Cópia/game/joystick_sw_pad.c | 288 - src - Cópia/game/joystick_sw_pad.h | 38 - src - Cópia/game/joystick_tm_fcs.c | 131 - src - Cópia/game/joystick_tm_fcs.h | 38 - src - Cópia/gcc_check.sh | 1 - src - Cópia/gcc_check_ioctl.sh | 1 - src - Cópia/i82335.c | 137 - src - Cópia/i82335.h | 1 - src - Cópia/intel.c | 70 - src - Cópia/intel.h | 5 - src - Cópia/intel_flash.c | 327 - src - Cópia/intel_flash.h | 22 - src - Cópia/intel_piix.c | 916 -- src - Cópia/intel_piix4.c | 393 - src - Cópia/intel_sio.c | 207 - src - Cópia/intel_sio.h | 17 - src - Cópia/io.c | 415 - src - Cópia/io.h | 72 - src - Cópia/keyboard.c | 331 - src - Cópia/keyboard.h | 103 - src - Cópia/keyboard_at.c | 2109 ----- src - Cópia/keyboard_xt.c | 595 -- src - Cópia/lang/language.h | 186 - src - Cópia/lpt.c | 211 - src - Cópia/lpt.h | 26 - src - Cópia/machine/m_amstrad.c | 1296 --- src - Cópia/machine/m_at.c | 109 - src - Cópia/machine/m_at_4x0.c | 919 -- src - Cópia/machine/m_at_ali1429.c | 113 - src - Cópia/machine/m_at_commodore.c | 55 - src - Cópia/machine/m_at_compaq.c | 137 - src - Cópia/machine/m_at_headland.c | 81 - src - Cópia/machine/m_at_neat.c | 109 - src - Cópia/machine/m_at_opti495.c | 347 - src - Cópia/machine/m_at_scat.c | 1397 --- src - Cópia/machine/m_at_sis_85c471.c | 251 - src - Cópia/machine/m_at_sis_85c496.c | 230 - src - Cópia/machine/m_at_sis_85c50x.c | 323 - src - Cópia/machine/m_at_t3100e.c | 782 -- src - Cópia/machine/m_at_t3100e.h | 58 - src - Cópia/machine/m_at_t3100e_vid.c | 762 -- src - Cópia/machine/m_at_wd76c10.c | 154 - src - Cópia/machine/m_europc.c | 767 -- src - Cópia/machine/m_olivetti_m24.c | 874 -- src - Cópia/machine/m_pcjr.c | 777 -- src - Cópia/machine/m_ps1.c | 568 -- src - Cópia/machine/m_ps1_hdc.c | 1364 --- src - Cópia/machine/m_ps2_isa.c | 163 - src - Cópia/machine/m_ps2_mca.c | 1256 --- src - Cópia/machine/m_tandy.c | 1781 ---- src - Cópia/machine/m_xt.c | 29 - src - Cópia/machine/m_xt_compaq.c | 58 - src - Cópia/machine/m_xt_laserxt.c | 140 - src - Cópia/machine/m_xt_t1000.c | 1087 --- src - Cópia/machine/m_xt_t1000.h | 59 - src - Cópia/machine/m_xt_t1000_vid.c | 749 -- src - Cópia/machine/m_xt_xi8088.c | 135 - src - Cópia/machine/m_xt_xi8088.h | 8 - src - Cópia/machine/machine.c | 109 - src - Cópia/machine/machine.h | 217 - src - Cópia/machine/machine_table.c | 266 - src - Cópia/mca.c | 68 - src - Cópia/mca.h | 7 - src - Cópia/mcr.c | 39 - src - Cópia/mem.c | 1926 ---- src - Cópia/mem.h | 288 - src - Cópia/memregs.c | 63 - src - Cópia/memregs.h | 25 - src - Cópia/mouse.c | 255 - src - Cópia/mouse.h | 81 - src - Cópia/mouse_bus - Cópia (2).c | 876 -- src - Cópia/mouse_bus - Cópia (3).c | 632 -- src - Cópia/mouse_bus - Cópia (4).c | 805 -- src - Cópia/mouse_bus - Cópia 2.c | 877 -- src - Cópia/mouse_bus - Cópia.c | 794 -- src - Cópia/mouse_bus.c | 789 -- src - Cópia/mouse_bus_good.c | 879 -- src - Cópia/mouse_bus_x.c | 795 -- src - Cópia/mouse_ps2.c | 319 - src - Cópia/mouse_serial.c | 324 - src - Cópia/network/bswap.h | 231 - src - Cópia/network/net_ne2000.c | 2846 ------ src - Cópia/network/net_ne2000.h | 54 - src - Cópia/network/net_pcap.c | 431 - src - Cópia/network/net_slirp.c | 277 - src - Cópia/network/network.c | 428 - src - Cópia/network/network.h | 132 - src - Cópia/network/pcap_if.c | 312 - src - Cópia/network/slirp/COPYRIGHT.txt | 61 - src - Cópia/network/slirp/VERSION.txt | 1 - src - Cópia/network/slirp/bootp.c | 242 - src - Cópia/network/slirp/bootp.h | 121 - src - Cópia/network/slirp/cksum.c | 137 - src - Cópia/network/slirp/config-host.h | 9 - src - Cópia/network/slirp/config.h | 9 - src - Cópia/network/slirp/ctl.h | 7 - src - Cópia/network/slirp/debug.c | 445 - src - Cópia/network/slirp/debug.h | 49 - src - Cópia/network/slirp/icmp_var.h | 65 - src - Cópia/network/slirp/if.c | 322 - src - Cópia/network/slirp/if.h | 50 - src - Cópia/network/slirp/ip.h | 354 - src - Cópia/network/slirp/ip_icmp.c | 366 - src - Cópia/network/slirp/ip_icmp.h | 168 - src - Cópia/network/slirp/ip_input.c | 694 -- src - Cópia/network/slirp/ip_output.c | 202 - src - Cópia/network/slirp/libslirp.h | 41 - src - Cópia/network/slirp/main.h | 54 - src - Cópia/network/slirp/mbuf.c | 248 - src - Cópia/network/slirp/mbuf.h | 143 - src - Cópia/network/slirp/misc.c | 972 -- src - Cópia/network/slirp/misc.h | 87 - src - Cópia/network/slirp/queue.c | 116 - src - Cópia/network/slirp/queue.h | 101 - src - Cópia/network/slirp/sbuf.c | 202 - src - Cópia/network/slirp/sbuf.h | 31 - src - Cópia/network/slirp/slirp.c | 710 -- src - Cópia/network/slirp/slirp.h | 441 - src - Cópia/network/slirp/slirp_config.h | 135 - src - Cópia/network/slirp/socket.c | 734 -- src - Cópia/network/slirp/socket.h | 104 - src - Cópia/network/slirp/tcp.h | 185 - src - Cópia/network/slirp/tcp_input.c | 1721 ---- src - Cópia/network/slirp/tcp_output.c | 601 -- src - Cópia/network/slirp/tcp_subr.c | 1327 --- src - Cópia/network/slirp/tcp_timer.c | 322 - src - Cópia/network/slirp/tcp_timer.h | 138 - src - Cópia/network/slirp/tcp_var.h | 256 - src - Cópia/network/slirp/tcpip.h | 70 - src - Cópia/network/slirp/tftp.c | 332 - src - Cópia/network/slirp/tftp.h | 40 - src - Cópia/network/slirp/udp.c | 681 -- src - Cópia/network/slirp/udp.h | 114 - src - Cópia/nmi.c | 25 - src - Cópia/nmi.h | 10 - src - Cópia/nvr.c | 371 - src - Cópia/nvr.h | 101 - src - Cópia/nvr_at.c | 746 -- src - Cópia/nvr_ps2.c | 174 - src - Cópia/nvr_ps2.h | 44 - src - Cópia/pc.c | 1144 --- src - Cópia/pci.c | 762 -- src - Cópia/pci.h | 57 - src - Cópia/pci_dummy.c | 242 - src - Cópia/pci_dummy.h | 1 - src - Cópia/pic.c | 536 -- src - Cópia/pic.h | 29 - src - Cópia/piix.h | 26 - src - Cópia/pit.c | 651 -- src - Cópia/pit.h | 74 - src - Cópia/plat.h | 152 - src - Cópia/plat_dynld.h | 30 - src - Cópia/plat_midi.h | 8 - src - Cópia/ppi.c | 26 - src - Cópia/ppi.h | 18 - src - Cópia/random.c | 92 - src - Cópia/random.h | 25 - src - Cópia/rom.c | 968 -- src - Cópia/rom.h | 195 - src - Cópia/scsi/scsi.c | 237 - src - Cópia/scsi/scsi.h | 367 - src - Cópia/scsi/scsi_aha154x.c | 1145 --- src - Cópia/scsi/scsi_aha154x.h | 13 - src - Cópia/scsi/scsi_bus.c | 366 - src - Cópia/scsi/scsi_buslogic.c | 1817 ---- src - Cópia/scsi/scsi_buslogic.h | 32 - src - Cópia/scsi/scsi_device.c | 403 - src - Cópia/scsi/scsi_device.h | 60 - src - Cópia/scsi/scsi_disk.c | 1331 --- src - Cópia/scsi/scsi_disk.h | 60 - src - Cópia/scsi/scsi_ncr5380.c | 1090 --- src - Cópia/scsi/scsi_ncr5380.h | 33 - src - Cópia/scsi/scsi_ncr53c810.c | 2215 ----- src - Cópia/scsi/scsi_ncr53c810.h | 31 - src - Cópia/scsi/scsi_x54x.c | 1986 ----- src - Cópia/scsi/scsi_x54x.h | 510 -- src - Cópia/serial.c | 386 - src - Cópia/serial.h | 119 - src - Cópia/sio.h | 31 - src - Cópia/sio_detect.c | 64 - src - Cópia/sio_fdc37c669.c | 328 - src - Cópia/sio_fdc37c66x.c | 331 - src - Cópia/sio_fdc37c93x.c | 567 -- src - Cópia/sio_pc87306.c | 455 - src - Cópia/sio_um8669f.c | 295 - src - Cópia/sio_w83877f.c | 538 -- src - Cópia/sound/dbopl.cpp | 1512 ---- src - Cópia/sound/dbopl.h | 259 - src - Cópia/sound/filters.h | 377 - src - Cópia/sound/midi.c | 260 - src - Cópia/sound/midi.h | 45 - src - Cópia/sound/midi_fluidsynth.c | 578 -- src - Cópia/sound/midi_fluidsynth.h | 1 - src - Cópia/sound/midi_mt32.c | 330 - src - Cópia/sound/midi_mt32.h | 2 - src - Cópia/sound/midi_system.c | 66 - src - Cópia/sound/midi_system.h | 1 - src - Cópia/sound/munt/Analog.cpp | 424 - src - Cópia/sound/munt/Analog.h | 53 - src - Cópia/sound/munt/BReverbModel.cpp | 662 -- src - Cópia/sound/munt/BReverbModel.h | 48 - src - Cópia/sound/munt/Enumerations.h | 187 - src - Cópia/sound/munt/File.cpp | 77 - src - Cópia/sound/munt/File.h | 73 - src - Cópia/sound/munt/FileStream.cpp | 83 - src - Cópia/sound/munt/FileStream.h | 46 - .../sound/munt/LA32FloatWaveGenerator.cpp | 359 - .../sound/munt/LA32FloatWaveGenerator.h | 132 - src - Cópia/sound/munt/LA32Ramp.cpp | 164 - src - Cópia/sound/munt/LA32Ramp.h | 47 - src - Cópia/sound/munt/LA32WaveGenerator.cpp | 423 - src - Cópia/sound/munt/LA32WaveGenerator.h | 266 - src - Cópia/sound/munt/MemoryRegion.h | 132 - src - Cópia/sound/munt/MidiEventQueue.h | 71 - src - Cópia/sound/munt/MidiStreamParser.cpp | 289 - src - Cópia/sound/munt/MidiStreamParser.h | 124 - src - Cópia/sound/munt/Part.cpp | 702 -- src - Cópia/sound/munt/Part.h | 153 - src - Cópia/sound/munt/Partial.cpp | 407 - src - Cópia/sound/munt/Partial.h | 130 - src - Cópia/sound/munt/PartialManager.cpp | 298 - src - Cópia/sound/munt/PartialManager.h | 64 - src - Cópia/sound/munt/Poly.cpp | 190 - src - Cópia/sound/munt/Poly.h | 70 - src - Cópia/sound/munt/ROMInfo.cpp | 119 - src - Cópia/sound/munt/ROMInfo.h | 80 - .../sound/munt/SampleRateConverter.cpp | 110 - src - Cópia/sound/munt/SampleRateConverter.h | 71 - .../sound/munt/SampleRateConverter_dummy.cpp | 63 - src - Cópia/sound/munt/Structures.h | 265 - src - Cópia/sound/munt/Synth.cpp | 2359 ----- src - Cópia/sound/munt/Synth.h | 500 -- src - Cópia/sound/munt/TVA.cpp | 381 - src - Cópia/sound/munt/TVA.h | 100 - src - Cópia/sound/munt/TVF.cpp | 240 - src - Cópia/sound/munt/TVF.h | 61 - src - Cópia/sound/munt/TVP.cpp | 350 - src - Cópia/sound/munt/TVP.h | 73 - src - Cópia/sound/munt/Tables.cpp | 97 - src - Cópia/sound/munt/Tables.h | 62 - src - Cópia/sound/munt/Types.h | 32 - .../sound/munt/c_interface/c_interface.cpp | 719 -- .../sound/munt/c_interface/c_interface.h | 434 - src - Cópia/sound/munt/c_interface/c_types.h | 336 - .../sound/munt/c_interface/cpp_interface.h | 479 - src - Cópia/sound/munt/config.h | 40 - src - Cópia/sound/munt/globals.h | 119 - src - Cópia/sound/munt/internals.h | 118 - src - Cópia/sound/munt/mmath.h | 68 - src - Cópia/sound/munt/mt32emu.h | 84 - src - Cópia/sound/munt/sha1/sha1.cpp | 185 - src - Cópia/sound/munt/sha1/sha1.h | 49 - .../sound/munt/srchelper/InternalResampler.cpp | 74 - .../sound/munt/srchelper/InternalResampler.h | 42 - .../sound/munt/srchelper/SamplerateAdapter.cpp | 99 - .../sound/munt/srchelper/SamplerateAdapter.h | 48 - .../sound/munt/srchelper/SoxrAdapter.cpp | 106 - .../sound/munt/srchelper/SoxrAdapter.h | 45 - .../srchelper/srctools/include/FIRResampler.h | 67 - .../srctools/include/FloatSampleProvider.h | 34 - .../srctools/include/IIR2xResampler.h | 100 - .../srctools/include/LinearResampler.h | 42 - .../srctools/include/ResamplerModel.h | 63 - .../srctools/include/ResamplerStage.h | 38 - .../srchelper/srctools/include/SincResampler.h | 46 - .../srchelper/srctools/src/FIRResampler.cpp | 107 - .../srchelper/srctools/src/IIR2xResampler.cpp | 229 - .../srchelper/srctools/src/LinearResampler.cpp | 47 - .../srchelper/srctools/src/ResamplerModel.cpp | 153 - .../srchelper/srctools/src/SincResampler.cpp | 136 - src - Cópia/sound/nukedopl.cpp | 1387 --- src - Cópia/sound/nukedopl.h | 150 - src - Cópia/sound/openal.c | 276 - src - Cópia/sound/resid-fp/AUTHORS | 4 - src - Cópia/sound/resid-fp/COPYING | 340 - src - Cópia/sound/resid-fp/ChangeLog | 136 - src - Cópia/sound/resid-fp/INSTALL | 14 - src - Cópia/sound/resid-fp/Makefile.am | 29 - src - Cópia/sound/resid-fp/Makefile.in | 557 -- src - Cópia/sound/resid-fp/NEWS | 1 - src - Cópia/sound/resid-fp/README | 79 - src - Cópia/sound/resid-fp/README.VICE | 14 - src - Cópia/sound/resid-fp/aclocal.m4 | 850 -- src - Cópia/sound/resid-fp/configure | 5955 ------------- src - Cópia/sound/resid-fp/configure.in | 166 - src - Cópia/sound/resid-fp/convolve-sse.cc | 76 - src - Cópia/sound/resid-fp/convolve.cc | 27 - src - Cópia/sound/resid-fp/envelope.cc | 254 - src - Cópia/sound/resid-fp/envelope.h | 174 - src - Cópia/sound/resid-fp/extfilt.cc | 94 - src - Cópia/sound/resid-fp/extfilt.h | 120 - src - Cópia/sound/resid-fp/filter.cc | 194 - src - Cópia/sound/resid-fp/filter.h | 383 - src - Cópia/sound/resid-fp/pot.cc | 26 - src - Cópia/sound/resid-fp/pot.h | 31 - src - Cópia/sound/resid-fp/samp2src.pl | 65 - src - Cópia/sound/resid-fp/sid.cc | 944 -- src - Cópia/sound/resid-fp/sid.h | 130 - src - Cópia/sound/resid-fp/siddefs-fp.h | 88 - src - Cópia/sound/resid-fp/siddefs-fp.h.in | 87 - src - Cópia/sound/resid-fp/version.cc | 21 - src - Cópia/sound/resid-fp/voice.cc | 102 - src - Cópia/sound/resid-fp/voice.h | 73 - src - Cópia/sound/resid-fp/wave.cc | 151 - src - Cópia/sound/resid-fp/wave.h | 457 - src - Cópia/sound/resid-fp/wave6581_PST.cc | 536 -- src - Cópia/sound/resid-fp/wave6581_PST.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave6581_PS_.cc | 536 -- src - Cópia/sound/resid-fp/wave6581_PS_.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave6581_P_T.cc | 536 -- src - Cópia/sound/resid-fp/wave6581_P_T.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave6581__ST.cc | 536 -- src - Cópia/sound/resid-fp/wave6581__ST.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave8580_PST.cc | 536 -- src - Cópia/sound/resid-fp/wave8580_PST.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave8580_PS_.cc | 536 -- src - Cópia/sound/resid-fp/wave8580_PS_.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave8580_P_T.cc | 536 -- src - Cópia/sound/resid-fp/wave8580_P_T.dat | Bin 4096 -> 0 bytes src - Cópia/sound/resid-fp/wave8580__ST.cc | 536 -- src - Cópia/sound/resid-fp/wave8580__ST.dat | Bin 4096 -> 0 bytes src - Cópia/sound/snd_ad1848.c | 223 - src - Cópia/sound/snd_ad1848.h | 35 - src - Cópia/sound/snd_adlib.c | 137 - src - Cópia/sound/snd_adlib.h | 2 - src - Cópia/sound/snd_adlibgold.c | 851 -- src - Cópia/sound/snd_adlibgold.h | 1 - src - Cópia/sound/snd_audiopci.c | 1309 --- src - Cópia/sound/snd_audiopci.h | 1 - src - Cópia/sound/snd_cms.c | 204 - src - Cópia/sound/snd_cms.h | 1 - src - Cópia/sound/snd_dbopl.cc | 187 - src - Cópia/sound/snd_dbopl.h | 17 - src - Cópia/sound/snd_emu8k.c | 2386 ----- src - Cópia/sound/snd_emu8k.h | 775 -- src - Cópia/sound/snd_gus.c | 1067 --- src - Cópia/sound/snd_gus.h | 1 - src - Cópia/sound/snd_lpt_dac.c | 124 - src - Cópia/sound/snd_lpt_dac.h | 2 - src - Cópia/sound/snd_lpt_dss.c | 120 - src - Cópia/sound/snd_lpt_dss.h | 1 - src - Cópia/sound/snd_mpu401.c | 984 -- src - Cópia/sound/snd_mpu401.h | 94 - src - Cópia/sound/snd_opl.c | 185 - src - Cópia/sound/snd_opl.h | 33 - src - Cópia/sound/snd_pas16.c | 780 -- src - Cópia/sound/snd_pas16.h | 1 - src - Cópia/sound/snd_pssj.c | 218 - src - Cópia/sound/snd_pssj.h | 1 - src - Cópia/sound/snd_resid.cc | 112 - src - Cópia/sound/snd_resid.h | 12 - src - Cópia/sound/snd_sb.c | 1954 ---- src - Cópia/sound/snd_sb.h | 47 - src - Cópia/sound/snd_sb_dsp.c | 1144 --- src - Cópia/sound/snd_sb_dsp.h | 90 - src - Cópia/sound/snd_sn76489.c | 253 - src - Cópia/sound/snd_sn76489.h | 33 - src - Cópia/sound/snd_speaker.c | 68 - src - Cópia/sound/snd_speaker.h | 8 - src - Cópia/sound/snd_ssi2001.c | 90 - src - Cópia/sound/snd_ssi2001.h | 1 - src - Cópia/sound/snd_wss.c | 124 - src - Cópia/sound/snd_wss.h | 1 - src - Cópia/sound/snd_ym7128.c | 138 - src - Cópia/sound/snd_ym7128.h | 25 - src - Cópia/sound/sound.c | 573 -- src - Cópia/sound/sound.h | 72 - src - Cópia/src_20170607.rar | Bin 1983925 -> 0 bytes src - Cópia/timer.c | 137 - src - Cópia/timer.h | 57 - src - Cópia/ui.h | 73 - src - Cópia/usb.c | 53 - src - Cópia/usb.h | 41 - src - Cópia/video/vid_ati18800.c | 305 - src - Cópia/video/vid_ati18800.h | 6 - src - Cópia/video/vid_ati28800.c | 645 -- src - Cópia/video/vid_ati28800.h | 9 - src - Cópia/video/vid_ati68860_ramdac.c | 197 - src - Cópia/video/vid_ati68860_ramdac.h | 20 - src - Cópia/video/vid_ati_eeprom.c | 235 - src - Cópia/video/vid_ati_eeprom.h | 19 - src - Cópia/video/vid_ati_mach64.c | 3513 -------- src - Cópia/video/vid_ati_mach64.h | 22 - src - Cópia/video/vid_bt485_ramdac.c | 192 - src - Cópia/video/vid_bt485_ramdac.h | 18 - src - Cópia/video/vid_cga.c | 598 -- src - Cópia/video/vid_cga.h | 65 - src - Cópia/video/vid_cga_comp.c | 345 - src - Cópia/video/vid_cga_comp.h | 27 - src - Cópia/video/vid_cl54xx.c | 2691 ------ src - Cópia/video/vid_cl54xx.h | 19 - src - Cópia/video/vid_colorplus.c | 477 - src - Cópia/video/vid_colorplus.h | 15 - src - Cópia/video/vid_compaq_cga.c | 461 - src - Cópia/video/vid_compaq_cga.h | 11 - src - Cópia/video/vid_ega.c | 1293 --- src - Cópia/video/vid_ega.h | 149 - src - Cópia/video/vid_ega_render.c | 550 -- src - Cópia/video/vid_ega_render.h | 39 - src - Cópia/video/vid_et4000.c | 218 - src - Cópia/video/vid_et4000.h | 4 - src - Cópia/video/vid_et4000w32.c | 1392 --- src - Cópia/video/vid_et4000w32.h | 7 - src - Cópia/video/vid_et4000w32i.c | 427 - src - Cópia/video/vid_genius.c | 655 -- src - Cópia/video/vid_genius.h | 1 - src - Cópia/video/vid_hercules.c | 427 - src - Cópia/video/vid_hercules.h | 4 - src - Cópia/video/vid_herculesplus.c | 739 -- src - Cópia/video/vid_herculesplus.h | 4 - src - Cópia/video/vid_icd2061.c | 80 - src - Cópia/video/vid_icd2061.h | 17 - src - Cópia/video/vid_ics2595.c | 73 - src - Cópia/video/vid_ics2595.h | 15 - src - Cópia/video/vid_incolor.c | 1083 --- src - Cópia/video/vid_incolor.h | 4 - src - Cópia/video/vid_mda.c | 380 - src - Cópia/video/vid_mda.h | 4 - src - Cópia/video/vid_nv_riva128.c | 3711 -------- src - Cópia/video/vid_nv_riva128.h | 3 - src - Cópia/video/vid_nvidia.c | 965 -- src - Cópia/video/vid_nvidia.h | 1 - src - Cópia/video/vid_oak_oti.c | 423 - src - Cópia/video/vid_oak_oti.h | 7 - src - Cópia/video/vid_paradise.c | 617 -- src - Cópia/video/vid_paradise.h | 9 - src - Cópia/video/vid_s3.c | 3245 ------- src - Cópia/video/vid_s3.h | 33 - src - Cópia/video/vid_s3_virge.c | 4328 --------- src - Cópia/video/vid_s3_virge.h | 11 - src - Cópia/video/vid_sc1502x_ramdac.c | 111 - src - Cópia/video/vid_sc1502x_ramdac.h | 11 - src - Cópia/video/vid_sdac_ramdac.c | 183 - src - Cópia/video/vid_sdac_ramdac.h | 19 - src - Cópia/video/vid_stg_ramdac.c | 181 - src - Cópia/video/vid_stg_ramdac.h | 14 - src - Cópia/video/vid_svga.c | 1353 --- src - Cópia/video/vid_svga.h | 172 - src - Cópia/video/vid_svga_render.c | 860 -- src - Cópia/video/vid_svga_render.h | 54 - src - Cópia/video/vid_table.c | 427 - src - Cópia/video/vid_tgui9440.c | 1796 ---- src - Cópia/video/vid_tgui9440.h | 6 - src - Cópia/video/vid_ti_cf62011.c | 312 - src - Cópia/video/vid_ti_cf62011.h | 4 - src - Cópia/video/vid_tkd8001_ramdac.c | 80 - src - Cópia/video/vid_tkd8001_ramdac.h | 11 - src - Cópia/video/vid_tvga.c | 381 - src - Cópia/video/vid_tvga.h | 4 - src - Cópia/video/vid_vga.c | 242 - src - Cópia/video/vid_vga.h | 8 - src - Cópia/video/vid_voodoo.c | 7888 ----------------- src - Cópia/video/vid_voodoo.h | 1 - src - Cópia/video/vid_voodoo_codegen_x86-64.h | 3349 ------- src - Cópia/video/vid_voodoo_codegen_x86.h | 3335 ------- src - Cópia/video/vid_voodoo_dither.h | 5136 ----------- src - Cópia/video/vid_wy700.c | 1021 --- src - Cópia/video/vid_wy700.h | 1 - src - Cópia/video/video.c | 875 -- src - Cópia/video/video.h | 271 - src - Cópia/vnc.c | 310 - src - Cópia/vnc.h | 39 - src - Cópia/vnc_keymap.c | 672 -- src - Cópia/win/86Box.manifest | 22 - src - Cópia/win/86Box.rc | 1002 --- src - Cópia/win/Makefile.mingw | 686 -- src - Cópia/win/icons/86Box-RB.ico | Bin 394182 -> 0 bytes src - Cópia/win/icons/86Box.ico | Bin 394182 -> 0 bytes src - Cópia/win/icons/cdrom.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/cdrom_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/cdrom_disabled.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/cdrom_empty.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/cdrom_empty_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/display.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_35.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_35_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_35_empty.ico | Bin 1150 -> 0 bytes .../win/icons/floppy_35_empty_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_525.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_525_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_525_empty.ico | Bin 1150 -> 0 bytes .../win/icons/floppy_525_empty_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_disabled.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/floppy_drives.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/hard_disk.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/hard_disk_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/input_devices.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/machine.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/network.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/network_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/other_peripherals.ico | Bin 1150 -> 0 bytes .../win/icons/other_removable_devices.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/ports.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/sound.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/zip.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/zip_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/zip_disabled.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/zip_empty.ico | Bin 1150 -> 0 bytes src - Cópia/win/icons/zip_empty_active.ico | Bin 1150 -> 0 bytes src - Cópia/win/pcap_if.rc | 54 - src - Cópia/win/plat_dir.h | 76 - src - Cópia/win/resource.h | 324 - src - Cópia/win/win.c | 792 -- src - Cópia/win/win.h | 156 - src - Cópia/win/win_about.c | 74 - src - Cópia/win/win_cdrom.c | 154 - src - Cópia/win/win_crashdump.c | 245 - src - Cópia/win/win_d3d.cpp | 648 -- src - Cópia/win/win_d3d.h | 46 - src - Cópia/win/win_ddraw.cpp | 693 -- src - Cópia/win/win_ddraw.h | 42 - src - Cópia/win/win_devconf.c | 732 -- src - Cópia/win/win_dialog.c | 200 - src - Cópia/win/win_dynld.c | 86 - src - Cópia/win/win_joystick.cpp | 313 - src - Cópia/win/win_jsconf.c | 558 -- src - Cópia/win/win_keyboard.c | 222 - src - Cópia/win/win_midi.c | 127 - src - Cópia/win/win_mouse.cpp | 103 - src - Cópia/win/win_new_floppy.c | 712 -- src - Cópia/win/win_opendir.c | 216 - src - Cópia/win/win_sdl.c | 462 - src - Cópia/win/win_sdl.c.bak | 448 - src - Cópia/win/win_sdl.h | 61 - src - Cópia/win/win_serial.c | 571 -- src - Cópia/win/win_settings.c | 4446 ---------- src - Cópia/win/win_snd_gain.c | 92 - src - Cópia/win/win_stbar.c | 1123 --- src - Cópia/win/win_thread.c | 169 - src - Cópia/win/win_ui.c | 1081 --- 692 files changed, 301464 deletions(-) delete mode 100644 src - Cópia/86box.h delete mode 100644 src - Cópia/Makefile.local delete mode 100644 src - Cópia/bugger.c delete mode 100644 src - Cópia/bugger.h delete mode 100644 src - Cópia/cdrom/cdrom.c delete mode 100644 src - Cópia/cdrom/cdrom.h delete mode 100644 src - Cópia/cdrom/cdrom_dosbox.cpp delete mode 100644 src - Cópia/cdrom/cdrom_dosbox.h delete mode 100644 src - Cópia/cdrom/cdrom_image.cc delete mode 100644 src - Cópia/cdrom/cdrom_image.h delete mode 100644 src - Cópia/cdrom/cdrom_null.c delete mode 100644 src - Cópia/cdrom/cdrom_null.h delete mode 100644 src - Cópia/config.c delete mode 100644 src - Cópia/config.h delete mode 100644 src - Cópia/cpu/386.c delete mode 100644 src - Cópia/cpu/386.h delete mode 100644 src - Cópia/cpu/386_common.h delete mode 100644 src - Cópia/cpu/386_dynarec.c delete mode 100644 src - Cópia/cpu/386_dynarec_ops.c delete mode 100644 src - Cópia/cpu/386_ops.h delete mode 100644 src - Cópia/cpu/808x.c delete mode 100644 src - Cópia/cpu/codegen.c delete mode 100644 src - Cópia/cpu/codegen.h delete mode 100644 src - Cópia/cpu/codegen_ops.c delete mode 100644 src - Cópia/cpu/codegen_ops.h delete mode 100644 src - Cópia/cpu/codegen_ops_arith.h delete mode 100644 src - Cópia/cpu/codegen_ops_fpu.h delete mode 100644 src - Cópia/cpu/codegen_ops_jump.h delete mode 100644 src - Cópia/cpu/codegen_ops_logic.h delete mode 100644 src - Cópia/cpu/codegen_ops_misc.h delete mode 100644 src - Cópia/cpu/codegen_ops_mmx.h delete mode 100644 src - Cópia/cpu/codegen_ops_mov.h delete mode 100644 src - Cópia/cpu/codegen_ops_shift.h delete mode 100644 src - Cópia/cpu/codegen_ops_stack.h delete mode 100644 src - Cópia/cpu/codegen_ops_x86-64.h delete mode 100644 src - Cópia/cpu/codegen_ops_x86.h delete mode 100644 src - Cópia/cpu/codegen_ops_xchg.h delete mode 100644 src - Cópia/cpu/codegen_timing_486.c delete mode 100644 src - Cópia/cpu/codegen_timing_686.c delete mode 100644 src - Cópia/cpu/codegen_timing_common.c delete mode 100644 src - Cópia/cpu/codegen_timing_common.h delete mode 100644 src - Cópia/cpu/codegen_timing_pentium.c delete mode 100644 src - Cópia/cpu/codegen_timing_winchip.c delete mode 100644 src - Cópia/cpu/codegen_x86-64.c delete mode 100644 src - Cópia/cpu/codegen_x86-64.h delete mode 100644 src - Cópia/cpu/codegen_x86.c delete mode 100644 src - Cópia/cpu/codegen_x86.h delete mode 100644 src - Cópia/cpu/cpu.c delete mode 100644 src - Cópia/cpu/cpu.h delete mode 100644 src - Cópia/cpu/cpu_table.c delete mode 100644 src - Cópia/cpu/x86.h delete mode 100644 src - Cópia/cpu/x86_flags.h delete mode 100644 src - Cópia/cpu/x86_ops.h delete mode 100644 src - Cópia/cpu/x86_ops_amd.h delete mode 100644 src - Cópia/cpu/x86_ops_arith.h delete mode 100644 src - Cópia/cpu/x86_ops_atomic.h delete mode 100644 src - Cópia/cpu/x86_ops_bcd.h delete mode 100644 src - Cópia/cpu/x86_ops_bit.h delete mode 100644 src - Cópia/cpu/x86_ops_bitscan.h delete mode 100644 src - Cópia/cpu/x86_ops_call.h delete mode 100644 src - Cópia/cpu/x86_ops_flag.h delete mode 100644 src - Cópia/cpu/x86_ops_fpu.h delete mode 100644 src - Cópia/cpu/x86_ops_i686.h delete mode 100644 src - Cópia/cpu/x86_ops_inc_dec.h delete mode 100644 src - Cópia/cpu/x86_ops_int.h delete mode 100644 src - Cópia/cpu/x86_ops_io.h delete mode 100644 src - Cópia/cpu/x86_ops_jump.h delete mode 100644 src - Cópia/cpu/x86_ops_misc.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_arith.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_cmp.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_logic.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_mov.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_pack.h delete mode 100644 src - Cópia/cpu/x86_ops_mmx_shift.h delete mode 100644 src - Cópia/cpu/x86_ops_mov.h delete mode 100644 src - Cópia/cpu/x86_ops_mov_ctrl.h delete mode 100644 src - Cópia/cpu/x86_ops_mov_seg.h delete mode 100644 src - Cópia/cpu/x86_ops_movx.h delete mode 100644 src - Cópia/cpu/x86_ops_msr.h delete mode 100644 src - Cópia/cpu/x86_ops_mul.h delete mode 100644 src - Cópia/cpu/x86_ops_pmode.h delete mode 100644 src - Cópia/cpu/x86_ops_prefix.h delete mode 100644 src - Cópia/cpu/x86_ops_rep.h delete mode 100644 src - Cópia/cpu/x86_ops_ret.h delete mode 100644 src - Cópia/cpu/x86_ops_set.h delete mode 100644 src - Cópia/cpu/x86_ops_shift.h delete mode 100644 src - Cópia/cpu/x86_ops_stack.h delete mode 100644 src - Cópia/cpu/x86_ops_string.h delete mode 100644 src - Cópia/cpu/x86_ops_xchg.h delete mode 100644 src - Cópia/cpu/x86seg.c delete mode 100644 src - Cópia/cpu/x86seg.h delete mode 100644 src - Cópia/cpu/x87.c delete mode 100644 src - Cópia/cpu/x87.h delete mode 100644 src - Cópia/cpu/x87_ops.h delete mode 100644 src - Cópia/cpu/x87_ops_arith.h delete mode 100644 src - Cópia/cpu/x87_ops_loadstore.h delete mode 100644 src - Cópia/cpu/x87_ops_misc.h delete mode 100644 src - Cópia/crcspeed/crc64speed.c delete mode 100644 src - Cópia/crcspeed/crc64speed.h delete mode 100644 src - Cópia/crcspeed/crcspeed.c delete mode 100644 src - Cópia/crcspeed/crcspeed.h delete mode 100644 src - Cópia/device.c delete mode 100644 src - Cópia/device.h delete mode 100644 src - Cópia/disk/hdc.c delete mode 100644 src - Cópia/disk/hdc.h delete mode 100644 src - Cópia/disk/hdc_esdi_at.c delete mode 100644 src - Cópia/disk/hdc_esdi_mca.c delete mode 100644 src - Cópia/disk/hdc_ide.c delete mode 100644 src - Cópia/disk/hdc_ide.h delete mode 100644 src - Cópia/disk/hdc_mfm_at.c delete mode 100644 src - Cópia/disk/hdc_mfm_xt.c delete mode 100644 src - Cópia/disk/hdc_xta.c delete mode 100644 src - Cópia/disk/hdc_xtide.c delete mode 100644 src - Cópia/disk/hdd.c delete mode 100644 src - Cópia/disk/hdd.h delete mode 100644 src - Cópia/disk/hdd_image.c delete mode 100644 src - Cópia/disk/hdd_table.c delete mode 100644 src - Cópia/disk/zip.c delete mode 100644 src - Cópia/disk/zip.h delete mode 100644 src - Cópia/dma.c delete mode 100644 src - Cópia/dma.h delete mode 100644 src - Cópia/floppy/fdc.c delete mode 100644 src - Cópia/floppy/fdc.h delete mode 100644 src - Cópia/floppy/fdd.c delete mode 100644 src - Cópia/floppy/fdd.h delete mode 100644 src - Cópia/floppy/fdd_86f.c delete mode 100644 src - Cópia/floppy/fdd_86f.h delete mode 100644 src - Cópia/floppy/fdd_common.c delete mode 100644 src - Cópia/floppy/fdd_common.h delete mode 100644 src - Cópia/floppy/fdd_fdi.c delete mode 100644 src - Cópia/floppy/fdd_fdi.h delete mode 100644 src - Cópia/floppy/fdd_imd.c delete mode 100644 src - Cópia/floppy/fdd_imd.h delete mode 100644 src - Cópia/floppy/fdd_img.c delete mode 100644 src - Cópia/floppy/fdd_img.h delete mode 100644 src - Cópia/floppy/fdd_json.c delete mode 100644 src - Cópia/floppy/fdd_json.h delete mode 100644 src - Cópia/floppy/fdd_td0.c delete mode 100644 src - Cópia/floppy/fdd_td0.h delete mode 100644 src - Cópia/floppy/fdi2raw.c delete mode 100644 src - Cópia/floppy/fdi2raw.h delete mode 100644 src - Cópia/floppy/lzf/Changes delete mode 100644 src - Cópia/floppy/lzf/LICENSE delete mode 100644 src - Cópia/floppy/lzf/Makefile.in delete mode 100644 src - Cópia/floppy/lzf/README delete mode 100644 src - Cópia/floppy/lzf/config.h delete mode 100644 src - Cópia/floppy/lzf/configure delete mode 100644 src - Cópia/floppy/lzf/configure.ac delete mode 100644 src - Cópia/floppy/lzf/crc32.h delete mode 100644 src - Cópia/floppy/lzf/install-sh delete mode 100644 src - Cópia/floppy/lzf/lzf.c delete mode 100644 src - Cópia/floppy/lzf/lzf.h delete mode 100644 src - Cópia/floppy/lzf/lzfP.h delete mode 100644 src - Cópia/floppy/lzf/lzf_c.c delete mode 100644 src - Cópia/floppy/lzf/lzf_d.c delete mode 100644 src - Cópia/game/gameport.c delete mode 100644 src - Cópia/game/gameport.h delete mode 100644 src - Cópia/game/joystick_ch_flightstick_pro.c delete mode 100644 src - Cópia/game/joystick_ch_flightstick_pro.h delete mode 100644 src - Cópia/game/joystick_standard.c delete mode 100644 src - Cópia/game/joystick_standard.h delete mode 100644 src - Cópia/game/joystick_sw_pad.c delete mode 100644 src - Cópia/game/joystick_sw_pad.h delete mode 100644 src - Cópia/game/joystick_tm_fcs.c delete mode 100644 src - Cópia/game/joystick_tm_fcs.h delete mode 100644 src - Cópia/gcc_check.sh delete mode 100644 src - Cópia/gcc_check_ioctl.sh delete mode 100644 src - Cópia/i82335.c delete mode 100644 src - Cópia/i82335.h delete mode 100644 src - Cópia/intel.c delete mode 100644 src - Cópia/intel.h delete mode 100644 src - Cópia/intel_flash.c delete mode 100644 src - Cópia/intel_flash.h delete mode 100644 src - Cópia/intel_piix.c delete mode 100644 src - Cópia/intel_piix4.c delete mode 100644 src - Cópia/intel_sio.c delete mode 100644 src - Cópia/intel_sio.h delete mode 100644 src - Cópia/io.c delete mode 100644 src - Cópia/io.h delete mode 100644 src - Cópia/keyboard.c delete mode 100644 src - Cópia/keyboard.h delete mode 100644 src - Cópia/keyboard_at.c delete mode 100644 src - Cópia/keyboard_xt.c delete mode 100644 src - Cópia/lang/language.h delete mode 100644 src - Cópia/lpt.c delete mode 100644 src - Cópia/lpt.h delete mode 100644 src - Cópia/machine/m_amstrad.c delete mode 100644 src - Cópia/machine/m_at.c delete mode 100644 src - Cópia/machine/m_at_4x0.c delete mode 100644 src - Cópia/machine/m_at_ali1429.c delete mode 100644 src - Cópia/machine/m_at_commodore.c delete mode 100644 src - Cópia/machine/m_at_compaq.c delete mode 100644 src - Cópia/machine/m_at_headland.c delete mode 100644 src - Cópia/machine/m_at_neat.c delete mode 100644 src - Cópia/machine/m_at_opti495.c delete mode 100644 src - Cópia/machine/m_at_scat.c delete mode 100644 src - Cópia/machine/m_at_sis_85c471.c delete mode 100644 src - Cópia/machine/m_at_sis_85c496.c delete mode 100644 src - Cópia/machine/m_at_sis_85c50x.c delete mode 100644 src - Cópia/machine/m_at_t3100e.c delete mode 100644 src - Cópia/machine/m_at_t3100e.h delete mode 100644 src - Cópia/machine/m_at_t3100e_vid.c delete mode 100644 src - Cópia/machine/m_at_wd76c10.c delete mode 100644 src - Cópia/machine/m_europc.c delete mode 100644 src - Cópia/machine/m_olivetti_m24.c delete mode 100644 src - Cópia/machine/m_pcjr.c delete mode 100644 src - Cópia/machine/m_ps1.c delete mode 100644 src - Cópia/machine/m_ps1_hdc.c delete mode 100644 src - Cópia/machine/m_ps2_isa.c delete mode 100644 src - Cópia/machine/m_ps2_mca.c delete mode 100644 src - Cópia/machine/m_tandy.c delete mode 100644 src - Cópia/machine/m_xt.c delete mode 100644 src - Cópia/machine/m_xt_compaq.c delete mode 100644 src - Cópia/machine/m_xt_laserxt.c delete mode 100644 src - Cópia/machine/m_xt_t1000.c delete mode 100644 src - Cópia/machine/m_xt_t1000.h delete mode 100644 src - Cópia/machine/m_xt_t1000_vid.c delete mode 100644 src - Cópia/machine/m_xt_xi8088.c delete mode 100644 src - Cópia/machine/m_xt_xi8088.h delete mode 100644 src - Cópia/machine/machine.c delete mode 100644 src - Cópia/machine/machine.h delete mode 100644 src - Cópia/machine/machine_table.c delete mode 100644 src - Cópia/mca.c delete mode 100644 src - Cópia/mca.h delete mode 100644 src - Cópia/mcr.c delete mode 100644 src - Cópia/mem.c delete mode 100644 src - Cópia/mem.h delete mode 100644 src - Cópia/memregs.c delete mode 100644 src - Cópia/memregs.h delete mode 100644 src - Cópia/mouse.c delete mode 100644 src - Cópia/mouse.h delete mode 100644 src - Cópia/mouse_bus - Cópia (2).c delete mode 100644 src - Cópia/mouse_bus - Cópia (3).c delete mode 100644 src - Cópia/mouse_bus - Cópia (4).c delete mode 100644 src - Cópia/mouse_bus - Cópia 2.c delete mode 100644 src - Cópia/mouse_bus - Cópia.c delete mode 100644 src - Cópia/mouse_bus.c delete mode 100644 src - Cópia/mouse_bus_good.c delete mode 100644 src - Cópia/mouse_bus_x.c delete mode 100644 src - Cópia/mouse_ps2.c delete mode 100644 src - Cópia/mouse_serial.c delete mode 100644 src - Cópia/network/bswap.h delete mode 100644 src - Cópia/network/net_ne2000.c delete mode 100644 src - Cópia/network/net_ne2000.h delete mode 100644 src - Cópia/network/net_pcap.c delete mode 100644 src - Cópia/network/net_slirp.c delete mode 100644 src - Cópia/network/network.c delete mode 100644 src - Cópia/network/network.h delete mode 100644 src - Cópia/network/pcap_if.c delete mode 100644 src - Cópia/network/slirp/COPYRIGHT.txt delete mode 100644 src - Cópia/network/slirp/VERSION.txt delete mode 100644 src - Cópia/network/slirp/bootp.c delete mode 100644 src - Cópia/network/slirp/bootp.h delete mode 100644 src - Cópia/network/slirp/cksum.c delete mode 100644 src - Cópia/network/slirp/config-host.h delete mode 100644 src - Cópia/network/slirp/config.h delete mode 100644 src - Cópia/network/slirp/ctl.h delete mode 100644 src - Cópia/network/slirp/debug.c delete mode 100644 src - Cópia/network/slirp/debug.h delete mode 100644 src - Cópia/network/slirp/icmp_var.h delete mode 100644 src - Cópia/network/slirp/if.c delete mode 100644 src - Cópia/network/slirp/if.h delete mode 100644 src - Cópia/network/slirp/ip.h delete mode 100644 src - Cópia/network/slirp/ip_icmp.c delete mode 100644 src - Cópia/network/slirp/ip_icmp.h delete mode 100644 src - Cópia/network/slirp/ip_input.c delete mode 100644 src - Cópia/network/slirp/ip_output.c delete mode 100644 src - Cópia/network/slirp/libslirp.h delete mode 100644 src - Cópia/network/slirp/main.h delete mode 100644 src - Cópia/network/slirp/mbuf.c delete mode 100644 src - Cópia/network/slirp/mbuf.h delete mode 100644 src - Cópia/network/slirp/misc.c delete mode 100644 src - Cópia/network/slirp/misc.h delete mode 100644 src - Cópia/network/slirp/queue.c delete mode 100644 src - Cópia/network/slirp/queue.h delete mode 100644 src - Cópia/network/slirp/sbuf.c delete mode 100644 src - Cópia/network/slirp/sbuf.h delete mode 100644 src - Cópia/network/slirp/slirp.c delete mode 100644 src - Cópia/network/slirp/slirp.h delete mode 100644 src - Cópia/network/slirp/slirp_config.h delete mode 100644 src - Cópia/network/slirp/socket.c delete mode 100644 src - Cópia/network/slirp/socket.h delete mode 100644 src - Cópia/network/slirp/tcp.h delete mode 100644 src - Cópia/network/slirp/tcp_input.c delete mode 100644 src - Cópia/network/slirp/tcp_output.c delete mode 100644 src - Cópia/network/slirp/tcp_subr.c delete mode 100644 src - Cópia/network/slirp/tcp_timer.c delete mode 100644 src - Cópia/network/slirp/tcp_timer.h delete mode 100644 src - Cópia/network/slirp/tcp_var.h delete mode 100644 src - Cópia/network/slirp/tcpip.h delete mode 100644 src - Cópia/network/slirp/tftp.c delete mode 100644 src - Cópia/network/slirp/tftp.h delete mode 100644 src - Cópia/network/slirp/udp.c delete mode 100644 src - Cópia/network/slirp/udp.h delete mode 100644 src - Cópia/nmi.c delete mode 100644 src - Cópia/nmi.h delete mode 100644 src - Cópia/nvr.c delete mode 100644 src - Cópia/nvr.h delete mode 100644 src - Cópia/nvr_at.c delete mode 100644 src - Cópia/nvr_ps2.c delete mode 100644 src - Cópia/nvr_ps2.h delete mode 100644 src - Cópia/pc.c delete mode 100644 src - Cópia/pci.c delete mode 100644 src - Cópia/pci.h delete mode 100644 src - Cópia/pci_dummy.c delete mode 100644 src - Cópia/pci_dummy.h delete mode 100644 src - Cópia/pic.c delete mode 100644 src - Cópia/pic.h delete mode 100644 src - Cópia/piix.h delete mode 100644 src - Cópia/pit.c delete mode 100644 src - Cópia/pit.h delete mode 100644 src - Cópia/plat.h delete mode 100644 src - Cópia/plat_dynld.h delete mode 100644 src - Cópia/plat_midi.h delete mode 100644 src - Cópia/ppi.c delete mode 100644 src - Cópia/ppi.h delete mode 100644 src - Cópia/random.c delete mode 100644 src - Cópia/random.h delete mode 100644 src - Cópia/rom.c delete mode 100644 src - Cópia/rom.h delete mode 100644 src - Cópia/scsi/scsi.c delete mode 100644 src - Cópia/scsi/scsi.h delete mode 100644 src - Cópia/scsi/scsi_aha154x.c delete mode 100644 src - Cópia/scsi/scsi_aha154x.h delete mode 100644 src - Cópia/scsi/scsi_bus.c delete mode 100644 src - Cópia/scsi/scsi_buslogic.c delete mode 100644 src - Cópia/scsi/scsi_buslogic.h delete mode 100644 src - Cópia/scsi/scsi_device.c delete mode 100644 src - Cópia/scsi/scsi_device.h delete mode 100644 src - Cópia/scsi/scsi_disk.c delete mode 100644 src - Cópia/scsi/scsi_disk.h delete mode 100644 src - Cópia/scsi/scsi_ncr5380.c delete mode 100644 src - Cópia/scsi/scsi_ncr5380.h delete mode 100644 src - Cópia/scsi/scsi_ncr53c810.c delete mode 100644 src - Cópia/scsi/scsi_ncr53c810.h delete mode 100644 src - Cópia/scsi/scsi_x54x.c delete mode 100644 src - Cópia/scsi/scsi_x54x.h delete mode 100644 src - Cópia/serial.c delete mode 100644 src - Cópia/serial.h delete mode 100644 src - Cópia/sio.h delete mode 100644 src - Cópia/sio_detect.c delete mode 100644 src - Cópia/sio_fdc37c669.c delete mode 100644 src - Cópia/sio_fdc37c66x.c delete mode 100644 src - Cópia/sio_fdc37c93x.c delete mode 100644 src - Cópia/sio_pc87306.c delete mode 100644 src - Cópia/sio_um8669f.c delete mode 100644 src - Cópia/sio_w83877f.c delete mode 100644 src - Cópia/sound/dbopl.cpp delete mode 100644 src - Cópia/sound/dbopl.h delete mode 100644 src - Cópia/sound/filters.h delete mode 100644 src - Cópia/sound/midi.c delete mode 100644 src - Cópia/sound/midi.h delete mode 100644 src - Cópia/sound/midi_fluidsynth.c delete mode 100644 src - Cópia/sound/midi_fluidsynth.h delete mode 100644 src - Cópia/sound/midi_mt32.c delete mode 100644 src - Cópia/sound/midi_mt32.h delete mode 100644 src - Cópia/sound/midi_system.c delete mode 100644 src - Cópia/sound/midi_system.h delete mode 100644 src - Cópia/sound/munt/Analog.cpp delete mode 100644 src - Cópia/sound/munt/Analog.h delete mode 100644 src - Cópia/sound/munt/BReverbModel.cpp delete mode 100644 src - Cópia/sound/munt/BReverbModel.h delete mode 100644 src - Cópia/sound/munt/Enumerations.h delete mode 100644 src - Cópia/sound/munt/File.cpp delete mode 100644 src - Cópia/sound/munt/File.h delete mode 100644 src - Cópia/sound/munt/FileStream.cpp delete mode 100644 src - Cópia/sound/munt/FileStream.h delete mode 100644 src - Cópia/sound/munt/LA32FloatWaveGenerator.cpp delete mode 100644 src - Cópia/sound/munt/LA32FloatWaveGenerator.h delete mode 100644 src - Cópia/sound/munt/LA32Ramp.cpp delete mode 100644 src - Cópia/sound/munt/LA32Ramp.h delete mode 100644 src - Cópia/sound/munt/LA32WaveGenerator.cpp delete mode 100644 src - Cópia/sound/munt/LA32WaveGenerator.h delete mode 100644 src - Cópia/sound/munt/MemoryRegion.h delete mode 100644 src - Cópia/sound/munt/MidiEventQueue.h delete mode 100644 src - Cópia/sound/munt/MidiStreamParser.cpp delete mode 100644 src - Cópia/sound/munt/MidiStreamParser.h delete mode 100644 src - Cópia/sound/munt/Part.cpp delete mode 100644 src - Cópia/sound/munt/Part.h delete mode 100644 src - Cópia/sound/munt/Partial.cpp delete mode 100644 src - Cópia/sound/munt/Partial.h delete mode 100644 src - Cópia/sound/munt/PartialManager.cpp delete mode 100644 src - Cópia/sound/munt/PartialManager.h delete mode 100644 src - Cópia/sound/munt/Poly.cpp delete mode 100644 src - Cópia/sound/munt/Poly.h delete mode 100644 src - Cópia/sound/munt/ROMInfo.cpp delete mode 100644 src - Cópia/sound/munt/ROMInfo.h delete mode 100644 src - Cópia/sound/munt/SampleRateConverter.cpp delete mode 100644 src - Cópia/sound/munt/SampleRateConverter.h delete mode 100644 src - Cópia/sound/munt/SampleRateConverter_dummy.cpp delete mode 100644 src - Cópia/sound/munt/Structures.h delete mode 100644 src - Cópia/sound/munt/Synth.cpp delete mode 100644 src - Cópia/sound/munt/Synth.h delete mode 100644 src - Cópia/sound/munt/TVA.cpp delete mode 100644 src - Cópia/sound/munt/TVA.h delete mode 100644 src - Cópia/sound/munt/TVF.cpp delete mode 100644 src - Cópia/sound/munt/TVF.h delete mode 100644 src - Cópia/sound/munt/TVP.cpp delete mode 100644 src - Cópia/sound/munt/TVP.h delete mode 100644 src - Cópia/sound/munt/Tables.cpp delete mode 100644 src - Cópia/sound/munt/Tables.h delete mode 100644 src - Cópia/sound/munt/Types.h delete mode 100644 src - Cópia/sound/munt/c_interface/c_interface.cpp delete mode 100644 src - Cópia/sound/munt/c_interface/c_interface.h delete mode 100644 src - Cópia/sound/munt/c_interface/c_types.h delete mode 100644 src - Cópia/sound/munt/c_interface/cpp_interface.h delete mode 100644 src - Cópia/sound/munt/config.h delete mode 100644 src - Cópia/sound/munt/globals.h delete mode 100644 src - Cópia/sound/munt/internals.h delete mode 100644 src - Cópia/sound/munt/mmath.h delete mode 100644 src - Cópia/sound/munt/mt32emu.h delete mode 100644 src - Cópia/sound/munt/sha1/sha1.cpp delete mode 100644 src - Cópia/sound/munt/sha1/sha1.h delete mode 100644 src - Cópia/sound/munt/srchelper/InternalResampler.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/InternalResampler.h delete mode 100644 src - Cópia/sound/munt/srchelper/SamplerateAdapter.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/SamplerateAdapter.h delete mode 100644 src - Cópia/sound/munt/srchelper/SoxrAdapter.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/SoxrAdapter.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/FIRResampler.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/FloatSampleProvider.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/IIR2xResampler.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/LinearResampler.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/ResamplerModel.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/ResamplerStage.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/include/SincResampler.h delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/src/FIRResampler.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/src/LinearResampler.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/src/ResamplerModel.cpp delete mode 100644 src - Cópia/sound/munt/srchelper/srctools/src/SincResampler.cpp delete mode 100644 src - Cópia/sound/nukedopl.cpp delete mode 100644 src - Cópia/sound/nukedopl.h delete mode 100644 src - Cópia/sound/openal.c delete mode 100644 src - Cópia/sound/resid-fp/AUTHORS delete mode 100644 src - Cópia/sound/resid-fp/COPYING delete mode 100644 src - Cópia/sound/resid-fp/ChangeLog delete mode 100644 src - Cópia/sound/resid-fp/INSTALL delete mode 100644 src - Cópia/sound/resid-fp/Makefile.am delete mode 100644 src - Cópia/sound/resid-fp/Makefile.in delete mode 100644 src - Cópia/sound/resid-fp/NEWS delete mode 100644 src - Cópia/sound/resid-fp/README delete mode 100644 src - Cópia/sound/resid-fp/README.VICE delete mode 100644 src - Cópia/sound/resid-fp/aclocal.m4 delete mode 100644 src - Cópia/sound/resid-fp/configure delete mode 100644 src - Cópia/sound/resid-fp/configure.in delete mode 100644 src - Cópia/sound/resid-fp/convolve-sse.cc delete mode 100644 src - Cópia/sound/resid-fp/convolve.cc delete mode 100644 src - Cópia/sound/resid-fp/envelope.cc delete mode 100644 src - Cópia/sound/resid-fp/envelope.h delete mode 100644 src - Cópia/sound/resid-fp/extfilt.cc delete mode 100644 src - Cópia/sound/resid-fp/extfilt.h delete mode 100644 src - Cópia/sound/resid-fp/filter.cc delete mode 100644 src - Cópia/sound/resid-fp/filter.h delete mode 100644 src - Cópia/sound/resid-fp/pot.cc delete mode 100644 src - Cópia/sound/resid-fp/pot.h delete mode 100644 src - Cópia/sound/resid-fp/samp2src.pl delete mode 100644 src - Cópia/sound/resid-fp/sid.cc delete mode 100644 src - Cópia/sound/resid-fp/sid.h delete mode 100644 src - Cópia/sound/resid-fp/siddefs-fp.h delete mode 100644 src - Cópia/sound/resid-fp/siddefs-fp.h.in delete mode 100644 src - Cópia/sound/resid-fp/version.cc delete mode 100644 src - Cópia/sound/resid-fp/voice.cc delete mode 100644 src - Cópia/sound/resid-fp/voice.h delete mode 100644 src - Cópia/sound/resid-fp/wave.cc delete mode 100644 src - Cópia/sound/resid-fp/wave.h delete mode 100644 src - Cópia/sound/resid-fp/wave6581_PST.cc delete mode 100644 src - Cópia/sound/resid-fp/wave6581_PST.dat delete mode 100644 src - Cópia/sound/resid-fp/wave6581_PS_.cc delete mode 100644 src - Cópia/sound/resid-fp/wave6581_PS_.dat delete mode 100644 src - Cópia/sound/resid-fp/wave6581_P_T.cc delete mode 100644 src - Cópia/sound/resid-fp/wave6581_P_T.dat delete mode 100644 src - Cópia/sound/resid-fp/wave6581__ST.cc delete mode 100644 src - Cópia/sound/resid-fp/wave6581__ST.dat delete mode 100644 src - Cópia/sound/resid-fp/wave8580_PST.cc delete mode 100644 src - Cópia/sound/resid-fp/wave8580_PST.dat delete mode 100644 src - Cópia/sound/resid-fp/wave8580_PS_.cc delete mode 100644 src - Cópia/sound/resid-fp/wave8580_PS_.dat delete mode 100644 src - Cópia/sound/resid-fp/wave8580_P_T.cc delete mode 100644 src - Cópia/sound/resid-fp/wave8580_P_T.dat delete mode 100644 src - Cópia/sound/resid-fp/wave8580__ST.cc delete mode 100644 src - Cópia/sound/resid-fp/wave8580__ST.dat delete mode 100644 src - Cópia/sound/snd_ad1848.c delete mode 100644 src - Cópia/sound/snd_ad1848.h delete mode 100644 src - Cópia/sound/snd_adlib.c delete mode 100644 src - Cópia/sound/snd_adlib.h delete mode 100644 src - Cópia/sound/snd_adlibgold.c delete mode 100644 src - Cópia/sound/snd_adlibgold.h delete mode 100644 src - Cópia/sound/snd_audiopci.c delete mode 100644 src - Cópia/sound/snd_audiopci.h delete mode 100644 src - Cópia/sound/snd_cms.c delete mode 100644 src - Cópia/sound/snd_cms.h delete mode 100644 src - Cópia/sound/snd_dbopl.cc delete mode 100644 src - Cópia/sound/snd_dbopl.h delete mode 100644 src - Cópia/sound/snd_emu8k.c delete mode 100644 src - Cópia/sound/snd_emu8k.h delete mode 100644 src - Cópia/sound/snd_gus.c delete mode 100644 src - Cópia/sound/snd_gus.h delete mode 100644 src - Cópia/sound/snd_lpt_dac.c delete mode 100644 src - Cópia/sound/snd_lpt_dac.h delete mode 100644 src - Cópia/sound/snd_lpt_dss.c delete mode 100644 src - Cópia/sound/snd_lpt_dss.h delete mode 100644 src - Cópia/sound/snd_mpu401.c delete mode 100644 src - Cópia/sound/snd_mpu401.h delete mode 100644 src - Cópia/sound/snd_opl.c delete mode 100644 src - Cópia/sound/snd_opl.h delete mode 100644 src - Cópia/sound/snd_pas16.c delete mode 100644 src - Cópia/sound/snd_pas16.h delete mode 100644 src - Cópia/sound/snd_pssj.c delete mode 100644 src - Cópia/sound/snd_pssj.h delete mode 100644 src - Cópia/sound/snd_resid.cc delete mode 100644 src - Cópia/sound/snd_resid.h delete mode 100644 src - Cópia/sound/snd_sb.c delete mode 100644 src - Cópia/sound/snd_sb.h delete mode 100644 src - Cópia/sound/snd_sb_dsp.c delete mode 100644 src - Cópia/sound/snd_sb_dsp.h delete mode 100644 src - Cópia/sound/snd_sn76489.c delete mode 100644 src - Cópia/sound/snd_sn76489.h delete mode 100644 src - Cópia/sound/snd_speaker.c delete mode 100644 src - Cópia/sound/snd_speaker.h delete mode 100644 src - Cópia/sound/snd_ssi2001.c delete mode 100644 src - Cópia/sound/snd_ssi2001.h delete mode 100644 src - Cópia/sound/snd_wss.c delete mode 100644 src - Cópia/sound/snd_wss.h delete mode 100644 src - Cópia/sound/snd_ym7128.c delete mode 100644 src - Cópia/sound/snd_ym7128.h delete mode 100644 src - Cópia/sound/sound.c delete mode 100644 src - Cópia/sound/sound.h delete mode 100644 src - Cópia/src_20170607.rar delete mode 100644 src - Cópia/timer.c delete mode 100644 src - Cópia/timer.h delete mode 100644 src - Cópia/ui.h delete mode 100644 src - Cópia/usb.c delete mode 100644 src - Cópia/usb.h delete mode 100644 src - Cópia/video/vid_ati18800.c delete mode 100644 src - Cópia/video/vid_ati18800.h delete mode 100644 src - Cópia/video/vid_ati28800.c delete mode 100644 src - Cópia/video/vid_ati28800.h delete mode 100644 src - Cópia/video/vid_ati68860_ramdac.c delete mode 100644 src - Cópia/video/vid_ati68860_ramdac.h delete mode 100644 src - Cópia/video/vid_ati_eeprom.c delete mode 100644 src - Cópia/video/vid_ati_eeprom.h delete mode 100644 src - Cópia/video/vid_ati_mach64.c delete mode 100644 src - Cópia/video/vid_ati_mach64.h delete mode 100644 src - Cópia/video/vid_bt485_ramdac.c delete mode 100644 src - Cópia/video/vid_bt485_ramdac.h delete mode 100644 src - Cópia/video/vid_cga.c delete mode 100644 src - Cópia/video/vid_cga.h delete mode 100644 src - Cópia/video/vid_cga_comp.c delete mode 100644 src - Cópia/video/vid_cga_comp.h delete mode 100644 src - Cópia/video/vid_cl54xx.c delete mode 100644 src - Cópia/video/vid_cl54xx.h delete mode 100644 src - Cópia/video/vid_colorplus.c delete mode 100644 src - Cópia/video/vid_colorplus.h delete mode 100644 src - Cópia/video/vid_compaq_cga.c delete mode 100644 src - Cópia/video/vid_compaq_cga.h delete mode 100644 src - Cópia/video/vid_ega.c delete mode 100644 src - Cópia/video/vid_ega.h delete mode 100644 src - Cópia/video/vid_ega_render.c delete mode 100644 src - Cópia/video/vid_ega_render.h delete mode 100644 src - Cópia/video/vid_et4000.c delete mode 100644 src - Cópia/video/vid_et4000.h delete mode 100644 src - Cópia/video/vid_et4000w32.c delete mode 100644 src - Cópia/video/vid_et4000w32.h delete mode 100644 src - Cópia/video/vid_et4000w32i.c delete mode 100644 src - Cópia/video/vid_genius.c delete mode 100644 src - Cópia/video/vid_genius.h delete mode 100644 src - Cópia/video/vid_hercules.c delete mode 100644 src - Cópia/video/vid_hercules.h delete mode 100644 src - Cópia/video/vid_herculesplus.c delete mode 100644 src - Cópia/video/vid_herculesplus.h delete mode 100644 src - Cópia/video/vid_icd2061.c delete mode 100644 src - Cópia/video/vid_icd2061.h delete mode 100644 src - Cópia/video/vid_ics2595.c delete mode 100644 src - Cópia/video/vid_ics2595.h delete mode 100644 src - Cópia/video/vid_incolor.c delete mode 100644 src - Cópia/video/vid_incolor.h delete mode 100644 src - Cópia/video/vid_mda.c delete mode 100644 src - Cópia/video/vid_mda.h delete mode 100644 src - Cópia/video/vid_nv_riva128.c delete mode 100644 src - Cópia/video/vid_nv_riva128.h delete mode 100644 src - Cópia/video/vid_nvidia.c delete mode 100644 src - Cópia/video/vid_nvidia.h delete mode 100644 src - Cópia/video/vid_oak_oti.c delete mode 100644 src - Cópia/video/vid_oak_oti.h delete mode 100644 src - Cópia/video/vid_paradise.c delete mode 100644 src - Cópia/video/vid_paradise.h delete mode 100644 src - Cópia/video/vid_s3.c delete mode 100644 src - Cópia/video/vid_s3.h delete mode 100644 src - Cópia/video/vid_s3_virge.c delete mode 100644 src - Cópia/video/vid_s3_virge.h delete mode 100644 src - Cópia/video/vid_sc1502x_ramdac.c delete mode 100644 src - Cópia/video/vid_sc1502x_ramdac.h delete mode 100644 src - Cópia/video/vid_sdac_ramdac.c delete mode 100644 src - Cópia/video/vid_sdac_ramdac.h delete mode 100644 src - Cópia/video/vid_stg_ramdac.c delete mode 100644 src - Cópia/video/vid_stg_ramdac.h delete mode 100644 src - Cópia/video/vid_svga.c delete mode 100644 src - Cópia/video/vid_svga.h delete mode 100644 src - Cópia/video/vid_svga_render.c delete mode 100644 src - Cópia/video/vid_svga_render.h delete mode 100644 src - Cópia/video/vid_table.c delete mode 100644 src - Cópia/video/vid_tgui9440.c delete mode 100644 src - Cópia/video/vid_tgui9440.h delete mode 100644 src - Cópia/video/vid_ti_cf62011.c delete mode 100644 src - Cópia/video/vid_ti_cf62011.h delete mode 100644 src - Cópia/video/vid_tkd8001_ramdac.c delete mode 100644 src - Cópia/video/vid_tkd8001_ramdac.h delete mode 100644 src - Cópia/video/vid_tvga.c delete mode 100644 src - Cópia/video/vid_tvga.h delete mode 100644 src - Cópia/video/vid_vga.c delete mode 100644 src - Cópia/video/vid_vga.h delete mode 100644 src - Cópia/video/vid_voodoo.c delete mode 100644 src - Cópia/video/vid_voodoo.h delete mode 100644 src - Cópia/video/vid_voodoo_codegen_x86-64.h delete mode 100644 src - Cópia/video/vid_voodoo_codegen_x86.h delete mode 100644 src - Cópia/video/vid_voodoo_dither.h delete mode 100644 src - Cópia/video/vid_wy700.c delete mode 100644 src - Cópia/video/vid_wy700.h delete mode 100644 src - Cópia/video/video.c delete mode 100644 src - Cópia/video/video.h delete mode 100644 src - Cópia/vnc.c delete mode 100644 src - Cópia/vnc.h delete mode 100644 src - Cópia/vnc_keymap.c delete mode 100644 src - Cópia/win/86Box.manifest delete mode 100644 src - Cópia/win/86Box.rc delete mode 100644 src - Cópia/win/Makefile.mingw delete mode 100644 src - Cópia/win/icons/86Box-RB.ico delete mode 100644 src - Cópia/win/icons/86Box.ico delete mode 100644 src - Cópia/win/icons/cdrom.ico delete mode 100644 src - Cópia/win/icons/cdrom_active.ico delete mode 100644 src - Cópia/win/icons/cdrom_disabled.ico delete mode 100644 src - Cópia/win/icons/cdrom_empty.ico delete mode 100644 src - Cópia/win/icons/cdrom_empty_active.ico delete mode 100644 src - Cópia/win/icons/display.ico delete mode 100644 src - Cópia/win/icons/floppy_35.ico delete mode 100644 src - Cópia/win/icons/floppy_35_active.ico delete mode 100644 src - Cópia/win/icons/floppy_35_empty.ico delete mode 100644 src - Cópia/win/icons/floppy_35_empty_active.ico delete mode 100644 src - Cópia/win/icons/floppy_525.ico delete mode 100644 src - Cópia/win/icons/floppy_525_active.ico delete mode 100644 src - Cópia/win/icons/floppy_525_empty.ico delete mode 100644 src - Cópia/win/icons/floppy_525_empty_active.ico delete mode 100644 src - Cópia/win/icons/floppy_disabled.ico delete mode 100644 src - Cópia/win/icons/floppy_drives.ico delete mode 100644 src - Cópia/win/icons/hard_disk.ico delete mode 100644 src - Cópia/win/icons/hard_disk_active.ico delete mode 100644 src - Cópia/win/icons/input_devices.ico delete mode 100644 src - Cópia/win/icons/machine.ico delete mode 100644 src - Cópia/win/icons/network.ico delete mode 100644 src - Cópia/win/icons/network_active.ico delete mode 100644 src - Cópia/win/icons/other_peripherals.ico delete mode 100644 src - Cópia/win/icons/other_removable_devices.ico delete mode 100644 src - Cópia/win/icons/ports.ico delete mode 100644 src - Cópia/win/icons/sound.ico delete mode 100644 src - Cópia/win/icons/zip.ico delete mode 100644 src - Cópia/win/icons/zip_active.ico delete mode 100644 src - Cópia/win/icons/zip_disabled.ico delete mode 100644 src - Cópia/win/icons/zip_empty.ico delete mode 100644 src - Cópia/win/icons/zip_empty_active.ico delete mode 100644 src - Cópia/win/pcap_if.rc delete mode 100644 src - Cópia/win/plat_dir.h delete mode 100644 src - Cópia/win/resource.h delete mode 100644 src - Cópia/win/win.c delete mode 100644 src - Cópia/win/win.h delete mode 100644 src - Cópia/win/win_about.c delete mode 100644 src - Cópia/win/win_cdrom.c delete mode 100644 src - Cópia/win/win_crashdump.c delete mode 100644 src - Cópia/win/win_d3d.cpp delete mode 100644 src - Cópia/win/win_d3d.h delete mode 100644 src - Cópia/win/win_ddraw.cpp delete mode 100644 src - Cópia/win/win_ddraw.h delete mode 100644 src - Cópia/win/win_devconf.c delete mode 100644 src - Cópia/win/win_dialog.c delete mode 100644 src - Cópia/win/win_dynld.c delete mode 100644 src - Cópia/win/win_joystick.cpp delete mode 100644 src - Cópia/win/win_jsconf.c delete mode 100644 src - Cópia/win/win_keyboard.c delete mode 100644 src - Cópia/win/win_midi.c delete mode 100644 src - Cópia/win/win_mouse.cpp delete mode 100644 src - Cópia/win/win_new_floppy.c delete mode 100644 src - Cópia/win/win_opendir.c delete mode 100644 src - Cópia/win/win_sdl.c delete mode 100644 src - Cópia/win/win_sdl.c.bak delete mode 100644 src - Cópia/win/win_sdl.h delete mode 100644 src - Cópia/win/win_serial.c delete mode 100644 src - Cópia/win/win_settings.c delete mode 100644 src - Cópia/win/win_snd_gain.c delete mode 100644 src - Cópia/win/win_stbar.c delete mode 100644 src - Cópia/win/win_thread.c delete mode 100644 src - Cópia/win/win_ui.c diff --git a/src - Cópia/86box.h b/src - Cópia/86box.h deleted file mode 100644 index a054900f9..000000000 --- a/src - Cópia/86box.h +++ /dev/null @@ -1,165 +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. - * - * Main include file for the application. - * - * Version: @(#)86box.h 1.0.23 2018/05/25 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_86BOX_H -# define EMU_86BOX_H - - -/* Configuration values. */ -#define SERIAL_MAX 2 -#define PARALLEL_MAX 1 -#define SCREEN_RES_X 640 -#define SCREEN_RES_Y 480 - -/* Version info. */ -#define EMU_NAME "86Box" -#define EMU_NAME_W L"86Box" -#define EMU_VERSION "2.00" -#define EMU_VERSION_W L"2.00" - -/* Filename and pathname info. */ -#define CONFIG_FILE L"86box.cfg" -#define NVR_PATH L"nvr" -#define SCREENSHOT_PATH L"screenshots" - - -#if defined(ENABLE_BUSLOGIC_LOG) || \ - defined(ENABLE_CDROM_LOG) || \ - defined(ENABLE_D86F_LOG) || \ - defined(ENABLE_FDC_LOG) || \ - defined(ENABLE_IDE_LOG) || \ - defined(ENABLE_NIC_LOG) -# define ENABLE_LOG_TOGGLES 1 -#endif - -#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP) -# define ENABLE_LOG_COMMANDS 1 -#endif - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define ABS(x) ((x) > 0 ? (x) : -(x)) - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global variables. */ -extern int dump_on_exit; /* (O) dump regs on exit*/ -extern int do_dump_config; /* (O) dump cfg after load */ -extern int start_in_fullscreen; /* (O) start in fullscreen */ -#ifdef _WIN32 -extern int force_debug; /* (O) force debug output */ -#endif -#ifdef USE_WX -extern int video_fps; /* (O) render speed in fps */ -#endif -extern int settings_only; /* (O) show only the settings dialog */ -#ifdef _WIN32 -extern uint64_t unique_id; -extern uint64_t source_hwnd; -#endif -extern wchar_t log_path[1024]; /* (O) full path of logfile */ - - -extern int window_w, window_h, /* (C) window size and */ - window_x, window_y, /* position info */ - window_remember, - vid_resize, /* (C) allow resizing */ - invert_display, /* (C) invert the display */ - suppress_overscan; /* (C) suppress overscans */ -extern int scale; /* (C) screen scale factor */ -extern int vid_api; /* (C) video renderer */ -extern int vid_cga_contrast, /* (C) video */ - video_fullscreen, /* (C) video */ - video_fullscreen_first, /* (C) video */ - video_fullscreen_scale, /* (C) video */ - enable_overscan, /* (C) video */ - force_43, /* (C) video */ - gfxcard; /* (C) graphics/video card */ -extern int serial_enabled[], /* (C) enable serial ports */ - lpt_enabled, /* (C) enable LPT ports */ - bugger_enabled; /* (C) enable ISAbugger */ -extern int sound_is_float, /* (C) sound uses FP values */ - GAMEBLASTER, /* (C) sound option */ - GUS, /* (C) sound option */ - SSI2001, /* (C) sound option */ - voodoo_enabled; /* (C) video option */ -extern uint32_t mem_size; /* (C) memory size */ -extern int cpu_manufacturer, /* (C) cpu manufacturer */ - cpu, /* (C) cpu type */ - cpu_use_dynarec, /* (C) cpu uses/needs Dyna */ - enable_external_fpu; /* (C) enable external FPU */ -extern int enable_sync; /* (C) enable time sync */ -extern int network_type; /* (C) net provider type */ -extern int network_card; /* (C) net interface num */ -extern char network_host[512]; /* (C) host network intf */ - - -#ifdef ENABLE_LOG_TOGGLES -extern int buslogic_do_log; -extern int cdrom_do_log; -extern int d86f_do_log; -extern int fdc_do_log; -extern int ide_do_log; -extern int serial_do_log; -extern int nic_do_log; -#endif - -extern wchar_t exe_path[1024]; /* path (dir) of executable */ -extern wchar_t usr_path[1024]; /* path (dir) of user data */ -extern wchar_t cfg_path[1024]; /* full path of config file */ -extern FILE *stdlog; /* file to log output to */ -extern int scrnsz_x, /* current screen size, X */ - scrnsz_y; /* current screen size, Y */ -extern int config_changed; /* config has changed */ - - -/* Function prototypes. */ -#ifdef HAVE_STDARG_H -extern void pclog_ex(const char *fmt, va_list); -#endif -extern void pclog_toggle_suppr(void); -extern void pclog(const char *fmt, ...); -extern void fatal(const char *fmt, ...); -extern void set_screen_size(int x, int y); -extern void set_screen_size_natural(void); -#if 0 -extern void pc_reload(wchar_t *fn); -#endif -extern int pc_init_modules(void); -extern int pc_init(int argc, wchar_t *argv[]); -extern void pc_close(void *threadid); -extern void pc_reset_hard_close(void); -extern void pc_reset_hard_init(void); -extern void pc_reset_hard(void); -extern void pc_reset(int hard); -extern void pc_full_speed(void); -extern void pc_speed_changed(void); -extern void pc_send_cad(void); -extern void pc_send_cae(void); -extern void pc_send_cab(void); -extern void pc_thread(void *param); -extern void pc_start(void); -extern void pc_onesec(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_86BOX_H*/ diff --git a/src - Cópia/Makefile.local b/src - Cópia/Makefile.local deleted file mode 100644 index a93152007..000000000 --- a/src - Cópia/Makefile.local +++ /dev/null @@ -1,164 +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. -# -# Prefix for localizing the general Makefile.mingw for local -# settings, so we can avoid changing the main one for all of -# our local setups. -# -# Version: @(#)Makefile.local 1.0.14 2018/05/26 -# -# Author: Fred N. van Kempen, -# - -######################################################################### -# Anything here will override defaults in Makefile.MinGW. # -######################################################################### - - -# Name of the executable. -#PROG := yourexe - - -# Various compile-time options. -# -DROM_TRACE=0xc800 traces ROM access from segment C800 -# -DIO_TRACE=0x66 traces I/O on port 0x66 -# -DIO_CATCH enables I/O range catch logs -STUFF := - -# Add feature selections here. -# -DANSI_CFG forces the config file to ANSI encoding. -# -DENABLE_VRAM_DUMP enables Video Ram dumping. -# -DENABLE_LOG_BREAKPOINT enables extra logging. -# Root logging: -# -DENABLE_BUGGER_LOG=N sets logging level at N. -# -DENABLE_CONFIG_LOG=N sets logging level at N. -# -DENABLE_DEVICE_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_AMSTRAD_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_LOG=N sets logging level at N. -# -DENABLE_IO_LOG=N sets logging level at N. -# -DENABLE_MEM_LOG=N sets logging level at N. -# -DENABLE_MOUSE_LOG=N sets logging level at N. -# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N. -# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N. -# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_NVR_LOG=N sets logging level at N. -# -DENABLE_PC_LOG=N sets logging level at N. -# -DENABLE_PCI_LOG=N sets logging level at N. -# -DENABLE_PIC_LOG=N sets logging level at N. -# -DENABLE_PIIX_LOG=N sets logging level at N. -# -DENABLE_ROM_LOG=N sets logging level at N. -# -DENABLE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_VNC_LOG=N sets logging level at N. -# cdrom/ logging: -# -DENABLE_CDROM_LOG=N sets logging level at N. -# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N. -# cpu/ logging: -# -DENABLE_386_LOG=N sets logging level at N. -# -DENABLE_386_DYNAREC_LOG=N sets logging level at N. -# -DENABLE_808X_LOG=N sets logging level at N. -# -DENABLE_X86SEG_LOG=N sets logging level at N. -# disk/ logging: -# -DENABLE_ESDI_AT_LOG=N sets logging level at N. -# -DENABLE_ESDI_MCA_LOG=N sets logging level at N. -# -DENABLE_HDC_LOG=N sets logging level at N. -# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N. -# -DENABLE_IDE_LOG=N sets logging level at N. -# -DENABLE_MFM_AT_LOG=N sets logging level at N. -# -DENABLE_MFM_XT_LOG=N sets logging level at N. -# -DENABLE_XTA_LOG=N sets logging level at N. -# -DENABLE_ZIP_LOG=N sets logging level at N. -# floppy/ logging: -# -DENABLE_D86F_LOG=N sets logging level at N. -# -DENABLE_FDC_LOG=N sets logging level at N. -# -DENABLE_FDD_LOG=N sets logging level at N. -# -DENABLE_FDI_LOG=N sets logging level at N. -# -DENABLE_FDI2RAW_LOG=N sets logging level at N. -# -DENABLE_IMD_LOG=N sets logging level at N. -# -DENABLE_IMG_LOG=N sets logging level at N. -# -DENABLE_JSON_LOG=N sets logging level at N. -# -DENABLE_TD0_LOG=N sets logging level at N. -# machine/ logging: -# -DENABLE_AMSTRAD_LOG=N sets logging level at N. -# -DENABLE_EUROPC_LOG=N sets logging level at N. -# -DENABLE_MACHINE_LOG=N sets logging level at N. -# -DENABLE_PS1_HDC_LOG=N sets logging level at N. -# -DENABLE_PS2_MCA_LOG=N sets logging level at N. -# -DENABLE_T1000_LOG=N sets logging level at N. -# -DENABLE_T3100E_LOG=N sets logging level at N. -# -DENABLE_TANDY_LOG=N sets logging level at N. -# network/ logging: -# -DENABLE_NETWORK_LOG=N sets logging level at N. -# -DENABLE_NIC_LOG=N sets logging level at N. -# -DENABLE_PCAP_LOG=N sets logging level at N. -# -DENABLE_SLIRP_LOG=N sets logging level at N. -# scsi/ logging: -# -DENABLE_AHA154X_LOG=N sets logging level at N. -# -DENABLE_BUSLOGIC_LOG=N sets logging level at N. -# -DENABLE_NCR5380_LOG=N sets logging level at N. -# -DENABLE_NCR53C810_LOG=N sets logging level at N. -# -DENABLE_SCSI_LOG=N sets logging level at N. -# -DENABLE_SCSI_BUS_LOG=N sets logging level at N. -# -DENABLE_SCSI_DISK_LOG=N sets logging level at N. -# -DENABLE_X54X_LOG=N sets logging level at N. -# sound/ logging: -# -DENABLE_ADLIB_LOG=N sets logging level at N. -# -DENABLE_AUDIOPCI_LOG=N sets logging level at N. -# -DENABLE_EMU8K_LOG=N sets logging level at N. -# -DENABLE_MPU401_LOG=N sets logging level at N. -# -DENABLE_PAS16_LOG=N sets logging level at N. -# -DENABLE_SB_LOG=N sets logging level at N. -# -DENABLE_SB_DSP_LOG=N sets logging level at N. -# -DENABLE_SOUND_LOG=N sets logging level at N. -# video/ logging: -# -DENABLE_ATI28800_LOG=N sets logging level at N. -# -DENABLE_MACH64_LOG=N sets logging level at N. -# -DENABLE_ET4000W32_LOG=N sets logging level at N. -# -DENABLE_NV_RIVA_LOG=N sets logging level at N. -# -DENABLE_NVIDIA_LOG=N sets logging level at N. -# -DENABLE_S3_VIRGE_LOG=N sets logging level at N. -# -DENABLE_VID_TABLE_LOG=N sets logging level at N. -# -DENABLE_VOODOO_LOG=N sets logging level at N. -# -DENABLE_VRAM_DUMP=N sets logging level at N. -# win/ logging: -# -DENABLE_DDRAW_LOG=N sets logging level at N. -# -DENABLE_DYNLD_LOG=N sets logging level at N. -# -DENABLE_JOYSTICK_LOG=N sets logging level at N. -# -DENABLE_SDL_LOG=N sets logging level at N. -# -DENABLE_WIN_LOG=N sets logging level at N. -EXTRAS := - - -AUTODEP := n -CRASHDUMP := n -DEBUG := n -OPTIM := n -X64 := n -RELEASE := n -USB := n -VNC := n -RDP := n -DEV_BUILD := n -DEV_BRANCH := n -CIRRUS := n -NE1000 := n -NV_RIVA := n -OPENAL := y -FLUIDSYNTH := y -MUNT := y -PAS16 := n -DYNAREC := y - - -######################################################################### -# Include the master Makefile.MinGW for the rest. # -######################################################################### -include win/Makefile.mingw - - -# End of Makefile.local. diff --git a/src - Cópia/bugger.c b/src - Cópia/bugger.c deleted file mode 100644 index 0619a0bb0..000000000 --- a/src - Cópia/bugger.c +++ /dev/null @@ -1,365 +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. - * - * Implementation of the ISA Bus (de)Bugger expansion card - * sold as a DIY kit in the late 1980's in The Netherlands. - * This card was a assemble-yourself 8bit ISA addon card for - * PC and AT systems that had several tools to aid in low- - * level debugging (mostly for faulty BIOSes, bootloaders - * and system kernels...) - * - * The standard version had a total of 16 LEDs (8 RED, plus - * 8 GREEN), two 7-segment displays and one 8-position DIP - * switch block on board for use as debugging tools. - * - * The "Plus" version, added an extra 2 7-segment displays, - * as well as a very simple RS-232 serial interface that - * could be used as a mini-console terminal. - * - * Two I/O ports were used; one for control, at offset 0 in - * I/O space, and one for data, at offset 1 in I/O space. - * Both registers could be read from and written to. Although - * the author has a vague memory of a DIP switch to set the - * board's I/O address, comments in old software seems to - * indicate that it was actually fixed to 0x7A (and 0x7B.) - * - * A READ on the data register always returned the actual - * state of the DIP switch. Writing data to the LEDs was done - * in two steps.. first, the block number (RED or GREEN) was - * written to the CTRL register, and then the actual LED data - * was written to the DATA register. Likewise, data for the - * 7-segment displays was written. - * - * The serial port was a bit different, and its operation is - * not verified, but two extra bits in the control register - * were used to set up parameters, and also the actual data - * input and output. - * - * TODO: Still have to implement the RS232 Serial Port Parameters - * configuration register (CTRL_SPCFG bit set) but have to - * remember that stuff first... - * - * Version: @(#)bugger.c 1.0.12 2018/04/29 - * - * Author: Fred N. van Kempen, - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "io.h" -#include "device.h" -#include "plat.h" -#include "ui.h" -#include "bugger.h" - - -/* BugBugger registers. */ -#define BUG_CTRL 0 -# define CTRL_RLED 0x00 /* write to the RED LED block */ -# define CTRL_GLED 0x01 /* write to the GREEN LED block */ -# define CTRL_SEG1 0x02 /* write to the RIGHT 7SEG displays */ -# define CTRL_SEG2 0x04 /* write to the LEFT 7SEG displays */ -# define CTRL_SPORT 0x20 /* enable the serial port */ -# define CTRL_SPCFG 0x40 /* set up the serial port */ -# define CTRL_INIT 0x80 /* enable and reset the card */ -# define CTRL_RESET 0xff /* this resets the board */ -#define BUG_DATA 1 - - -static uint8_t bug_ctrl, /* control register */ - bug_data, /* data register */ - bug_ledr, bug_ledg, /* RED and GREEN LEDs */ - bug_seg1, bug_seg2, /* LEFT and RIGHT 7SEG displays */ - bug_spcfg; /* serial port configuration */ -# define FIFO_LEN 256 -static uint8_t bug_buff[FIFO_LEN], /* serial port data buffer */ - *bug_bptr; -# define UISTR_LEN 24 -static char bug_str[UISTR_LEN]; /* UI output string */ - - -extern void ui_sb_bugui(char *__str); - - -#ifdef ENABLE_BUGGER_LOG -int bugger_do_log = ENABLE_BUGGER_LOG; -#endif - - -static void -bugger_log(const char *format, ...) -{ -#ifdef ENABLE_BUGGER_LOG - va_list ap; - - if (bugger_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Update the system's UI with the actual Bugger status. */ -static void -bug_setui(void) -{ - /* Format all current info in a string. */ - sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c", - bug_seg2, bug_seg1, - (bug_ledg&0x80)?'G':'g', (bug_ledg&0x40)?'G':'g', - (bug_ledg&0x20)?'G':'g', (bug_ledg&0x10)?'G':'g', - (bug_ledg&0x08)?'G':'g', (bug_ledg&0x04)?'G':'g', - (bug_ledg&0x02)?'G':'g', (bug_ledg&0x01)?'G':'g', - (bug_ledr&0x80)?'R':'r', (bug_ledr&0x40)?'R':'r', - (bug_ledr&0x20)?'R':'r', (bug_ledr&0x10)?'R':'r', - (bug_ledr&0x08)?'R':'r', (bug_ledr&0x04)?'R':'r', - (bug_ledr&0x02)?'R':'r', (bug_ledr&0x01)?'R':'r'); - - /* Send formatted string to the UI. */ - ui_sb_bugui(bug_str); -} - - -/* Flush the serial port. */ -static void -bug_spflsh(void) -{ - *bug_bptr = '\0'; - bugger_log("BUGGER- serial port [%s]\n", bug_buff); - bug_bptr = bug_buff; -} - - -/* Handle a write to the Serial Port Data register. */ -static void -bug_wsport(uint8_t val) -{ - uint8_t old = bug_ctrl; - - /* Clear the SPORT bit to indicate we are busy. */ - bug_ctrl &= ~CTRL_SPORT; - - /* Delay while processing byte.. */ - if (bug_bptr == &bug_buff[FIFO_LEN-1]) { - /* Buffer full, gotta flush. */ - bug_spflsh(); - } - - /* Write (store) the byte. */ - *bug_bptr++ = val; - - /* Restore the SPORT bit. */ - bug_ctrl |= (old & CTRL_SPORT); - - bugger_log("BUGGER- sport %02x\n", val); -} - - -/* Handle a write to the Serial Port Configuration register. */ -static void -bug_wspcfg(uint8_t val) -{ - bug_spcfg = val; - - bugger_log("BUGGER- spcfg %02x\n", bug_spcfg); -} - - -/* Handle a write to the control register. */ -static void -bug_wctrl(uint8_t val) -{ - if (val == CTRL_RESET) { - /* User wants us to reset. */ - bug_ctrl = CTRL_INIT; - bug_spcfg = 0x00; - bug_bptr = NULL; - } else { - /* If turning off the serial port, flush it. */ - if ((bug_ctrl & CTRL_SPORT) && !(val & CTRL_SPORT)) - bug_spflsh(); - - /* FIXME: did they do this using an XOR of operation bits? --FvK */ - - if (val & CTRL_SPCFG) { - /* User wants to configure the serial port. */ - bug_ctrl &= ~(CTRL_SPORT|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); - bug_ctrl |= CTRL_SPCFG; - } else if (val & CTRL_SPORT) { - /* User wants to talk to the serial port. */ - bug_ctrl &= ~(CTRL_SPCFG|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); - bug_ctrl |= CTRL_SPORT; - if (bug_bptr == NULL) - bug_bptr = bug_buff; - } else if (val & CTRL_SEG2) { - /* User selected SEG2 (LEFT, Plus only) for output. */ - bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG1|CTRL_GLED); - bug_ctrl |= CTRL_SEG2; - } else if (val & CTRL_SEG1) { - /* User selected SEG1 (RIGHT) for output. */ - bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_GLED); - bug_ctrl |= CTRL_SEG1; - } else if (val & CTRL_GLED) { - /* User selected the GREEN LEDs for output. */ - bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_SEG1); - bug_ctrl |= CTRL_GLED; - } else { - /* User selected the RED LEDs for output. */ - bug_ctrl &= - ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); - } - } - - /* Update the UI with active settings. */ - bugger_log("BUGGER- ctrl %02x\n", bug_ctrl); - bug_setui(); -} - - -/* Handle a write to the data register. */ -static void -bug_wdata(uint8_t val) -{ - bug_data = val; - - if (bug_ctrl & CTRL_SPCFG) - bug_wspcfg(val); - else if (bug_ctrl & CTRL_SPORT) - bug_wsport(val); - else { - if (bug_ctrl & CTRL_SEG2) - bug_seg2 = val; - else if (bug_ctrl & CTRL_SEG1) - bug_seg1 = val; - else if (bug_ctrl & CTRL_GLED) - bug_ledg = val; - else - bug_ledr = val; - - bugger_log("BUGGER- data %02x\n", bug_data); - } - - /* Update the UI with active settings. */ - bug_setui(); -} - - -/* Reset the ISA BusBugger controller. */ -static void -bug_reset(void) -{ - /* Clear the data register. */ - bug_data = 0x00; - - /* Clear the RED and GREEN LEDs. */ - bug_ledr = 0x00; bug_ledg = 0x00; - - /* Clear both 7SEG displays. */ - bug_seg1 = 0x00; bug_seg2 = 0x00; - - /* Reset the control register (updates UI.) */ - bug_wctrl(CTRL_RESET); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bug_write(uint16_t port, uint8_t val, void *priv) -{ - switch (port-BUGGER_ADDR) { - case BUG_CTRL: /* control register */ - if (val == CTRL_RESET) { - /* Perform a full reset. */ - bug_reset(); - } else if (bug_ctrl & CTRL_INIT) { - /* Only allow writes if initialized. */ - bug_wctrl(val); - } - break; - - case BUG_DATA: /* data register */ - if (bug_ctrl & CTRL_INIT) { - bug_wdata(val); - } - break; - - } -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bug_read(uint16_t port, void *priv) -{ - uint8_t ret = 0xff; - - if (bug_ctrl & CTRL_INIT) switch (port-BUGGER_ADDR) { - case BUG_CTRL: /* control register */ - ret = bug_ctrl; - break; - - case BUG_DATA: /* data register */ - if (bug_ctrl & CTRL_SPCFG) { - ret = bug_spcfg; - } else if (bug_ctrl & CTRL_SPORT) { - ret = 0x00; /* input not supported */ - } else { - /* Just read the DIP switch. */ - ret = bug_data; - } - break; - - default: - break; - } - - return(ret); -} - - -/* Initialize the ISA BusBugger emulator. */ -static void * -bug_init(const device_t *info) -{ - bugger_log("%s, I/O=%04x\n", info->name, BUGGER_ADDR); - - /* Initialize local registers. */ - bug_reset(); - - io_sethandler(BUGGER_ADDR, BUGGER_ADDRLEN, - bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); - - /* Just so its not NULL. */ - return(&bug_ctrl); -} - - -/* Remove the ISA BusBugger emulator from the system. */ -static void -bug_close(UNUSED(void *priv)) -{ - io_removehandler(BUGGER_ADDR, BUGGER_ADDRLEN, - bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); -} - - -const device_t bugger_device = { - "ISA/PCI Bus Bugger", - DEVICE_ISA | DEVICE_AT, - 0, - bug_init, bug_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/bugger.h b/src - Cópia/bugger.h deleted file mode 100644 index d3a1ac775..000000000 --- a/src - Cópia/bugger.h +++ /dev/null @@ -1,48 +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. - * - * Implementation of the ISA Bus (de)Bugger expansion card - * sold as a DIY kit in the late 1980's in The Netherlands. - * This card was a assemble-yourself 8bit ISA addon card for - * PC and AT systems that had several tools to aid in low- - * level debugging (mostly for faulty BIOSes, bootloaders - * and system kernels...) - * - * Definitions for the BUGGER card. - * - * Version: @(#)bugger.h 1.0.6 2018/03/18 - * - * Author: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#ifndef BUGGER_H -# define BUGGER_H - - -/* I/O port range used. */ -#define BUGGER_ADDR 0x007a -#define BUGGER_ADDRLEN 4 - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global variables. */ -extern const device_t bugger_device; - - -/* Functions. */ - -#ifdef __cplusplus -} -#endif - - -#endif /*BUGGER_H*/ diff --git a/src - Cópia/cdrom/cdrom.c b/src - Cópia/cdrom/cdrom.c deleted file mode 100644 index a0e46eeec..000000000 --- a/src - Cópia/cdrom/cdrom.c +++ /dev/null @@ -1,3274 +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. - * - * Implementation of the CD-ROM drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * Version: @(#)cdrom.c 1.0.48 2018/05/28 - * - * Author: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi.h" -#include "../nvr.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" -#include "../sound/sound.h" -#include "../ui.h" -#include "cdrom.h" -#include "cdrom_image.h" -#include "cdrom_null.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define MIN_SEEK 2000 -#define MAX_SEEK 333333 - -#define cdbufferb dev->buffer - - -cdrom_t *cdrom[CDROM_NUM]; -cdrom_image_t cdrom_image[CDROM_NUM]; -cdrom_drive_t cdrom_drives[CDROM_NUM]; -uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; - - -#pragma pack(push,1) -static struct -{ - uint8_t opcode; - uint8_t polled; - uint8_t reserved2[2]; - uint8_t class; - uint8_t reserved3[2]; - uint16_t len; - uint8_t control; -} *gesn_cdb; -#pragma pack(pop) - -#pragma pack(push,1) -static struct -{ - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; -} *gesn_event_header; -#pragma pack(pop) - - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t cdrom_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, /* 0x02 */ - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, /* 0x04-0x07 */ - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, 0, /* 0x09-0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, /* 0x14 */ - IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, /* 0x16-0x19 */ - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, /* 0x1C-0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, /* 0x26-0x27 */ - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, 0, /* 0x29-0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, 0, /* 0x2C-0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ - 0, 0, /* 0x40-0x41 */ - IMPLEMENTED | CHECK_READY, /* 0x42 */ - IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, /* 0x44 */ - IMPLEMENTED | CHECK_READY, /* 0x45 */ - IMPLEMENTED | ALLOW_UA, /* 0x46 */ - IMPLEMENTED | CHECK_READY, /* 0x47 */ - IMPLEMENTED | CHECK_READY, /* 0x48 */ - 0, /* 0x49 */ - IMPLEMENTED | ALLOW_UA, /* 0x4A */ - IMPLEMENTED | CHECK_READY, /* 0x4B */ - 0, 0, /* 0x4C-0x4D */ - IMPLEMENTED | CHECK_READY, /* 0x4E */ - 0, 0, /* 0x4F-0x50 */ - IMPLEMENTED | CHECK_READY, /* 0x51 */ - IMPLEMENTED | CHECK_READY, /* 0x52 */ - 0, 0, /* 0x53-0x54 */ - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, /* 0x56-0x59 */ - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, /* 0x5B-0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ - 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ - IMPLEMENTED | CHECK_READY, /* 0xA5 */ - 0, 0, /* 0xA6-0xA7 */ - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, 0, 0, 0, /* 0xA9-0xAC */ - IMPLEMENTED | CHECK_READY, /* 0xAD */ - 0, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, /* 0xB0-0xB3 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ - 0, 0, 0, /* 0xB5-0xB7 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ - IMPLEMENTED | CHECK_READY, /* 0xB9 */ - IMPLEMENTED | CHECK_READY, /* 0xBA */ - IMPLEMENTED, /* 0xBB */ - IMPLEMENTED | CHECK_READY, /* 0xBC */ - IMPLEMENTED, /* 0xBD */ - IMPLEMENTED | CHECK_READY, /* 0xBE */ - IMPLEMENTED | CHECK_READY, /* 0xBF */ - 0, 0, /* 0xC0-0xC1 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC3-0xCC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ - IMPLEMENTED | SCSI_ONLY, /* 0xDA */ - 0, 0, 0, 0, 0, /* 0xDB-0xDF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ -}; - -static uint64_t cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | - GPMODEP_CDROM_PAGE | - GPMODEP_CDROM_AUDIO_PAGE | - GPMODEP_CAPABILITIES_PAGE | - GPMODEP_ALL_PAGES); - - -static const mode_sense_pages_t cdrom_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } -} }; - -static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { 0x8E, 0xE, 5, 4, 0,128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } -} }; - -static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { 0x8E, 0xE, 5, 4, 0,128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } -} }; - -uint8_t cdrom_read_capacity_cdb[12] = {0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - -static void cdrom_command_complete(cdrom_t *dev); - -static void cdrom_mode_sense_load(cdrom_t *dev); - -static void cdrom_init(cdrom_t *dev); -void cdrom_phase_callback(cdrom_t *dev); - - -#ifdef ENABLE_CDROM_LOG -int cdrom_do_log = ENABLE_CDROM_LOG; -#endif - - -static void -cdrom_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_LOG - va_list ap; - - if (cdrom_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -int -find_cdrom_for_channel(uint8_t channel) -{ - uint8_t i = 0; - - for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) && (cdrom_drives[i].ide_channel == channel)) - return i; - } - return 0xff; -} - - -void -build_atapi_cdrom_map() -{ - uint8_t i = 0; - - memset(atapi_cdrom_drives, 0xff, 8); - - for (i = 0; i < 8; i++) - atapi_cdrom_drives[i] = find_cdrom_for_channel(i); -} - - -int -find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t i = 0; - - for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) - return i; - } - return 0xff; -} - - -void -build_scsi_cdrom_map() -{ - uint8_t i = 0; - uint8_t j = 0; - - for (i = 0; i < 16; i++) - memset(scsi_cdrom_drives[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_cdrom_drives[i][j] = find_cdrom_for_scsi_id(i, j); - } -} - - -static void -cdrom_set_callback(cdrom_t *dev) -{ - if (dev && dev->drv && (dev->drv->bus_type != CDROM_BUS_SCSI)) - ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); -} - - -void -cdrom_set_signature(cdrom_t *dev) -{ - if (!dev) - return; - dev->phase = 1; - dev->request_length = 0xEB14; -} - - -static void -cdrom_init(cdrom_t *dev) -{ - if (!dev) - return; - - /* Tell the cdrom_t struct what cdrom_drives element corresponds to it. */ - dev->drv = &(cdrom_drives[dev->id]); - - /* Do a reset (which will also rezero it). */ - cdrom_reset(dev); - - /* Configure the drive. */ - dev->requested_blocks = 1; - - dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= CDROM_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < CDROM_BUS_SCSI) - dev->drv->bus_mode |= 1; - cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - dev->cdb_len = 12; - - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; - dev->packet_status = 0xff; - cdrom_sense_key = cdrom_asc = cdrom_ascq = dev->unit_attention = 0; - dev->cur_speed = dev->drv->speed; - cdrom_mode_sense_load(dev); -} - - -static int -cdrom_supports_pio(cdrom_t *dev) -{ - return (dev->drv->bus_mode & 1); -} - - -static int -cdrom_supports_dma(cdrom_t *dev) -{ - return (dev->drv->bus_mode & 2); -} - - -/* Returns: 0 for none, 1 for PIO, 2 for DMA. */ -static int -cdrom_current_mode(cdrom_t *dev) -{ - if (!cdrom_supports_pio(dev) && !cdrom_supports_dma(dev)) - return 0; - if (cdrom_supports_pio(dev) && !cdrom_supports_dma(dev)) { - cdrom_log("CD-ROM %i: Drive does not support DMA, setting to PIO\n", dev->id); - return 1; - } - if (!cdrom_supports_pio(dev) && cdrom_supports_dma(dev)) - return 2; - if (cdrom_supports_pio(dev) && cdrom_supports_dma(dev)) { - cdrom_log("CD-ROM %i: Drive supports both, setting to %s\n", dev->id, - (dev->features & 1) ? "DMA" : "PIO", - dev->id); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -cdrom_CDROM_PHASE_to_scsi(cdrom_t *dev) -{ - if (dev->status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -cdrom_atapi_phase_to_scsi(cdrom_t *dev) -{ - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; - } - - return 0; -} - - -int -cdrom_lba_to_msf_accurate(int lba) -{ - int temp_pos; - int m, s, f; - - temp_pos = lba + 150; - f = temp_pos % 75; - temp_pos -= f; - temp_pos /= 75; - s = temp_pos % 60; - temp_pos -= s; - temp_pos /= 60; - m = temp_pos; - - return ((m << 16) | (s << 8) | f); -} - - -uint32_t -cdrom_mode_sense_get_channel(cdrom_t *dev, int channel) -{ - return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; -} - - -uint32_t -cdrom_mode_sense_get_volume(cdrom_t *dev, int channel) -{ - return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; -} - - -static void -cdrom_mode_sense_load(cdrom_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - int i; - - memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - for (i = 0; i < 0x3f; i++) { - if (cdrom_mode_sense_pages_default.pages[i][1] != 0) { - if (dev->drv->bus_type == CDROM_BUS_SCSI) - memcpy(dev->ms_pages_saved.pages[i], - cdrom_mode_sense_pages_default_scsi.pages[i], - cdrom_mode_sense_pages_default_scsi.pages[i][1] + 2); - else - memcpy(dev->ms_pages_saved.pages[i], - cdrom_mode_sense_pages_default.pages[i], - cdrom_mode_sense_pages_default.pages[i][1] + 2); - } - } - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - swprintf(file_name, 512, L"scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), L"rb"); - if (f) { - fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); - fclose(f); - } -} - - -static void -cdrom_mode_sense_save(cdrom_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - swprintf(file_name, 512, L"scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), L"wb"); - if (f) { - fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); - fclose(f); - } -} - - -int -cdrom_read_capacity(cdrom_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - int size = 0; - - size = dev->handler->size(dev->id) - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(buffer, 0, 8); - buffer[0] = (size >> 24) & 0xff; - buffer[1] = (size >> 16) & 0xff; - buffer[2] = (size >> 8) & 0xff; - buffer[3] = size & 0xff; - buffer[6] = 8; /* 2048 = 0x0800 */ - *len = 8; - - return 1; -} - - -/*SCSI Mode Sense 6/10*/ -static uint8_t -cdrom_mode_sense_read(cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) -{ - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - return cdrom_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - return cdrom_mode_sense_pages_default_scsi.pages[page][pos]; - else - return cdrom_mode_sense_pages_default.pages[page][pos]; - break; - } - - return 0; -} - - -static uint32_t -cdrom_mode_sense(cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) -{ - uint8_t page_control = (type >> 6) & 3; - int i = 0, j = 0; - - uint8_t msplen; - - type &= 0x3f; - - if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = 0; /* Number of blocks (0 = all). */ - buf[pos++] = 0; - buf[pos++] = 0; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ - buf[pos++] = 8; - buf[pos++] = 0; - } - - for (i = 0; i < 0x40; i++) { - if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (cdrom_mode_sense_page_flags & (1LL << dev->current_page_code)) { - buf[pos++] = cdrom_mode_sense_read(dev, page_control, i, 0); - msplen = cdrom_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) { - if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { - if (j & 1) - buf[pos++] = ((dev->drv->speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->speed * 176) >> 8); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { - if (j & 1) - buf[pos++] = ((dev->cur_speed * 176) & 0xff); - else - buf[pos++] = ((dev->cur_speed * 176) >> 8); - } else - buf[pos++] = cdrom_mode_sense_read(dev, page_control, i, 2 + j); - } - } - } - } - - return pos; -} - - -static void -cdrom_update_request_length(cdrom_t *dev, int len, int block_len) -{ - int32_t bt, min_len = 0; - - dev->max_transfer_len = dev->request_length; - - /* For media access commands, make sure the requested DRQ length matches the block length. */ - switch (dev->current_cdb[0]) { - case 0x08: - case 0x28: - case 0xa8: - case 0xb9: - case 0xbe: - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; - - min_len = block_len; - - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - default: - dev->packet_len = len; - break; - } - /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; - - if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; - else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; - - return; -} - - -static double -cdrom_get_short_seek(cdrom_t *dev) -{ - switch(dev->cur_speed) { - case 0: - fatal("CD-ROM %i: 0x speed\n", dev->id); - return 0.0; - case 1: - return 240.0; - case 2: - return 160.0; - case 3: - return 150.0; - case 4: case 5: case 6: case 7: case 8: - case 9: case 10: case 11: - return 112.0; - case 12: case 13: case 14: case 15: - return 75.0; - case 16: case 17: case 18: case 19: - return 58.0; - case 20: case 21: case 22: case 23: - case 40: case 41: case 42: case 43: - case 44: case 45: case 46: case 47: - case 48: - return 50.0; - default: - /* 24-32, 52+ */ - return 45.0; - } -} - - -static double -cdrom_get_long_seek(cdrom_t *dev) -{ - switch(dev->cur_speed) { - case 0: - fatal("CD-ROM %i: 0x speed\n", dev->id); - return 0.0; - case 1: - return 1446.0; - case 2: - return 1000.0; - case 3: - return 900.0; - case 4: case 5: case 6: case 7: case 8: - case 9: case 10: case 11: - return 675.0; - case 12: case 13: case 14: case 15: - return 400.0; - case 16: case 17: case 18: case 19: - return 350.0; - case 20: case 21: case 22: case 23: - case 40: case 41: case 42: case 43: - case 44: case 45: case 46: case 47: - case 48: - return 300.0; - default: - /* 24-32, 52+ */ - return 270.0; - } -} - - -static double -cdrom_seek_time(cdrom_t *dev) -{ - uint32_t diff = dev->seek_diff; - double sd = (double) (MAX_SEEK - MIN_SEEK); - - if (diff < MIN_SEEK) - return 0.0; - if (diff > MAX_SEEK) - diff = MAX_SEEK; - - diff -= MIN_SEEK; - - return cdrom_get_short_seek(dev) + ((cdrom_get_long_seek(dev) * ((double) diff)) / sd); -} - - -static double -cdrom_bus_speed(cdrom_t *dev) -{ - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - dev->callback = -1LL; /* Speed depends on SCSI controller */ - return 0.0; - } else { - if (cdrom_current_mode(dev) == 2) - return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } -} - - -static void -cdrom_command_bus(cdrom_t *dev) -{ - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - dev->callback = 1LL * CDROM_TIME; - cdrom_set_callback(dev); -} - - -static void -cdrom_command_common(cdrom_t *dev) -{ - double bytes_per_second, period; - double dusec; - - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - dev->callback = 0LL; - - cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->cur_speed); - - if (dev->packet_status == CDROM_PHASE_COMPLETE) { - cdrom_phase_callback(dev); - dev->callback = 0LL; - } else { - switch(dev->current_cdb[0]) { - case GPCMD_REZERO_UNIT: - case 0x0b: - case 0x2b: - /* Seek time is in us. */ - period = cdrom_seek_time(dev); - cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (int64_t) period); - period = period * ((double) TIMER_USEC); - dev->callback += ((int64_t) period); - cdrom_set_callback(dev); - return; - case 0x08: - case 0x28: - case 0xa8: - /* Seek time is in us. */ - period = cdrom_seek_time(dev); - cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (int64_t) period); - period = period * ((double) TIMER_USEC); - dev->callback += ((int64_t) period); - case 0x25: - case 0x42: - case 0x43: - case 0x44: - case 0x51: - case 0x52: - case 0xad: - case 0xb8: - case 0xb9: - case 0xbe: - if (dev->current_cdb[0] == 0x42) - dev->callback += 200LL * CDROM_TIME; - /* Account for seek time. */ - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->cur_speed; - break; - default: - bytes_per_second = cdrom_bus_speed(dev); - if (bytes_per_second == 0.0) { - dev->callback = -1LL; /* Speed depends on SCSI controller */ - return; - } - break; - } - - period = 1000000.0 / bytes_per_second; - cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (int64_t) period); - period = period * (double) (dev->packet_len); - cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (int64_t) period); - dusec = period * ((double) TIMER_USEC); - dev->callback += ((int64_t) dusec); - } - cdrom_set_callback(dev); -} - - -static void -cdrom_command_complete(cdrom_t *dev) -{ - dev->packet_status = CDROM_PHASE_COMPLETE; - cdrom_command_common(dev); -} - - -static void -cdrom_command_read(cdrom_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_IN; - cdrom_command_common(dev); - dev->total_read = 0; -} - - -static void -cdrom_command_read_dma(cdrom_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_IN_DMA; - cdrom_command_common(dev); - dev->total_read = 0; -} - - -static void -cdrom_command_write(cdrom_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_OUT; - cdrom_command_common(dev); -} - - -static void cdrom_command_write_dma(cdrom_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_OUT_DMA; - cdrom_command_common(dev); -} - - -/* id = Current CD-ROM device ID; - len = Total transfer length; - block_len = Length of a single block (why does it matter?!); - alloc_len = Allocated transfer length; - direction = Transfer direction (0 = read from host, 1 = write to host). */ -static void cdrom_data_command_finish(cdrom_t *dev, int len, int block_len, int alloc_len, int direction) -{ - cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos = 0; - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if ((len == 0) || (cdrom_current_mode(dev) == 0)) { - if (dev->drv->bus_type != CDROM_BUS_SCSI) - dev->packet_len = 0; - - cdrom_command_complete(dev); - } else { - if (cdrom_current_mode(dev) == 2) { - if (dev->drv->bus_type != CDROM_BUS_SCSI) - dev->packet_len = alloc_len; - - if (direction == 0) - cdrom_command_read_dma(dev); - else - cdrom_command_write_dma(dev); - } else { - cdrom_update_request_length(dev, len, block_len); - if (direction == 0) - cdrom_command_read(dev); - else - cdrom_command_write(dev); - } - } - - cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); -} - - -static void -cdrom_sense_clear(cdrom_t *dev, int command) -{ - dev->previous_command = command; - cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; -} - - -static void -cdrom_set_phase(cdrom_t *dev, uint8_t phase) -{ - uint8_t scsi_id = dev->drv->scsi_device_id; - uint8_t scsi_lun = dev->drv->scsi_device_lun; - - if (dev->drv->bus_type != CDROM_BUS_SCSI) - return; - - SCSIDevices[scsi_id][scsi_lun].Phase = phase; -} - - -static void -cdrom_cmd_error(cdrom_t *dev) -{ - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * CDROM_TIME; - cdrom_set_callback(dev); - cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, cdrom_sense_key, cdrom_asc, cdrom_ascq); -} - - -static void -cdrom_unit_attention(cdrom_t *dev) -{ - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * CDROM_TIME; - cdrom_set_callback(dev); - cdrom_log("CD-ROM %i: UNIT ATTENTION\n", dev->id); -} - - -static void -cdrom_bus_master_error(cdrom_t *dev) -{ - cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_not_ready(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_NOT_READY; - cdrom_asc = ASC_MEDIUM_NOT_PRESENT; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_invalid_lun(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_INV_LUN; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_illegal_opcode(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_ILLEGAL_OPCODE; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_lba_out_of_range(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_LBA_OUT_OF_RANGE; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_invalid_field(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; - cdrom_ascq = 0; - cdrom_cmd_error(dev); - dev->status = 0x53; -} - - -static void -cdrom_invalid_field_pl(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - cdrom_ascq = 0; - cdrom_cmd_error(dev); - dev->status = 0x53; -} - - -static void -cdrom_illegal_mode(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -static void -cdrom_incompatible_format(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_INCOMPATIBLE_FORMAT; - cdrom_ascq = 2; - cdrom_cmd_error(dev); -} - - -static void -cdrom_data_phase_error(cdrom_t *dev) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_DATA_PHASE_ERROR; - cdrom_ascq = 0; - cdrom_cmd_error(dev); -} - - -void -cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) -{ - int temp = 0; - - switch(cdb[0]) { - case GPCMD_READ_6: - cdb[1] = (lba_pos >> 16) & 0xff; - cdb[2] = (lba_pos >> 8) & 0xff; - cdb[3] = lba_pos & 0xff; - break; - - case GPCMD_READ_10: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[7] = (number_of_blocks >> 8) & 0xff; - cdb[8] = number_of_blocks & 0xff; - break; - - case GPCMD_READ_12: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[6] = (number_of_blocks >> 24) & 0xff; - cdb[7] = (number_of_blocks >> 16) & 0xff; - cdb[8] = (number_of_blocks >> 8) & 0xff; - cdb[9] = number_of_blocks & 0xff; - break; - - case GPCMD_READ_CD_MSF: - temp = cdrom_lba_to_msf_accurate(lba_pos); - cdb[3] = (temp >> 16) & 0xff; - cdb[4] = (temp >> 8) & 0xff; - cdb[5] = temp & 0xff; - - temp = cdrom_lba_to_msf_accurate(lba_pos + number_of_blocks - 1); - cdb[6] = (temp >> 16) & 0xff; - cdb[7] = (temp >> 8) & 0xff; - cdb[8] = temp & 0xff; - break; - - case GPCMD_READ_CD: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[6] = (number_of_blocks >> 16) & 0xff; - cdb[7] = (number_of_blocks >> 8) & 0xff; - cdb[8] = number_of_blocks & 0xff; - break; - } -} - - -static int -cdrom_read_data(cdrom_t *dev, int msf, int type, int flags, int32_t *len) -{ - int ret = 0; - uint32_t cdsize = 0; - - int i = 0; - int temp_len = 0; - - cdsize = dev->handler->size(dev->id); - - if (dev->sector_pos >= cdsize) { - cdrom_log("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", dev->id, - dev->sector_pos, cdsize); - cdrom_lba_out_of_range(dev); - return 0; - } - - if ((dev->sector_pos + dev->sector_len - 1) >= cdsize) { - cdrom_log("CD-ROM %i: Trying to read to beyond the end of disc (%i >= %i)\n", dev->id, - (dev->sector_pos + dev->sector_len - 1), cdsize); - cdrom_lba_out_of_range(dev); - return 0; - } - - dev->old_len = 0; - *len = 0; - - for (i = 0; i < dev->requested_blocks; i++) { - ret = dev->handler->readsector_raw(dev->id, cdbufferb + dev->data_pos, dev->sector_pos + i, - msf, type, flags, &temp_len); - - dev->data_pos += temp_len; - dev->old_len += temp_len; - - *len += temp_len; - - if (!ret) { - cdrom_illegal_mode(dev); - return 0; - } - } - - return 1; -} - - -static int -cdrom_read_blocks(cdrom_t *dev, int32_t *len, int first_batch) -{ - int ret = 0, msf = 0; - int type = 0, flags = 0; - - if (dev->current_cdb[0] == 0xb9) - msf = 1; - - if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - type = (dev->current_cdb[1] >> 2) & 7; - flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); - } else { - type = 8; - flags = 0x10; - } - - dev->data_pos = 0; - - if (!dev->sector_len) { - cdrom_command_complete(dev); - return -1; - } - - cdrom_log("Reading %i blocks starting from %i...\n", dev->requested_blocks, dev->sector_pos); - - cdrom_update_cdb(dev->current_cdb, dev->sector_pos, dev->requested_blocks); - - ret = cdrom_read_data(dev, msf, type, flags, len); - - cdrom_log("Read %i bytes of blocks...\n", *len); - - if (!ret || ((dev->old_len != *len) && !first_batch)) { - if ((dev->old_len != *len) && !first_batch) - cdrom_illegal_mode(dev); - - return 0; - } - - dev->sector_pos += dev->requested_blocks; - dev->sector_len -= dev->requested_blocks; - - return 1; -} - - -/*SCSI Read DVD Structure*/ -static int -cdrom_read_dvd_structure(cdrom_t *dev, int format, const uint8_t *packet, uint8_t *buf) -{ - int layer = packet[6]; - uint64_t total_sectors; - - switch (format) { - case 0x00: /* Physical format information */ - total_sectors = (uint64_t) dev->handler->size(dev->id); - - if (layer != 0) { - cdrom_invalid_field(dev); - return 0; - } - - total_sectors >>= 2; - if (total_sectors == 0) { - /* return -ASC_MEDIUM_NOT_PRESENT; */ - cdrom_not_ready(dev); - return 0; - } - - buf[4] = 1; /* DVD-ROM, part version 1 */ - buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ - buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ - buf[7] = 0; /* default densities */ - - /* FIXME: 0x30000 per spec? */ - buf[8] = buf[9] = buf[10] = buf[11] = 0; /* start sector */ - buf[12] = (total_sectors >> 24) & 0xff; /* end sector */ - buf[13] = (total_sectors >> 16) & 0xff; - buf[14] = (total_sectors >> 8) & 0xff; - buf[15] = total_sectors & 0xff; - - buf[16] = (total_sectors >> 24) & 0xff; /* l0 end sector */ - buf[17] = (total_sectors >> 16) & 0xff; - buf[18] = (total_sectors >> 8) & 0xff; - buf[19] = total_sectors & 0xff; - - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048 +2 ) >> 8) & 0xff; - buf[1] = (2048 + 2) & 0xff; - - /* 2k data + 4 byte header */ - return (2048 + 4); - - case 0x01: /* DVD copyright information */ - buf[4] = 0; /* no copyright data */ - buf[5] = 0; /* no region restrictions */ - - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((4 + 2) >> 8) & 0xff; - buf[1] = (4 + 2) & 0xff; - - /* 4 byte header + 4 byte data */ - return (4 + 4); - - case 0x03: /* BCA information - invalid field for no BCA info */ - cdrom_invalid_field(dev); - return 0; - - case 0x04: /* DVD disc manufacturing information */ - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048 + 2) >> 8) & 0xff; - buf[1] = (2048 + 2) & 0xff; - - /* 2k data + 4 byte header */ - return (2048 + 4); - - case 0xff: - /* - * This lists all the command capabilities above. Add new ones - * in order and update the length and buffer return values. - */ - - buf[4] = 0x00; /* Physical format */ - buf[5] = 0x40; /* Not writable, is readable */ - buf[6] = ((2048 + 4) >> 8) & 0xff; - buf[7] = (2048 + 4) & 0xff; - - buf[8] = 0x01; /* Copyright info */ - buf[9] = 0x40; /* Not writable, is readable */ - buf[10] = ((4 + 4) >> 8) & 0xff; - buf[11] = (4 + 4) & 0xff; - - buf[12] = 0x03; /* BCA info */ - buf[13] = 0x40; /* Not writable, is readable */ - buf[14] = ((188 + 4) >> 8) & 0xff; - buf[15] = (188 + 4) & 0xff; - - buf[16] = 0x04; /* Manufacturing info */ - buf[17] = 0x40; /* Not writable, is readable */ - buf[18] = ((2048 + 4) >> 8) & 0xff; - buf[19] = (2048 + 4) & 0xff; - - /* Size of buffer, not including 2 byte size field */ - buf[6] = ((16 + 2) >> 8) & 0xff; - buf[7] = (16 + 2) & 0xff; - - /* data written + 4 byte header */ - return (16 + 4); - - default: /* TODO: formats beyond DVD-ROM requires */ - cdrom_invalid_field(dev); - return 0; - } -} - - -void -cdrom_insert(cdrom_t *dev) -{ - dev->unit_attention = 1; - cdrom_log("CD-ROM %i: Media insert\n", dev->id); -} - - -/*SCSI Sense Initialization*/ -void -cdrom_sense_code_ok(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - cdrom_sense_key = SENSE_NONE; - cdrom_asc = 0; - cdrom_ascq = 0; -} - - -static int -cdrom_pre_execution_check(cdrom_t *dev, uint8_t *cdb) -{ - int ready = 0, status = 0; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (((dev->request_length >> 5) & 7) != dev->drv->scsi_device_lun) { - cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); - cdrom_invalid_lun(dev); - return 0; - } - } - - if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); - - cdrom_illegal_opcode(dev); - return 0; - } - - if ((dev->drv->bus_type < CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { - cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - cdrom_illegal_opcode(dev); - return 0; - } - - if ((dev->drv->bus_type == CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { - cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - cdrom_illegal_opcode(dev); - return 0; - } - - status = dev->handler->status(dev->id); - - if ((status == CD_STATUS_PLAYING) || (status == CD_STATUS_PAUSED)) { - ready = 1; - goto skip_ready_check; - } - - if (dev->handler->medium_changed(dev->id)) - cdrom_insert(dev); - - ready = dev->handler->ready(dev->id); - -skip_ready_check: - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - if (!ready && dev->unit_attention) - dev->unit_attention = 0; - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { - /* cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention++; - cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", - dev->id, cdb[0]); - cdrom_unit_attention(dev); - return 0; - } - } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */ - dev->unit_attention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (cdb[0] != GPCMD_REQUEST_SENSE) - cdrom_sense_clear(dev, cdb[0]); - - /* Next it's time for NOT READY. */ - if (!ready) - dev->media_status = MEC_MEDIA_REMOVAL; - else - dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; - - if ((cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { - cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - cdrom_not_ready(dev); - return 0; - } - - cdrom_log("CD-ROM %i: Continuing with command %02X\n", dev->id, cdb[0]); - - return 1; -} - - -static void -cdrom_seek(cdrom_t *dev, uint32_t pos) -{ - /* cdrom_log("CD-ROM %i: Seek %08X\n", dev->id, pos); */ - dev->seek_pos = pos; - if (dev->handler && dev->handler->stop) - dev->handler->stop(dev->id); -} - - -static void -cdrom_rezero(cdrom_t *dev) -{ - if (dev->handler && dev->handler->stop) - dev->handler->stop(dev->id); - dev->sector_pos = dev->sector_len = 0; - cdrom_seek(dev, 0); -} - - -void -cdrom_reset(cdrom_t *dev) -{ - if (!dev) - return; - - cdrom_rezero(dev); - dev->status = 0; - dev->callback = 0LL; - cdrom_set_callback(dev); - dev->packet_status = 0xff; - dev->unit_attention = 0xff; -} - - -static int -cdrom_playing_completed(cdrom_t *dev) -{ - dev->prev_status = dev->cd_status; - dev->cd_status = dev->handler->status(dev->id); - if (((dev->prev_status == CD_STATUS_PLAYING) || (dev->prev_status == CD_STATUS_PAUSED)) && ((dev->cd_status != CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_PAUSED))) - return 1; - else - return 0; -} - - -static void -cdrom_request_sense(cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) -{ - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - memcpy(buffer, dev->sense, alloc_length); - } - - buffer[0] = 0x70; - - if ((cdrom_sense_key > 0) && ((dev->cd_status < CD_STATUS_PLAYING) || - (dev->cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(dev)) { - buffer[2]=SENSE_ILLEGAL_REQUEST; - buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } else if ((cdrom_sense_key == 0) && (dev->cd_status >= CD_STATUS_PLAYING) && - (dev->cd_status != CD_STATUS_STOPPED)) { - buffer[2]=SENSE_ILLEGAL_REQUEST; - buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=(dev->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } else { - if (dev->unit_attention && (cdrom_sense_key == 0)) { - buffer[2]=SENSE_UNIT_ATTENTION; - buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[13]=0; - } - } - - cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); - - if (buffer[2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; - } - - /* Clear the sense stuff as per the spec. */ - cdrom_sense_clear(dev, GPCMD_REQUEST_SENSE); -} - - -void -cdrom_request_sense_for_scsi(cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) -{ - int ready = 0; - - if (dev->handler->medium_changed(dev->id)) - cdrom_insert(dev); - - ready = dev->handler->ready(dev->id); - - if (!ready && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; - } - - /* Do *NOT* advance the unit attention phase. */ - cdrom_request_sense(dev, buffer, alloc_length); -} - - -static void -cdrom_set_buf_len(cdrom_t *dev, int32_t *BufLen, int32_t *src_len) -{ - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - cdrom_log("CD-ROM %i: Actual transfer length: %i\n", dev->id, *BufLen); - } -} - - -static void -cdrom_buf_alloc(cdrom_t *dev, uint32_t len) -{ - cdrom_log("CD-ROM %i: Allocated buffer length: %i\n", dev->id, len); - cdbufferb = (uint8_t *) malloc(len); -} - - -static void -cdrom_buf_free(cdrom_t *dev) -{ - if (cdbufferb) { - cdrom_log("CD-ROM %i: Freeing buffer...\n", dev->id); - free(cdbufferb); - cdbufferb = NULL; - } -} - - -void -cdrom_command(cdrom_t *dev, uint8_t *cdb) -{ - int len, max_len, used_len, alloc_length, msf; - int pos = 0, i= 0, size_idx, idx = 0; - uint32_t feature; - unsigned preamble_len; - int toc_format, block_desc = 0; - int ret, format = 0; - int real_pos, track = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int32_t blen = 0, *BufLen; - uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - dev->status &= ~ERR_STAT; - } else { - BufLen = &blen; - dev->error = 0; - } - - dev->packet_len = 0; - dev->request_pos = 0; - - device_identify[7] = dev->id + 0x30; - - device_identify_ex[7] = dev->id + 0x30; - device_identify_ex[10] = EMU_VERSION[0]; - device_identify_ex[12] = EMU_VERSION[2]; - device_identify_ex[13] = EMU_VERSION[3]; - - dev->data_pos = 0; - - memcpy(dev->current_cdb, cdb, dev->cdb_len); - - dev->cd_status = dev->handler->status(dev->id); - - if (cdb[0] != 0) { - cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, dev->unit_attention); - cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length); - - cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); - } - - msf = cdb[1] & 2; - dev->sector_len = 0; - - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (cdrom_pre_execution_check(dev, cdb) == 0) - return; - - switch (cdb[0]) { - case GPCMD_TEST_UNIT_READY: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_command_complete(dev); - break; - - case GPCMD_REZERO_UNIT: - if (dev->handler->stop) - dev->handler->stop(dev->id); - dev->sector_pos = dev->sector_len = 0; - dev->seek_diff = dev->seek_pos; - cdrom_seek(dev, 0); - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - cdrom_buf_alloc(dev, 256); - cdrom_set_buf_len(dev, BufLen, &max_len); - cdrom_request_sense(dev, cdbufferb, max_len); - cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); - break; - - case GPCMD_SET_SPEED: - case GPCMD_SET_SPEED_ALT: - dev->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; - if (dev->cur_speed < 1) - dev->cur_speed = 1; - else if (dev->cur_speed > dev->drv->speed) - dev->cur_speed = dev->drv->speed; - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_command_complete(dev); - break; - - case GPCMD_MECHANISM_STATUS: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - cdrom_buf_alloc(dev, 8); - - cdrom_set_buf_len(dev, BufLen, &len); - - memset(cdbufferb, 0, 8); - cdbufferb[5] = 1; - - cdrom_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_TOC_PMA_ATIP: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - cdrom_buf_alloc(dev, 65536); - - toc_format = cdb[2] & 0xf; - - if (toc_format == 0) - toc_format = (cdb[9] >> 6) & 3; - - switch (toc_format) { - case 0: /*Normal*/ - len = dev->handler->readtoc(dev->id, cdbufferb, cdb[6], msf, max_len, - 0); - break; - case 1: /*Multi session*/ - len = dev->handler->readtoc_session(dev->id, cdbufferb, msf, max_len); - cdbufferb[0] = 0; cdbufferb[1] = 0xA; - break; - case 2: /*Raw*/ - len = dev->handler->readtoc_raw(dev->id, cdbufferb, max_len); - break; - default: - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - if (len > max_len) { - len = max_len; - - cdbufferb[0] = ((len - 2) >> 8) & 0xff; - cdbufferb[1] = (len - 2) & 0xff; - } - - cdrom_set_buf_len(dev, BufLen, &len); - - if (len >= 8) { - cdrom_log("CD-ROM %i: TOC: %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], - cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); - } - - if (len >= 16) { - cdrom_log(" %02X %02X %02X %02X %02X %02X %02X %02X\n", - cdbufferb[8], cdbufferb[9], cdbufferb[10], cdbufferb[11], - cdbufferb[12], cdbufferb[13], cdbufferb[14], cdbufferb[15]); - } - - if (len >= 24) { - cdrom_log(" %02X %02X %02X %02X %02X %02X %02X %02X\n", - cdbufferb[16], cdbufferb[17], cdbufferb[18], cdbufferb[19], - cdbufferb[20], cdbufferb[21], cdbufferb[22], cdbufferb[23]); - } - - if (len >= 32) { - cdrom_log(" %02X %02X %02X %02X %02X %02X %02X %02X\n", - cdbufferb[24], cdbufferb[25], cdbufferb[26], cdbufferb[27], - cdbufferb[28], cdbufferb[29], cdbufferb[30], cdbufferb[31]); - } - - if (len >= 36) { - cdrom_log(" %02X %02X %02X %02X\n", - cdbufferb[32], cdbufferb[33], cdbufferb[34], cdbufferb[35]); - } - - cdrom_data_command_finish(dev, len, len, len, 0); - /* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", dev->id, - toc_format, ide->cylinder, cdbufferb[1]); */ - return; - - case GPCMD_READ_CD_OLD: - /* IMPORTANT: Convert the command to new read CD - for pass through purposes. */ - dev->current_cdb[0] = 0xbe; - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = 2048; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - msf = 0; - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; - break; - case GPCMD_READ_CD_MSF: - alloc_length = 2856; - dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - - dev->sector_len -= dev->sector_pos; - dev->sector_len++; - msf = 1; - break; - case GPCMD_READ_CD_OLD: - case GPCMD_READ_CD: - alloc_length = 2856; - dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - msf = 0; - break; - } - - dev->seek_diff = ABS((int) (pos - dev->seek_pos)); - dev->seek_pos = dev->sector_pos; - - if (!dev->sector_len) { - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - /* cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->callback = 20LL * CDROM_TIME; - cdrom_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - cdrom_buf_alloc(dev, dev->packet_len); - - ret = cdrom_read_blocks(dev, &alloc_length, 1); - if (ret <= 0) { - cdrom_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, - alloc_length, 0); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != CDROM_PHASE_COMPLETE) - ui_sb_update_icon(SB_CDROM | dev->id, 1); - else - ui_sb_update_icon(SB_CDROM | dev->id, 0); - return; - - case GPCMD_READ_HEADER: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = ((cdb[7] << 8) | cdb[8]); - cdrom_buf_alloc(dev, 8); - - dev->sector_len = 1; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; - if (msf) - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - else - real_pos = dev->sector_pos; - cdbufferb[0] = 1; /*2048 bytes user data*/ - cdbufferb[1] = cdbufferb[2] = cdbufferb[3] = 0; - cdbufferb[4] = (real_pos >> 24); - cdbufferb[5] = ((real_pos >> 16) & 0xff); - cdbufferb[6] = ((real_pos >> 8) & 0xff); - cdbufferb[7] = real_pos & 0xff; - - len = 8; - len = MIN(len, alloc_length); - - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_data_command_finish(dev, len, len, len, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - cdrom_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - cdrom_buf_alloc(dev, 65536); - } - - dev->current_page_code = cdb[2] & 0x3F; - - if (!(cdrom_mode_sense_page_flags & (1LL << dev->current_page_code))) { - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - memset(cdbufferb, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdrom_mode_sense(dev, cdbufferb, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - cdbufferb[0] = len - 1; - cdbufferb[1] = dev->handler->media_type_id(dev->id); - if (block_desc) - cdbufferb[3] = 8; - } else { - len = cdrom_mode_sense(dev, cdbufferb, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - cdbufferb[0]=(len - 2) >> 8; - cdbufferb[1]=(len - 2) & 255; - cdbufferb[2] = dev->handler->media_type_id(dev->id); - if (block_desc) { - cdbufferb[6] = 0; - cdbufferb[7] = 8; - } - } - - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - cdrom_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - cdrom_buf_alloc(dev, 65536); - } - - cdrom_set_buf_len(dev, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - dev->current_page_pos = 0; - - cdrom_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_GET_CONFIGURATION: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - /* XXX: could result in alignment problems in some architectures */ - feature = (cdb[2] << 8) | cdb[3]; - max_len = (cdb[7] << 8) | cdb[8]; - - /* only feature 0 is supported */ - if ((cdb[2] != 0) || (cdb[3] > 2)) { - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - cdrom_buf_alloc(dev, 65536); - memset(cdbufferb, 0, max_len); - - alloc_length = 0; - b = cdbufferb; - - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (dev->handler->ready(dev->id)) { - len = dev->handler->size(dev->id); - if (len > CD_MAX_SECTORS) { - b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_DVD_ROM & 0xff; - ret = 1; - } else { - b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_CD_ROM & 0xff; - ret = 0; - } - } else - ret = 2; - - alloc_length = 8; - b += 8; - - if ((feature == 0) || ((cdb[1] & 3) < 2)) { - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - alloc_length += 4; - b += 4; - - for (i = 0; i < 2; i++) { - b[0] = (profiles[i] >> 8) & 0xff; - b[1] = profiles[i] & 0xff; - - if (ret == i) - b[2] |= 1; - - alloc_length += 4; - b += 4; - } - } - if ((feature == 1) || ((cdb[1] & 3) < 2)) { - b[1] = 1; - b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - b[7] = 1; - else - b[7] = 2; - b[8] = 1; - - alloc_length += 12; - b += 12; - } - if ((feature == 2) || ((cdb[1] & 3) < 2)) { - b[1] = 2; - b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 2; - - alloc_length += 8; - b += 8; - } - - cdbufferb[0] = ((alloc_length - 4) >> 24) & 0xff; - cdbufferb[1] = ((alloc_length - 4) >> 16) & 0xff; - cdbufferb[2] = ((alloc_length - 4) >> 8) & 0xff; - cdbufferb[3] = (alloc_length - 4) & 0xff; - - alloc_length = MIN(alloc_length, max_len); - - cdrom_set_buf_len(dev, BufLen, &alloc_length); - - cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); - break; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - cdrom_buf_alloc(dev, 8 + sizeof(gesn_event_header)); - - gesn_cdb = (void *) cdb; - gesn_event_header = (void *) cdbufferb; - - /* It is fine by the MMC spec to not support async mode operations. */ - if (!(gesn_cdb->polled & 0x01)) { - /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; - - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; - - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) { - gesn_event_header->notification_class |= GESN_MEDIA; - - cdbufferb[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ - cdbufferb[5] = 1; /* Power Status (1 = Active) */ - cdbufferb[6] = 0; - cdbufferb[7] = 0; - used_len = 8; - } else { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - - memcpy(cdbufferb, gesn_event_header, 4); - - cdrom_set_buf_len(dev, BufLen, &used_len); - - cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); - break; - - case GPCMD_READ_DISC_INFORMATION: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - cdrom_buf_alloc(dev, 65536); - - memset(cdbufferb, 0, 34); - memset(cdbufferb, 1, 9); - cdbufferb[0] = 0; - cdbufferb[1] = 32; - cdbufferb[2] = 0xe; /* last session complete, disc finalized */ - cdbufferb[7] = 0x20; /* unrestricted use */ - cdbufferb[8] = 0x00; /* CD-ROM */ - - len=34; - len = MIN(len, max_len); - - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_READ_TRACK_INFORMATION: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - cdrom_buf_alloc(dev, 65536); - - track = ((uint32_t) cdb[2]) << 24; - track |= ((uint32_t) cdb[3]) << 16; - track |= ((uint32_t) cdb[4]) << 8; - track |= (uint32_t) cdb[5]; - - if (((cdb[1] & 0x03) != 1) || (track != 1)) { - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - len = 36; - - memset(cdbufferb, 0, 36); - cdbufferb[0] = 0; - cdbufferb[1] = 34; - cdbufferb[2] = 1; /* track number (LSB) */ - cdbufferb[3] = 1; /* session number (LSB) */ - cdbufferb[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - cdbufferb[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - cdbufferb[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ - cdbufferb[24] = (dev->handler->size(dev->id) >> 24) & 0xff; /* track size */ - cdbufferb[25] = (dev->handler->size(dev->id) >> 16) & 0xff; /* track size */ - cdbufferb[26] = (dev->handler->size(dev->id) >> 8) & 0xff; /* track size */ - cdbufferb[27] = dev->handler->size(dev->id) & 0xff; /* track size */ - - if (len > max_len) { - len = max_len; - cdbufferb[0] = ((max_len - 2) >> 8) & 0xff; - cdbufferb[1] = (max_len - 2) & 0xff; - } - - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_12: - case GPCMD_PLAY_AUDIO_MSF: - case GPCMD_PLAY_AUDIO_TRACK_INDEX: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_PLAY_AUDIO_10: - msf = 0; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_PLAY_AUDIO_12: - msf = 0; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - break; - case GPCMD_PLAY_AUDIO_MSF: - /* This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it. */ - msf = 1; - pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_PLAY_AUDIO_TRACK_INDEX: - msf = 2; - pos = (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 8) | cdb[8]; - break; - } - - if ((dev->drv->host_drive < 1) || (dev->cd_status <= CD_STATUS_DATA_ONLY)) { - cdrom_illegal_mode(dev); - break; - } - - if (dev->handler->playaudio) - ret = dev->handler->playaudio(dev->id, pos, len, msf); - else - ret = 0; - - if (ret) - cdrom_command_complete(dev); - else - cdrom_illegal_mode(dev); - break; - - case GPCMD_READ_SUBCHANNEL: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = (cdb[1] >> 1) & 1; - - cdrom_buf_alloc(dev, 32); - - cdrom_log("CD-ROM %i: Getting page %i (%s)\n", dev->id, cdb[3], msf ? "MSF" : "LBA"); - - if (cdb[3] > 3) { - /* cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", dev->id, - cdb[3]); */ - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - - switch(cdb[3]) { - case 0: - alloc_length = 4; - break; - case 1: - alloc_length = 16; - break; - default: - alloc_length = 24; - break; - } - - memset(cdbufferb, 0, 24); - pos = 0; - cdbufferb[pos++] = 0; - cdbufferb[pos++] = 0; /*Audio status*/ - cdbufferb[pos++] = 0; cdbufferb[pos++] = 0; /*Subchannel length*/ - cdbufferb[pos++] = cdb[3] & 3; /*Format code*/ - if (cdb[3] == 1) { - cdbufferb[1] = dev->handler->getcurrentsubchannel(dev->id, &cdbufferb[5], msf); - switch(dev->cd_status) { - case CD_STATUS_PLAYING: - cdbufferb[1] = 0x11; - break; - case CD_STATUS_PAUSED: - cdbufferb[1] = 0x12; - break; - case CD_STATUS_DATA_ONLY: - cdbufferb[1] = 0x15; - break; - default: - cdbufferb[1] = 0x13; - break; - } - } - - if (!(cdb[2] & 0x40) || (cdb[3] == 0)) - len = 4; - else - len = alloc_length; - - len = MIN(len, max_len); - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_log("CD-ROM %i: Read subchannel:", dev->id); - for (i = 0; i < 32; i += 8) { - cdrom_log("[%02X] %02X %02X %02X %02X %02X %02X %02X %02X\n", i, - cdbufferb[i], cdbufferb[i + 1], cdbufferb[i + 2], cdbufferb[i + 3], - cdbufferb[i + 4], cdbufferb[i + 5], cdbufferb[i + 6], cdbufferb[i + 7]); - } - - cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_READ_DVD_STRUCTURE: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - - cdrom_buf_alloc(dev, alloc_length); - - len = dev->handler->size(dev->id); - - if ((cdb[7] < 0xc0) && (len <= CD_MAX_SECTORS)) { - cdrom_incompatible_format(dev); - cdrom_buf_free(dev); - return; - } - - memset(cdbufferb, 0, alloc_length); - - if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { - if (cdb[1] == 0) { - ret = cdrom_read_dvd_structure(dev, format, cdb, cdbufferb); - if (ret) { - cdrom_set_buf_len(dev, BufLen, &alloc_length); - cdrom_data_command_finish(dev, alloc_length, alloc_length, - len, 0); - } else - cdrom_buf_free(dev); - return; - } - } else { - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - break; - - case GPCMD_START_STOP_UNIT: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disc. */ - if (dev->handler->stop) - dev->handler->stop(dev->id); - break; - case 1: /* Start the disc and read the TOC. */ - dev->handler->medium_changed(dev->id); /* This causes a TOC reload. */ - break; - case 2: /* Eject the disc if possible. */ - if (dev->handler->stop) - dev->handler->stop(dev->id); - cdrom_eject(dev->id); - break; - case 3: /* Load the disc (close tray). */ - cdrom_reload(dev->id); - break; - } - - cdrom_command_complete(dev); - break; - - case GPCMD_INQUIRY: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - cdrom_buf_alloc(dev, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - cdbufferb[idx++] = 05; - cdbufferb[idx++] = cdb[2]; - cdbufferb[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - cdbufferb[idx++] = 0x00; - cdbufferb[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - cdrom_data_phase_error(dev); - cdrom_buf_free(dev); - return; - } - - cdbufferb[idx++] = 0x02; - cdbufferb[idx++] = 0x00; - cdbufferb[idx++] = 0x00; - cdbufferb[idx++] = 20; - ide_padstr8(cdbufferb + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - cdbufferb[idx++] = 0x02; - cdbufferb[idx++] = 0x01; - cdbufferb[idx++] = 0x00; - cdbufferb[idx++] = 68; - ide_padstr8(cdbufferb + idx, 8, EMU_NAME); /* Vendor */ - idx += 8; - ide_padstr8(cdbufferb + idx, 40, device_identify_ex); /* Product */ - idx += 40; - ide_padstr8(cdbufferb + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - cdrom_invalid_field(dev); - cdrom_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(cdbufferb, 0, 8); - cdbufferb[0] = 5; /*CD-ROM*/ - cdbufferb[1] = 0x80; /*Removable*/ - cdbufferb[2] = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - cdbufferb[3] = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 0x12 : 0x21; - cdbufferb[4] = 31; - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - cdbufferb[6] = 1; /* 16-bit transfers supported */ - cdbufferb[7] = 0x20; /* Wide bus supported */ - } - - ide_padstr8(cdbufferb + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(cdbufferb + 16, 16, device_identify); /* Product */ - ide_padstr8(cdbufferb + 32, 4, EMU_VERSION); /* Revision */ - idx = 36; - - if (max_len == 96) { - cdbufferb[4] = 91; - idx = 96; - } - } - -atapi_out: - cdbufferb[size_idx] = idx - preamble_len; - len=idx; - - len = MIN(len, max_len); - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_command_complete(dev); - break; - - case GPCMD_PAUSE_RESUME_ALT: - case GPCMD_PAUSE_RESUME: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - if (cdb[8] & 1) { - if (dev->handler->resume) - dev->handler->resume(dev->id); - else { - cdrom_illegal_mode(dev); - break; - } - } else { - if (dev->handler->pause) - dev->handler->pause(dev->id); - else { - cdrom_illegal_mode(dev); - break; - } - } - cdrom_command_complete(dev); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - dev->seek_diff = ABS((int) (pos - dev->seek_pos)); - cdrom_seek(dev, pos); - cdrom_command_complete(dev); - break; - - case GPCMD_READ_CDROM_CAPACITY: - cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - cdrom_buf_alloc(dev, 8); - - if (cdrom_read_capacity(dev, dev->current_cdb, cdbufferb, (uint32_t *) &len) == 0) { - cdrom_buf_free(dev); - return; - } - - cdrom_set_buf_len(dev, BufLen, &len); - - cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_STOP_PLAY_SCAN: - cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - if (dev->handler->stop) - dev->handler->stop(dev->id); - else { - cdrom_illegal_mode(dev); - break; - } - cdrom_command_complete(dev); - break; - - default: - cdrom_illegal_opcode(dev); - break; - } - - /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ - - if (cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - cdrom_buf_free(dev); -} - - -/* The command second phase function, needed for Mode Select. */ -static uint8_t -cdrom_phase_data_out(cdrom_t *dev) -{ - uint16_t block_desc_len, pos; - uint16_t i = 0; - - uint8_t error = 0; - uint8_t page, page_len, hdr_len, val, old_val, ch; - - FILE *f; - - switch(dev->current_cdb[0]) { - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - f = nvr_fopen(L"modeselect.bin", L"wb"); - fwrite(cdbufferb, 1, dev->total_length, f); - fclose(f); - - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) - hdr_len = 8; - else - hdr_len = 4; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = cdbufferb[2]; - block_desc_len <<= 8; - block_desc_len |= cdbufferb[3]; - } else { - block_desc_len = cdbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= cdbufferb[7]; - } - } else - block_desc_len = 0; - - pos = hdr_len + block_desc_len; - - while(1) { - page = cdbufferb[pos] & 0x3F; - page_len = cdbufferb[pos + 1]; - - pos += 2; - - if (!(cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { - cdrom_log("Unimplemented page %02X\n", page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = cdrom_mode_sense_pages_changeable.pages[page][i + 2]; - val = cdbufferb[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else { - cdrom_log("Unchangeable value on position %02X on page %02X\n", i + 2, page); - error |= 1; - } - } - } - } - - pos += page_len; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - val = cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - - if (dev->do_page_save && val) - cdrom_mode_sense_save(dev); - - if (pos >= dev->total_length) - break; - } - - if (error) { - cdrom_invalid_field_pl(dev); - return 0; - } - break; - } - - return 1; -} - - -/* This is the general ATAPI PIO request function. */ -static void -cdrom_pio_request(cdrom_t *dev, uint8_t out) -{ - int ret = 0; - - if (dev->drv->bus_type < CDROM_BUS_SCSI) { - cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", dev->id); - ide_irq_lower(ide_drives[dev->drv->ide_channel]); - } - - dev->status = BUSY_STAT; - - if (dev->pos >= dev->packet_len) { - cdrom_log("CD-ROM %i: %i bytes %s, command done\n", dev->id, dev->pos, out ? "written" : "read"); - - dev->pos = dev->request_pos = 0; - if (out) { - ret = cdrom_phase_data_out(dev); - /* If ret = 0 (phase 1 error), then we do not do anything else other than - free the buffer, as the phase and callback have already been set by the - error function. */ - if (ret) - cdrom_command_complete(dev); - } else - cdrom_command_complete(dev); - cdrom_buf_free(dev); - } else { - cdrom_log("CD-ROM %i: %i bytes %s, %i bytes are still left\n", dev->id, dev->pos, - out ? "written" : "read", dev->packet_len - dev->pos); - - /* If less than (packet length) bytes are remaining, update packet length - accordingly. */ - if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) - dev->max_transfer_len = dev->packet_len - dev->pos; - cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, - dev->max_transfer_len); - - dev->packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; - - dev->status = BUSY_STAT; - dev->phase = 1; - cdrom_phase_callback(dev); - dev->callback = 0LL; - cdrom_set_callback(dev); - - dev->request_pos = 0; - } -} - - -static int -cdrom_read_from_ide_dma(uint8_t channel) -{ - cdrom_t *dev; - - uint8_t id = atapi_cdrom_drives[channel]; - int ret; - - if (id > CDROM_NUM) - return 0; - - dev = cdrom[id]; - - if (ide_bus_master_write) { - ret = ide_bus_master_write(channel >> 1, - cdbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - cdrom_bus_master_error(dev); - return 0; - } else - return 1; - } else - return 0; - - return 0; -} - - -static int -cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - cdrom_t *dev; - - uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > CDROM_NUM) - return 0; - - dev = cdrom[id]; - - cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); - return 1; -} - - -static void -cdrom_irq_raise(cdrom_t *dev) -{ - if (dev->drv->bus_type < CDROM_BUS_SCSI) - ide_irq_raise(ide_drives[dev->drv->ide_channel]); -} - - -static int -cdrom_read_from_dma(cdrom_t *dev) -{ - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - int ret = 0; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - ret = cdrom_read_from_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - else - ret = cdrom_read_from_ide_dma(dev->drv->ide_channel); - - if (ret != 1) - return ret; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", dev->id, *BufLen); - else - cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", dev->id, dev->packet_len); - - ret = cdrom_phase_data_out(dev); - - if (ret) - return 1; - else - return 0; -} - - -static int -cdrom_write_to_ide_dma(uint8_t channel) -{ - cdrom_t *dev; - - uint8_t id = atapi_cdrom_drives[channel]; - int ret; - - if (id > CDROM_NUM) - return 0; - - dev = cdrom[id]; - - if (ide_bus_master_read) { - ret = ide_bus_master_read(channel >> 1, - cdbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - cdrom_bus_master_error(dev); - return 0; - } else - return 1; - } else - return 0; -} - - -static int -cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - cdrom_t *dev; - - uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > CDROM_NUM) - return 0; - - dev = cdrom[id]; - - cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, *BufLen); - cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], - cdbufferb[6], cdbufferb[7]); - cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); - return 1; -} - - -static int -cdrom_write_to_dma(cdrom_t *dev) -{ - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - int ret = 0; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - cdrom_log("Write to SCSI DMA: (%02X:%02X)\n", dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - ret = cdrom_write_to_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - } else - ret = cdrom_write_to_ide_dma(dev->drv->ide_channel); - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - cdrom_log("CD-ROM %i: SCSI Output data length: %i\n", dev->id, *BufLen); - else - cdrom_log("CD-ROM %i: ATAPI Output data length: %i\n", dev->id, dev->packet_len); - - return ret; -} - - -void -cdrom_phase_callback(cdrom_t *dev) -{ - int ret; - - switch(dev->packet_status) { - case CDROM_PHASE_IDLE: - cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", dev->id); - dev->pos = 0; - dev->phase = 1; - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - return; - case CDROM_PHASE_COMMAND: - cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", dev->id); - dev->status = BUSY_STAT | (dev->status & ERR_STAT); - memcpy(dev->atapi_cdb, cdbufferb, dev->cdb_len); - cdrom_command(dev, dev->atapi_cdb); - return; - case CDROM_PHASE_COMPLETE: - cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", dev->id); - dev->status = READY_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - ui_sb_update_icon(SB_CDROM | dev->id, 0); - cdrom_irq_raise(dev); - return; - case CDROM_PHASE_DATA_OUT: - cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", dev->id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 0; - cdrom_irq_raise(dev); - return; - case CDROM_PHASE_DATA_OUT_DMA: - cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", dev->id); - ret = cdrom_read_from_dma(dev); - - if ((ret == 1) || (dev->drv->bus_type == CDROM_BUS_SCSI)) { - cdrom_log("CD-ROM %i: DMA data out phase done\n"); - cdrom_buf_free(dev); - cdrom_command_complete(dev); - } else if (ret == 2) { - cdrom_log("CD-ROM %i: DMA out not enabled, wait\n"); - cdrom_command_bus(dev); - } else { - cdrom_log("CD-ROM %i: DMA data out phase failure\n"); - cdrom_buf_free(dev); - } - return; - case CDROM_PHASE_DATA_IN: - cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", dev->id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 2; - cdrom_irq_raise(dev); - return; - case CDROM_PHASE_DATA_IN_DMA: - cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", dev->id); - ret = cdrom_write_to_dma(dev); - - if ((ret == 1) || (dev->drv->bus_type == CDROM_BUS_SCSI)) { - cdrom_log("CD-ROM %i: DMA data in phase done\n", dev->id); - cdrom_buf_free(dev); - cdrom_command_complete(dev); - } else if (ret == 2) { - cdrom_log("CD-ROM %i: DMA in not enabled, wait\n", dev->id); - cdrom_command_bus(dev); - } else { - cdrom_log("CD-ROM %i: DMA data in phase failure\n", dev->id); - cdrom_buf_free(dev); - } - return; - case CDROM_PHASE_ERROR: - cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", dev->id); - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - cdrom_irq_raise(dev); - ui_sb_update_icon(SB_CDROM | dev->id, 0); - return; - } -} - - -uint32_t -cdrom_read(uint8_t channel, int length) -{ - cdrom_t *dev; - - uint16_t *cdbufferw; - uint32_t *cdbufferl; - - uint8_t id = atapi_cdrom_drives[channel]; - - uint32_t temp = 0; - - if (id > CDROM_NUM) - return 0; - - dev = cdrom[id]; - - cdbufferw = (uint16_t *) cdbufferb; - cdbufferl = (uint32_t *) cdbufferb; - - if (!cdbufferb) - return 0; - - /* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it, - which can happen when issuing media access commands with an allocated length below minimum request length - (which is 1 sector = 2048 bytes). */ - switch(length) { - case 1: - temp = (dev->pos < dev->packet_len) ? cdbufferb[dev->pos] : 0; - dev->pos++; - dev->request_pos++; - break; - case 2: - temp = (dev->pos < dev->packet_len) ? cdbufferw[dev->pos >> 1] : 0; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - temp = (dev->pos < dev->packet_len) ? cdbufferl[dev->pos >> 2] : 0; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return 0; - } - - if (dev->packet_status == CDROM_PHASE_DATA_IN) { - cdrom_log("CD-ROM %i: Returning: %04X (buffer position: %05i, request position: %05i)\n", - id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - cdrom_log("CD-ROM %i: Issuing read callback\n", id); - cdrom_pio_request(dev, 0); - } - return temp; - } else { - cdrom_log("CD-ROM %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n", - id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - return 0; - } -} - - -void -cdrom_write(uint8_t channel, uint32_t val, int length) -{ - cdrom_t *dev; - - uint16_t *cdbufferw; - uint32_t *cdbufferl; - - uint8_t id = atapi_cdrom_drives[channel]; - - if (id > CDROM_NUM) - return; - - dev = cdrom[id]; - - if ((dev->packet_status == CDROM_PHASE_IDLE) && !cdbufferb) - cdrom_buf_alloc(dev, dev->cdb_len); - - cdbufferw = (uint16_t *) cdbufferb; - cdbufferl = (uint32_t *) cdbufferb; - - if (!cdbufferb) - return; - - switch(length) { - case 1: - cdbufferb[dev->pos] = val & 0xff; - dev->pos++; - dev->request_pos++; - break; - case 2: - cdbufferw[dev->pos >> 1] = val & 0xffff; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - cdbufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; - } - - if (dev->packet_status == CDROM_PHASE_DATA_OUT) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - cdrom_pio_request(dev, 1); - } - return; - } else if (dev->packet_status == CDROM_PHASE_IDLE) { - if (dev->pos >= dev->cdb_len) { - dev->pos = 0; - dev->status = BUSY_STAT; - dev->packet_status = CDROM_PHASE_COMMAND; - timer_process(); - cdrom_phase_callback(dev); - timer_update_outstanding(); - } - return; - } -} - - -/* Peform a master init on the entire module. */ -void -cdrom_global_init(void) -{ - /* Clear the global data. */ - memset(cdrom, 0x00, sizeof(cdrom)); - memset(cdrom_drives, 0x00, sizeof(cdrom_drives)); -} - - -void -cdrom_hard_reset(void) -{ - int c; - cdrom_t *dev; - - for (c = 0; c < CDROM_NUM; c++) { - if (cdrom_drives[c].bus_type) { - cdrom_log("CDROM hard_reset drive=%d\n", c); - - if (!cdrom[c]) { - cdrom[c] = (cdrom_t *) malloc(sizeof(cdrom_t)); - memset(cdrom[c], 0, sizeof(cdrom_t)); - } - - dev = cdrom[c]; - - /* Set the numerical ID because of ->handler and logging. */ - dev->id = c; - - cdrom_init(dev); - - if (dev->drv->host_drive == 200) { - image_open(c, cdrom_image[c].image_path); - image_reset(c); - } else - cdrom_null_open(c); - } - } - - build_atapi_cdrom_map(); - - sound_cd_thread_reset(); -} - - -void -cdrom_close_handler(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - switch (dev->drv->host_drive) { - case 200: - image_close(id); - break; - default: - null_close(id); - break; - } -} - - -void -cdrom_close(void) -{ - cdrom_t *dev; - int c; - - for (c = 0; c < CDROM_NUM; c++) { - dev = cdrom[c]; - - if (dev) { - if (dev->drv && dev->handler) - cdrom_close_handler(c); - - free(cdrom[c]); - cdrom[c] = NULL; - } - } -} diff --git a/src - Cópia/cdrom/cdrom.h b/src - Cópia/cdrom/cdrom.h deleted file mode 100644 index 337c62285..000000000 --- a/src - Cópia/cdrom/cdrom.h +++ /dev/null @@ -1,193 +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. - * - * Implementation of the CD-ROM drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * Version: @(#)cdrom.h 1.0.12 2018/04/30 - * - * Author: Miran Grca, - * - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_CDROM_H -#define EMU_CDROM_H - - -#define CDROM_NUM 4 - -#define CD_STATUS_EMPTY 0 -#define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PLAYING 2 -#define CD_STATUS_PAUSED 3 -#define CD_STATUS_STOPPED 4 - -#define CDROM_PHASE_IDLE 0x00 -#define CDROM_PHASE_COMMAND 0x01 -#define CDROM_PHASE_COMPLETE 0x02 -#define CDROM_PHASE_DATA_IN 0x03 -#define CDROM_PHASE_DATA_IN_DMA 0x04 -#define CDROM_PHASE_DATA_OUT 0x05 -#define CDROM_PHASE_DATA_OUT_DMA 0x06 -#define CDROM_PHASE_ERROR 0x80 - -#define BUF_SIZE 32768 - -#define CDROM_IMAGE 200 - -#define CDROM_TIME (5LL * 100LL * (1LL << TIMER_SHIFT)) - - -enum { - CDROM_BUS_DISABLED = 0, - CDROM_BUS_ATAPI = 4, - CDROM_BUS_SCSI, - CDROM_BUS_USB -}; - - -typedef struct { - int (*ready)(uint8_t id); - int (*medium_changed)(uint8_t id); - int (*media_type_id)(uint8_t id); - - int (*audio_callback)(uint8_t id, int16_t *output, int len); - void (*audio_stop)(uint8_t id); - int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); - int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(uint8_t id, uint8_t *b, int maxlen); - uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); - int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); - uint8_t (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf); - void (*pause)(uint8_t id); - void (*resume)(uint8_t id); - uint32_t (*size)(uint8_t id); - int (*status)(uint8_t id); - void (*stop)(uint8_t id); - void (*exit)(uint8_t id); -} CDROM; - -typedef struct { - int host_drive; - int prev_host_drive; - - unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ - - uint8_t speed, ide_channel, - bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - - unsigned int scsi_device_id, scsi_device_lun, - sound_on; -} cdrom_drive_t; - -typedef struct { - mode_sense_pages_t ms_pages_saved; - - CDROM *handler; - cdrom_drive_t *drv; - - uint8_t previous_command, - error, features, - status, phase, - id, *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; - - uint16_t request_length, max_transfer_len; - int16_t cd_buffer[BUF_SIZE]; - - int media_status, is_dma, - packet_status, requested_blocks, - current_page_len, current_page_pos, - mode_select_phase, do_page_save, - total_length, written_length, - callback, data_pos, - cd_status, prev_status, - unit_attention, request_pos, - total_read, cur_speed, - block_total, all_blocks_total, - old_len, block_descriptor_len, - init_length, last_subchannel_pos, - cd_buflen, cd_state, - handler_inited, disc_changed; - - uint32_t sector_pos, sector_len, - seek_pos, seek_diff, - pos, packet_len, - cdb_len, cd_end, - cdrom_capacity; - - uint64_t current_page_code; -} cdrom_t; - -typedef struct { - int image_is_iso; - wchar_t image_path[1024], - *prev_image_path; - FILE* image; -} cdrom_image_t; - - -extern cdrom_t *cdrom[CDROM_NUM]; -extern cdrom_drive_t cdrom_drives[CDROM_NUM]; -extern cdrom_image_t cdrom_image[CDROM_NUM]; -extern uint8_t atapi_cdrom_drives[8]; -extern uint8_t scsi_cdrom_drives[16][8]; - -#define cdrom_sense_error dev->sense[0] -#define cdrom_sense_key dev->sense[2] -#define cdrom_asc dev->sense[12] -#define cdrom_ascq dev->sense[13] -#define cdrom_drive cdrom_drives[id].host_drive - - -#ifdef __cplusplus -extern "C" { -#endif - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; - -extern uint32_t cdrom_mode_sense_get_channel(cdrom_t *dev, int channel); -extern uint32_t cdrom_mode_sense_get_volume(cdrom_t *dev, int channel); -extern void build_atapi_cdrom_map(void); -extern void build_scsi_cdrom_map(void); -extern int cdrom_CDROM_PHASE_to_scsi(cdrom_t *dev); -extern int cdrom_atapi_phase_to_scsi(cdrom_t *dev); -extern void cdrom_command(cdrom_t *dev, uint8_t *cdb); -extern void cdrom_phase_callback(cdrom_t *dev); -extern uint32_t cdrom_read(uint8_t channel, int length); -extern void cdrom_write(uint8_t channel, uint32_t val, int length); - -extern int cdrom_lba_to_msf_accurate(int lba); - -extern void cdrom_close_handler(uint8_t id); -extern void cdrom_close(void); -extern void cdrom_reset(cdrom_t *dev); -extern void cdrom_set_signature(cdrom_t *dev); -extern void cdrom_request_sense_for_scsi(cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length); -extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); -extern void cdrom_insert(cdrom_t *dev); - -extern int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern int cdrom_read_capacity(cdrom_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); - -extern void cdrom_global_init(void); -extern void cdrom_global_reset(void); -extern void cdrom_hard_reset(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_CDROM_H*/ diff --git a/src - Cópia/cdrom/cdrom_dosbox.cpp b/src - Cópia/cdrom/cdrom_dosbox.cpp deleted file mode 100644 index 0408be688..000000000 --- a/src - Cópia/cdrom/cdrom_dosbox.cpp +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * 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. - */ - -/* Modified for use with PCem by bit */ - -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#ifdef _WIN32 -//FIXME: should not be needed. */ -# define _GNU_SOURCE -#endif -#include -#include - -#include -#include -#include -#include -#include -#include -#include //GCC 2.95 -#include -#include -#include -#include "../plat.h" -#include "cdrom_dosbox.h" - -#ifndef _WIN32 -# include -#else -# include -#endif - -using namespace std; - -#define MAX_LINE_LENGTH 512 -#define MAX_FILENAME_LENGTH 256 -#define CROSS_LEN 512 - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) -{ - memset(fn, 0, sizeof(fn)); - strcpy(fn, filename); - file = fopen64(fn, "rb"); - if (file == NULL) - error = true; - else - error = false; -} - -CDROM_Interface_Image::BinaryFile::~BinaryFile() -{ - fclose(file); - file = NULL; - memset(fn, 0, sizeof(fn)); -} - -bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) -{ - fseeko64(file, seek, SEEK_SET); - fread(buffer, 1, count, file); - return 1; -} - -uint64_t CDROM_Interface_Image::BinaryFile::getLength() -{ - fseeko64(file, 0, SEEK_END); - return ftello64(file); -} - -CDROM_Interface_Image::CDROM_Interface_Image() -{ - // printf("CDROM_Interface_Image constructor\n"); -} - -CDROM_Interface_Image::~CDROM_Interface_Image() -{ - // printf("CDROM_Interface_Image destructor\n"); - ClearTracks(); -} - -void CDROM_Interface_Image::InitNewMedia() -{ -} - -bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) -{ - (void)forceCD; - if (LoadCueSheet(path)) return true; - if (LoadIsoFile(path)) return true; - - // print error message on dosbox console - //printf("Could not load image file: %s\n", path); - return false; -} - -bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) -{ - attr = 0; - strcpy(upc, this->mcn.c_str()); - return true; -} - -bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) -{ - stTrack = 1; - end = (int)(tracks.size() - 1); - FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); - return true; -} - -bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) -{ - if (track < 1 || track > (int)tracks.size()) return false; - FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); - track_number = tracks[track - 1].track_number; - attr = tracks[track - 1].attr; - return true; -} - -bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - int cur_track = GetTrack(sector); - if (cur_track < 1) return false; - track = (unsigned char)cur_track; - attr = tracks[track - 1].attr; - index = 1; - FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); - /* FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); */ - /* Note by Kotori: Yes, the absolute position should be adjusted by 150, but not the relative position. */ - FRAMES_TO_MSF(sector - tracks[track - 1].start, &relPos.min, &relPos.sec, &relPos.fr); - return true; -} - -bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - mediaPresent = true; - mediaChanged = false; - trayOpen = false; - return true; -} - -bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) -{ - int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - Bitu buflen = num * sectorSize; - Bit8u* buf = new Bit8u[buflen]; - - bool success = true; //Gobliiins reads 0 sectors - for(unsigned long i = 0; i < num; i++) { - success = ReadSector(&buf[i * sectorSize], raw, sector + i); - if (!success) break; - } - - memcpy((void*)buffer, buf, buflen); - delete[] buf; - - return success; -} - -bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) -{ - (void)unload; - return true; -} - -int CDROM_Interface_Image::GetTrack(unsigned int sector) -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end() - 1; - - while(i != end) { - Track &curr = *i; - Track &next = *(i + 1); - if (curr.start <= sector && sector < next.start) return curr.number; - i++; - } - return -1; -} - -bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) -{ - uint64_t length; - - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - uint64_t s = (uint64_t) sector; - uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize); - if (tracks[track].mode2) - length = (raw ? RAW_SECTOR_SIZE : 2336); - else - length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); - if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; - if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; - if (tracks[track].mode2 && !raw) seek += 24; - - return tracks[track].file->read(buffer, seek, length); -} - -bool CDROM_Interface_Image::ReadSectorSub(Bit8u *buffer, unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - uint64_t s = (uint64_t) sector; - uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize); - if (tracks[track].sectorSize != 2448) return false; - - return tracks[track].file->read(buffer, seek, 2448); -} - -int CDROM_Interface_Image::GetSectorSize(unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return 0; - - return tracks[track].sectorSize; -} - -bool CDROM_Interface_Image::IsMode2(unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - if (tracks[track].mode2) - { - return true; - } - else - { - return false; - } -} - -int CDROM_Interface_Image::GetMode2Form(unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - return tracks[track].form; -} - -bool CDROM_Interface_Image::LoadIsoFile(char* filename) -{ - tracks.clear(); - - // data track - Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL}; - bool error; - track.file = new BinaryFile(filename, error); - if (error) { - delete track.file; - return false; - } - track.number = 1; - track.track_number = 1;//IMPORTANT: This is needed. - track.attr = DATA_TRACK;//data - track.form = 0; - - // try to detect iso type - if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { - track.sectorSize = COOKED_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, 2324, true)) { - track.sectorSize = 2324; - track.form = 2; - track.mode2 = true; - } else if (CanReadPVD(track.file, 2336, true)) { - track.sectorSize = 2336; - track.mode2 = true; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = true; - } else { - /* Unknown mode: Assume regular 2048-byte sectors, this is needed so Apple Rhapsody ISO's can be mounted. */ - track.sectorSize = COOKED_SECTOR_SIZE; - track.mode2 = false; - } - - track.length = track.file->getLength() / track.sectorSize; - tracks.push_back(track); - - // leadout track - track.number = 2; - track.track_number = 0xAA; - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.start = track.length; - track.length = 0; - track.file = NULL; - tracks.push_back(track); - - return true; -} - -bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2) -{ - Bit8u pvd[COOKED_SECTOR_SIZE]; - uint64_t seek = 16 * sectorSize; // first vd is located at sector 16 - if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; - if (mode2) seek += 24; - file->read(pvd, seek, COOKED_SECTOR_SIZE); - // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) - return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || - (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); -} - -#ifdef _WIN32 -static string dirname(char * file) { - char * sep = strrchr(file, '\\'); - if (sep == NULL) - sep = strrchr(file, '/'); - if (sep == NULL) - return ""; - else { - int len = (int)(sep - file); - char tmp[MAX_FILENAME_LENGTH]; - safe_strncpy(tmp, file, len+1); - return tmp; - } -} -#endif - -bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) -{ - Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL}; - tracks.clear(); - uint64_t shift = 0; - uint64_t currPregap = 0; - uint64_t totalPregap = 0; - uint64_t prestart = 0; - bool success; - bool canAddTrack = false; - char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument - safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); - string pathname(dirname(tmp)); - ifstream in; - in.open(cuefile, ios::in); - if (in.fail()) return false; - - while(!in.eof()) { - // get next line - char buf[MAX_LINE_LENGTH]; - in.getline(buf, MAX_LINE_LENGTH); - if (in.fail() && !in.eof()) return false; // probably a binary file - istringstream line(buf); - - string command; - GetCueKeyword(command, line); - - if (command == "TRACK") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - - track.start = 0; - track.skip = 0; - currPregap = 0; - prestart = 0; - - line >> track.number; - track.track_number = track.number; - string type; - GetCueKeyword(type, line); - - track.form = 0; - - if (type == "AUDIO") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = AUDIO_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2048") { - track.sectorSize = COOKED_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE2/2048") { - track.form = 1; - track.sectorSize = 2048; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "MODE2/2324") { - track.form = 2; - track.sectorSize = 2324; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "MODE2/2336") { - track.sectorSize = 2336; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "MODE2/2352") { - track.form = 1; /* Assume this is XA Mode 2 Form 1. */ - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "CDG/2448") { - track.sectorSize = 2448; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "CDI/2336") { - track.sectorSize = 2336; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "CDI/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = true; - } else success = false; - - canAddTrack = true; - } - else if (command == "INDEX") { - uint64_t index; - line >> index; - uint64_t frame; - success = GetCueFrame(frame, line); - - if (index == 1) track.start = frame; - else if (index == 0) prestart = frame; - // ignore other indices - } - else if (command == "FILE") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - canAddTrack = false; - - string filename; - GetCueString(filename, line); - GetRealFileName(filename, pathname); - string type; - GetCueKeyword(type, line); - - track.file = NULL; - bool error = true; - if (type == "BINARY") { - track.file = new BinaryFile(filename.c_str(), error); - } - if (error) { - delete track.file; - success = false; - } - } - else if (command == "PREGAP") success = GetCueFrame(currPregap, line); - else if (command == "CATALOG") success = GetCueString(mcn, line); - // ignored commands - else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" - || command == "PERFORMER" || command == "POSTGAP" || command == "REM" - || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; - // failure - else success = false; - - if (!success) return false; - } - // add last track - if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; - - // add leadout track - track.number++; - track.track_number = 0xAA; - // track.attr = 0;//sync with load iso - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - // track.attr = last_attr | 0x02; - track.start = 0; - track.length = 0; - track.file = NULL; - if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; - - return true; -} - -bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap) -{ - // frames between index 0(prestart) and 1(curr.start) must be skipped - uint64_t skip; - if (prestart > 0) { - if (prestart > curr.start) return false; - skip = curr.start - prestart; - } else skip = 0; - - // first track (track number must be 1) - if (tracks.empty()) { - if (curr.number != 1) return false; - curr.skip = skip * curr.sectorSize; - curr.start += currPregap; - totalPregap = currPregap; - tracks.push_back(curr); - return true; - } - - Track &prev = *(tracks.end() - 1); - - // current track consumes data from the same file as the previous - if (prev.file == curr.file) { - curr.start += shift; - prev.length = curr.start + totalPregap - prev.start - skip; - curr.skip += prev.skip + (prev.length * prev.sectorSize) + (skip * curr.sectorSize); - totalPregap += currPregap; - curr.start += totalPregap; - // current track uses a different file as the previous track - } else { - uint64_t tmp = prev.file->getLength() - ((uint64_t) prev.skip); - prev.length = tmp / ((uint64_t) prev.sectorSize); - if (tmp % prev.sectorSize != 0) prev.length++; // padding - - curr.start += prev.start + prev.length + currPregap; - curr.skip = skip * curr.sectorSize; - shift += prev.start + prev.length; - totalPregap = currPregap; - } - - // error checks - if (curr.number <= 1) return false; - if (prev.number + 1 != curr.number) return false; - if (curr.start < prev.start + prev.length) return false; -#if 0 - /* curr.length is unsigned, so... --FvK */ - if (curr.length < 0) return false; -#endif - - tracks.push_back(curr); - return true; -} - -bool CDROM_Interface_Image::HasDataTrack(void) -{ - //Data track has attribute 0x14 - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == DATA_TRACK) return true; - } - return false; -} - -bool CDROM_Interface_Image::HasAudioTracks(void) -{ - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == AUDIO_TRACK) return true; - } - return false; -} - - -bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) -{ - // check if file exists - struct stat test; - if (stat(filename.c_str(), &test) == 0) return true; - - // check if file with path relative to cue file exists - string tmpstr(pathname + "/" + filename); - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } -#if defined (_WIN32) || defined(OS2) - //Nothing -#else - //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) - //which is common for some commercial rereleases of DOS games using DOSBox - - string copy = filename; - size_t l = copy.size(); - for (size_t i = 0; i < l;i++) { - if(copy[i] == '\\') copy[i] = '/'; - } - - if (stat(copy.c_str(), &test) == 0) { - filename = copy; - return true; - } - - tmpstr = pathname + "/" + copy; - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } - -#endif - return false; -} - -bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) -{ - in >> keyword; - for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); - - return true; -} - -bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in) -{ - string msf; - in >> msf; - int min, sec, fr; - bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; - frames = MSF_TO_FRAMES(min, sec, fr); - - return success; -} - -bool CDROM_Interface_Image::GetCueString(string &str, istream &in) -{ - int pos = (int)in.tellg(); - in >> str; - if (str[0] == '\"') { - if (str[str.size() - 1] == '\"') { - str.assign(str, 1, str.size() - 2); - } else { - in.seekg(pos, ios::beg); - char buffer[MAX_FILENAME_LENGTH]; - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); - str = buffer; - } - } - return true; -} - -void CDROM_Interface_Image::ClearTracks() -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end(); - - TrackFile* last = NULL; - while(i != end) { - Track &curr = *i; - if (curr.file != last) { - delete curr.file; - last = curr.file; - } - i++; - } - tracks.clear(); -} diff --git a/src - Cópia/cdrom/cdrom_dosbox.h b/src - Cópia/cdrom/cdrom_dosbox.h deleted file mode 100644 index f5dc4f346..000000000 --- a/src - Cópia/cdrom/cdrom_dosbox.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * 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. - */ - -/* Modified for use with PCem by bit */ - -#ifndef __CDROM_INTERFACE__ -#define __CDROM_INTERFACE__ - -#include -#include -#include -#include -#include -#include - -#include -typedef signed int Bits; -typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; -typedef uint16_t Bit16u; -typedef int32_t Bit32s; -typedef uint32_t Bit32u; - -typedef size_t PhysPt; - -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -#define DATA_TRACK 0x14 -#define AUDIO_TRACK 0x10 - -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M,S,F) { \ - int value = f; \ - *(F) = value%CD_FPS; \ - value /= CD_FPS; \ - *(S) = value%60; \ - value /= 60; \ - *(M) = value; \ -} -#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) - - -typedef struct SMSF { - unsigned char min; - unsigned char sec; - unsigned char fr; -} TMSF; - -typedef struct SCtrl { - Bit8u out[4]; // output channel - Bit8u vol[4]; // channel volume -} TCtrl; - -extern int CDROM_GetMountType(char* path, int force); - -class CDROM_Interface -{ -public: -// CDROM_Interface (void); - virtual ~CDROM_Interface (void) {}; - - virtual bool SetDevice (char* path, int forceCD) = 0; - - virtual bool GetUPC (unsigned char& attr, char* upc) = 0; - - virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; - virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; - virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; - virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; - - virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; - - virtual bool LoadUnloadMedia (bool unload) = 0; - - virtual void InitNewMedia (void) {}; -}; - -class CDROM_Interface_Image : public CDROM_Interface -{ -private: - class TrackFile { - public: - virtual bool read(Bit8u *buffer, uint64_t seek, uint64_t count) = 0; - virtual uint64_t getLength() = 0; - virtual ~TrackFile() { }; - }; - - class BinaryFile : public TrackFile { - public: - BinaryFile(const char *filename, bool &error); - ~BinaryFile(); - bool read(Bit8u *buffer, uint64_t seek, uint64_t count); - uint64_t getLength(); - private: - BinaryFile(); - char fn[260]; - FILE *file; - }; - - struct Track { - int number; - int track_number; - int attr; - int form; - uint64_t start; - uint64_t length; - uint64_t skip; - uint64_t sectorSize; - bool mode2; - TrackFile *file; - }; - -public: - CDROM_Interface_Image (); - virtual ~CDROM_Interface_Image (void); - void InitNewMedia (void); - bool SetDevice (char* path, int forceCD); - bool GetUPC (unsigned char& attr, char* upc); - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); - bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); - bool LoadUnloadMedia (bool unload); - bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); - bool ReadSectorSub (Bit8u *buffer, unsigned long sector); - int GetSectorSize (unsigned long sector); - bool IsMode2 (unsigned long sector); - int GetMode2Form (unsigned long sector); - bool HasDataTrack (void); - bool HasAudioTracks (void); - - int GetTrack (unsigned int sector); - -private: - // player -static void CDAudioCallBack(Bitu len); - - void ClearTracks(); - bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2); - // cue sheet processing - bool LoadCueSheet(char *cuefile); - bool GetRealFileName(std::string& filename, std::string& pathname); - bool GetCueKeyword(std::string &keyword, std::istream &in); - bool GetCueFrame(uint64_t &frames, std::istream &in); - bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap); - - std::vector tracks; -typedef std::vector::iterator track_it; - std::string mcn; -}; - -void cdrom_image_log(const char *format, ...); - -#endif /* __CDROM_INTERFACE__ */ diff --git a/src - Cópia/cdrom/cdrom_image.cc b/src - Cópia/cdrom/cdrom_image.cc deleted file mode 100644 index c1a301ba6..000000000 --- a/src - Cópia/cdrom/cdrom_image.cc +++ /dev/null @@ -1,1107 +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. - * - * CD-ROM image support. - * - * Version: @(#)cdrom_image.cc 1.0.0 2018/03/29 - * - * Author: RichardG867, - * Miran Grca, - * bit, - * - * Copyright 2015-2018 Richardg867. - * Copyright 2015-2018 Miran Grca. - * Copyright 2017,2018 bit. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#include -#include "../config.h" -#include "../plat.h" -#include "../scsi/scsi.h" -#include "cdrom_dosbox.h" -#include "cdrom.h" -#include "cdrom_image.h" -#include "cdrom_null.h" - -#define CD_STATUS_EMPTY 0 -#define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PLAYING 2 -#define CD_STATUS_PAUSED 3 -#define CD_STATUS_STOPPED 4 - -/* 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: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -extern CDROM image_cdrom; - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048], - ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8], - user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2336]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; -} sector_raw_data_t; - -typedef union __attribute__((__packed__)) -{ - sector_raw_data_t sector_data; - uint8_t raw_data[2352]; -} sector_t; - -typedef struct __attribute__((__packed__)) -{ - sector_t sector; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; -uint8_t raw_buffer[2448]; -uint8_t extra_buffer[296]; - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - - -#ifdef ENABLE_CDROM_IMAGE_LOG -int cdrom_image_do_log = ENABLE_CDROM_IMAGE_LOG; -#endif - - -static CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; -static char afn[1024]; - -void image_close(uint8_t id); - - -void -cdrom_image_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_IMAGE_LOG - if (cdrom_image_do_log) { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - - -int -image_audio_callback(uint8_t id, int16_t *output, int len) -{ - cdrom_t *dev = cdrom[id]; - int ret = 1; - - if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { - cdrom_image_log("image_audio_callback(i): Not playing\n", id); - if (dev->cd_state == CD_PLAYING) - dev->seek_pos += (len >> 11); - memset(output, 0, len * 2); - return 0; - } - while (dev->cd_buflen < len) { - if (dev->seek_pos < dev->cd_end) { - if (!cdimg[id]->ReadSector((unsigned char*)&dev->cd_buffer[dev->cd_buflen], true, - dev->seek_pos)) { - memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_state = CD_STOPPED; - dev->cd_buflen = len; - ret = 0; - } else { - dev->seek_pos++; - dev->cd_buflen += (RAW_SECTOR_SIZE / 2); - ret = 1; - } - } else { - memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_state = CD_STOPPED; - dev->cd_buflen = len; - ret = 0; - } - } - - memcpy(output, dev->cd_buffer, len * 2); - memmove(dev->cd_buffer, &dev->cd_buffer[len], (BUF_SIZE - len) * 2); - dev->cd_buflen -= len; - return ret; -} - - -void -image_audio_stop(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - dev->cd_state = CD_STOPPED; -} - - -static uint8_t -image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - cdrom_t *dev = cdrom[id]; - if (!cdimg[id]) - return 0; - int number; - unsigned char attr; - TMSF tmsf; - int m = 0, s = 0, f = 0; - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - if (attr == DATA_TRACK) { - cdrom_image_log("Can't play data track\n"); - dev->seek_pos = 0; - dev->cd_state = CD_STOPPED; - return 0; - } - cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf == 2) { - cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); - pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); - len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - } else if (ismsf == 1) { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - - if (pos == 0xffffff) { - cdrom_image_log("Playing from current position (MSF)\n"); - pos = dev->seek_pos; - } else - pos = MSFtoLBA(m, s, f) - 150; - - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f) - 150; - - cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); - } else if (ismsf == 0) { - if (pos == 0xffffffff) { - cdrom_image_log("Playing from current position\n"); - pos = dev->seek_pos; - } - len += pos; - } - - dev->seek_pos = pos; - dev->cd_end = len; - dev->cd_state = CD_PLAYING; - dev->cd_buflen = 0; - - return 1; -} - - -static void -image_pause(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (dev->cd_state == CD_PLAYING) - dev->cd_state = CD_PAUSED; -} - - -static void -image_resume(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) - return; - if (dev->cd_state == CD_PAUSED) - dev->cd_state = CD_PLAYING; -} - - -static void -image_stop(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) - return; - dev->cd_state = CD_STOPPED; -} - - -static int -image_ready(uint8_t id) -{ - if (!cdimg[id] || (wcslen(cdrom_image[id].image_path) == 0)) - return 0; - - return 1; -} - - -static int -image_get_last_block(uint8_t id) -{ - int first_track, last_track; - int number, c; - unsigned char attr; - TMSF tmsf; - uint32_t lb=0; - - if (!cdimg[id]) - return 0; - - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - for (c = 0; c <= last_track; c++) { - uint32_t address; - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ - if (address > lb) - lb = address; - } - return lb; -} - - -static int -image_medium_changed(uint8_t id) -{ - /* There is no way to change the medium within an already mounted image. */ - return 0; -} - - -static uint8_t -image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - cdrom_t *dev = cdrom[id]; - uint8_t ret; - int pos = 0; - uint32_t cdpos; - TMSF relPos, absPos; - unsigned char attr, track, index; - - cdpos = dev->seek_pos; - - if (!cdimg[id]) - return 0; - - cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); - - if (cdrom_image[id].image_is_iso) - ret = 0x15; - else { - if (dev->cd_state == CD_PLAYING) - ret = 0x11; - else if (dev->cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; - } - - b[pos++] = attr; - b[pos++] = track; - b[pos++] = index; - - if (msf) { - b[pos + 3] = (uint8_t) absPos.fr; - b[pos + 2] = (uint8_t) absPos.sec; - b[pos + 1] = (uint8_t) absPos.min; - b[pos] = 0; - pos += 4; - b[pos + 3] = (uint8_t) relPos.fr; - b[pos + 2] = (uint8_t) relPos.sec; - b[pos + 1] = (uint8_t) relPos.min; - b[pos] = 0; - pos += 4; - } else { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr) - 150; - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - } - - return ret; -} - - -static int -image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - int m, s, f; - unsigned char attr; - TMSF tmsf; - int number; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) - return 0; - - if (ismsf) { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f) - 150; - } - - /* GetTrack requires LBA. */ - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - - return attr == AUDIO_TRACK; -} - - -static int -is_legal(int id, int cdrom_sector_type, int cdrom_sector_flags, int audio, int mode2) -{ - if (!(cdrom_sector_flags & 0x70)) { /* 0x00/0x08/0x80/0x88 are illegal modes */ - cdrom_image_log("CD-ROM %i: [Any Mode] 0x00/0x08/0x80/0x88 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_type != 1) && !audio) { - if (!(cdrom_sector_flags & 0x70)) { /* 0x00/0x08/0x80/0x88 are illegal modes */ - cdrom_image_log("CD-ROM %i: [Any Data Mode] 0x00/0x08/0x80/0x88 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) { - cdrom_image_log("CD-ROM %i: [Any Data Mode] Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) { - cdrom_image_log("CD-ROM %i: [Any Data Mode] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) { /* EDC/ECC without user data is an illegal mode */ - cdrom_image_log("CD-ROM %i: [Any Data Mode] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0xf0) == 0x90) || ((cdrom_sector_flags & 0xf0) == 0xc0)) { /* 0x90/0x98/0xC0/0xC8 are illegal modes */ - cdrom_image_log("CD-ROM %i: [Any Data Mode] 0x90/0x98/0xC0/0xC8 are illegal modes\n", id); - return 0; - } - - if (((cdrom_sector_type > 3) && (cdrom_sector_type != 8)) || (mode2 && (mode2 & 0x03))) { - if ((cdrom_sector_flags & 0xf0) == 0x30) { /* 0x30/0x38 are illegal modes */ - cdrom_image_log("CD-ROM %i: [Any XA Mode 2] 0x30/0x38 are illegal modes\n", id); - return 0; - } - if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) { /* 0xBx and 0xDx are illegal modes */ - cdrom_image_log("CD-ROM %i: [Any XA Mode 2] 0xBx and 0xDx are illegal modes\n", id); - return 0; - } - } - } - - return 1; -} - - -static void -read_sector_to_buffer(uint8_t id, uint8_t *raw_buffer, uint32_t msf, uint32_t lba, int mode2, int len) -{ - uint8_t *bb = raw_buffer; - - cdimg[id]->ReadSector(raw_buffer + 16, false, lba); - - /* Sync bytes */ - bb[0] = 0; - memset(bb + 1, 0xff, 10); - bb[11] = 0; - bb += 12; - - /* Sector header */ - bb[0] = (msf >> 16) & 0xff; - bb[1] = (msf >> 8) & 0xff; - bb[2] = msf & 0xff; - - bb[3] = 1; /* mode 1 data */ - bb += mode2 ? 12 : 4; - bb += len; - if (mode2 && ((mode2 & 0x03) == 1)) - memset(bb, 0, 280); - else if (!mode2) - memset(bb, 0, 288); -} - - -static void -read_audio(int id, uint32_t lba, uint8_t *b) -{ - if (cdimg[id]->GetSectorSize(lba) == 2352) - cdimg[id]->ReadSector(raw_buffer, true, lba); - else - cdimg[id]->ReadSectorSub(raw_buffer, lba); - - memcpy(b, raw_buffer, 2352); - cdrom_sector_size = 2352; -} - - -static void -read_mode1(int id, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((cdrom_image[id].image_is_iso) || (cdimg[id]->GetSectorSize(lba) == 2048)) - read_sector_to_buffer(id, raw_buffer, msf, lba, mode2, 2048); - else if (cdimg[id]->GetSectorSize(lba) == 2352) - cdimg[id]->ReadSector(raw_buffer, true, lba); - else - cdimg[id]->ReadSectorSub(raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { /* Sync */ - cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { /* Header */ - cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - if (cdrom_sector_flags & 0x40) { /* Sub-header */ - if (!(cdrom_sector_flags & 0x10)) { /* No user data */ - cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - } - - if (cdrom_sector_flags & 0x10) { /* User data */ - cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); - memcpy(b, raw_buffer + 16, 2048); - cdrom_sector_size += 2048; - b += 2048; - } - - if (cdrom_sector_flags & 0x08) { /* EDC/ECC */ - cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); - memcpy(b, raw_buffer + 2064, 288); - cdrom_sector_size += 288; - b += 288; - } -} - - -static void -read_mode2_non_xa(int id, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((cdrom_image[id].image_is_iso) || (cdimg[id]->GetSectorSize(lba) == 2336)) - read_sector_to_buffer(id, raw_buffer, msf, lba, mode2, 2336); - else if (cdimg[id]->GetSectorSize(lba) == 2352) - cdimg[id]->ReadSector(raw_buffer, true, lba); - else - cdimg[id]->ReadSectorSub(raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { /* Sync */ - cdrom_image_log("CD-ROM %i: [Mode 2 Formless] Sync\n", id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { /* Header */ - cdrom_image_log("CD-ROM %i: [Mode 2 Formless] Header\n", id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) { /* Sub-header */ - cdrom_image_log("CD-ROM %i: [Mode 2 Formless] Sub-header\n", id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - - if (cdrom_sector_flags & 0x10) { /* User data */ - cdrom_image_log("CD-ROM %i: [Mode 2 Formless] User data\n", id); - memcpy(b, raw_buffer + 24, 2336); - cdrom_sector_size += 2336; - b += 2336; - } -} - - -static void -read_mode2_xa_form1(int id, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((cdrom_image[id].image_is_iso) || (cdimg[id]->GetSectorSize(lba) == 2048)) - read_sector_to_buffer(id, raw_buffer, msf, lba, mode2, 2048); - else if (cdimg[id]->GetSectorSize(lba) == 2352) - cdimg[id]->ReadSector(raw_buffer, true, lba); - else - cdimg[id]->ReadSectorSub(raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { /* Sync */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { /* Header */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - if (cdrom_sector_flags & 0x40) { /* Sub-header */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - - if (cdrom_sector_flags & 0x10) { /* User data */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); - memcpy(b, raw_buffer + 24, 2048); - cdrom_sector_size += 2048; - b += 2048; - } - - if (cdrom_sector_flags & 0x08) { /* EDC/ECC */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); - memcpy(b, raw_buffer + 2072, 280); - cdrom_sector_size += 280; - b += 280; - } -} - - -static void -read_mode2_xa_form2(int id, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((cdrom_image[id].image_is_iso) || (cdimg[id]->GetSectorSize(lba) == 2324)) - read_sector_to_buffer(id, raw_buffer, msf, lba, mode2, 2324); - else if (cdimg[id]->GetSectorSize(lba) == 2352) - cdimg[id]->ReadSector(raw_buffer, true, lba); - else - cdimg[id]->ReadSectorSub(raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { /* Sync */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 2] Sync\n", id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { /* Header */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 2] Header\n", id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - if (cdrom_sector_flags & 0x40) { /* Sub-header */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 2] Sub-header\n", id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - - if (cdrom_sector_flags & 0x10) { /* User data */ - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 2] User data\n", id); - memcpy(b, raw_buffer + 24, 2328); - cdrom_sector_size += 2328; - b += 2328; - } -} - - -static int -image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, - int cdrom_sector_flags, int *len) -{ - uint8_t *b, *temp_b; - uint32_t msf, lba; - int audio, mode2; - int m, s, f; - - if (!cdimg[id]) - return 0; - - if (!cdrom_drives[id].host_drive) - return 0; - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) { - m = (sector >> 16) & 0xff; - s = (sector >> 8) & 0xff; - f = sector & 0xff; - lba = MSFtoLBA(m, s, f) - 150; - msf = sector; - } else { - lba = sector; - msf = cdrom_lba_to_msf_accurate(sector); - } - - if (cdrom_image[id].image_is_iso) { - audio = 0; - mode2 = cdimg[id]->IsMode2(lba) ? 1 : 0; - } else { - audio = image_is_track_audio(id, sector, ismsf); - mode2 = cdimg[id]->IsMode2(lba) ? 1 : 0; - } - mode2 <<= 2; - mode2 |= cdimg[id]->GetMode2Form(lba); - - memset(raw_buffer, 0, 2448); - memset(extra_buffer, 0, 296); - - if (!(cdrom_sector_flags & 0xf0)) { /* 0x00 and 0x08 are illegal modes */ - cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if (!is_legal(id, cdrom_sector_type, cdrom_sector_flags, audio, mode2)) - return 0; - - if ((cdrom_sector_type == 3) || ((cdrom_sector_type > 4) && (cdrom_sector_type != 8))) { - if (cdrom_sector_type == 3) - cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); - if (cdrom_sector_type > 4) - cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); - return 0; - } else if (cdrom_sector_type == 1) { - if (!audio || cdrom_image[id].image_is_iso) { - cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); - return 0; - } - - read_audio(id, lba, temp_b); - } else if (cdrom_sector_type == 2) { - if (audio || mode2) { - cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a sector of another type\n", id); - return 0; - } - - read_mode1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 3) { - if (audio || !mode2 || (mode2 & 0x03)) { - cdrom_image_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", id); - return 0; - } - - read_mode2_non_xa(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 4) { - if (audio || !mode2 || ((mode2 & 0x03) != 1)) { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", id); - return 0; - } - - read_mode2_xa_form1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 5) { - if (audio || !mode2 || ((mode2 & 0x03) != 2)) { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 2] Attempting to read a sector of another type\n", id); - return 0; - } - - read_mode2_xa_form2(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 8) { - if (audio) { - cdrom_image_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", id); - return 0; - } - - if (mode2 && ((mode2 & 0x03) == 1)) - read_mode2_xa_form1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - else if (!mode2) - read_mode1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - else { - cdrom_image_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", id); - return 0; - } - } else { - if (mode2) { - if ((mode2 & 0x03) == 0x01) - read_mode2_xa_form1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - else if ((mode2 & 0x03) == 0x02) - read_mode2_xa_form2(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - else - read_mode2_non_xa(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else { - if (audio) - read_audio(id, lba, temp_b); - else - read_mode1(id, cdrom_sector_flags, lba, msf, mode2, temp_b); - } - } - - if ((cdrom_sector_flags & 0x06) == 0x02) { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 294); - cdrom_sector_size += 294; - } else if ((cdrom_sector_flags & 0x06) == 0x04) { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) { - cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 96); - cdrom_sector_size += 96; - } else if ((cdrom_sector_flags & 0x700) == 0x200) { - cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 16); - cdrom_sector_size += 16; - } else if ((cdrom_sector_flags & 0x700) == 0x400) { - cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - - -static uint32_t -image_size(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - return dev->cdrom_capacity; -} - - -static int -image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - int number, len = 4; - int c, d, first_track, last_track; - uint32_t temp; - unsigned char attr; - TMSF tmsf; - - if (!cdimg[id]) - return 0; - - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - d = 0; - for (c = 0; c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - if (number >= starttrack) { - d=c; - break; - } - } - - if (starttrack != 0xAA) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - b[2] = number; - } - - for (c = d; c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } else { - temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - if (single) - break; - } - - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - - return len; -} - - -static int -image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - int number, len = 4; - TMSF tmsf; - unsigned char attr; - uint32_t temp; - - if (!cdimg[id]) - return 0; - - cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); - - if (number == 0) - number = 1; - - b[2] = b[3] = 1; - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - if (msf) { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } else { - temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - if (maxlen < len) - return maxlen; - - return len; -} - - -static int -image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) -{ - int track, len = 4; - int first_track, last_track; - int number; - unsigned char attr; - TMSF tmsf; - - if (!cdimg[id]) - return 0; - - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - for (track = first_track; track <= last_track; track++) { - cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); - - b[len++] = track; - b[len++]= attr; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - - return len; -} - - -static int -image_status(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - if (!cdimg[id]) - return CD_STATUS_EMPTY; - - if (cdrom_image[id].image_is_iso) - return CD_STATUS_DATA_ONLY; - - if (cdimg[id]->HasAudioTracks()) { - switch(dev->cd_state) { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - default: - return CD_STATUS_STOPPED; - } - } - - return CD_STATUS_DATA_ONLY; -} - - -void -image_reset(UNUSED(uint8_t id)) -{ - return; -} - - -void -image_close(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - dev->cd_state = CD_STOPPED; - if (cdimg[id]) { - delete cdimg[id]; - cdimg[id] = NULL; - } -} - - -int -image_open(uint8_t id, wchar_t *fn) -{ - cdrom_t *dev = cdrom[id]; - - wcscpy(cdrom_image[id].image_path, fn); - - if (! wcscasecmp(plat_get_extension(fn), L"ISO")) - cdrom_image[id].image_is_iso = 1; - else - cdrom_image[id].image_is_iso = 0; - - cdimg[id] = new CDROM_Interface_Image(); - memset(afn, 0, sizeof(afn)); - wcstombs(afn, fn, sizeof(afn)); - if (!cdimg[id]->SetDevice(afn, false)) { - image_close(id); - cdrom_set_null_handler(id); - cdrom_image_log("[f] image_open(): cdrom[%i]->handler = %08X\n", id, cdrom[id]->handler); - return 1; - } - dev->cd_state = CD_STOPPED; - dev->seek_pos = 0; - dev->cd_buflen = 0; - dev->cdrom_capacity = image_get_last_block(id) + 1; - cdrom[id]->handler = &image_cdrom; - - return 0; -} - - -static void -image_exit(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - dev->handler_inited = 0; -} - - -/* TODO: Check for what data type a mixed CD is. */ -static int image_media_type_id(uint8_t id) -{ - if (image_size(id) > 405000) - return 65; /* DVD. */ - else { - if (cdrom_image[id].image_is_iso) - return 1; /* Data CD. */ - else - return 3; /* Mixed mode CD. */ - } -} - - -CDROM image_cdrom = -{ - image_ready, - image_medium_changed, - image_media_type_id, - image_audio_callback, - image_audio_stop, - image_readtoc, - image_readtoc_session, - image_readtoc_raw, - image_getcurrentsubchannel, - image_readsector_raw, - image_playaudio, - image_pause, - image_resume, - image_size, - image_status, - image_stop, - image_exit -}; diff --git a/src - Cópia/cdrom/cdrom_image.h b/src - Cópia/cdrom/cdrom_image.h deleted file mode 100644 index 415956e56..000000000 --- a/src - Cópia/cdrom/cdrom_image.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IMAGE_H -#define CDROM_IMAGE_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int image_open(uint8_t id, wchar_t *fn); -extern void image_reset(uint8_t id); - -extern void image_close(uint8_t id); - -void update_status_bar_icon_state(int tag, int state); -extern void cdrom_set_null_handler(uint8_t id); - -#ifdef __cplusplus -} -#endif - -#endif /* ! CDROM_IMAGE_H */ diff --git a/src - Cópia/cdrom/cdrom_null.c b/src - Cópia/cdrom/cdrom_null.c deleted file mode 100644 index 15b2c937f..000000000 --- a/src - Cópia/cdrom/cdrom_null.c +++ /dev/null @@ -1,161 +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. - * - * Implementation of the CD-ROM null interface for unmounted - * guest CD-ROM drives. - * - * Version: @(#)cdrom_null.c 1.0.7 2018/03/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2016 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../scsi/scsi.h" -#include "cdrom.h" - - -static CDROM null_cdrom; - - -static int -null_ready(uint8_t id) -{ - return(0); -} - - -/* Always return 0, the contents of a null CD-ROM drive never change. */ -static int -null_medium_changed(uint8_t id) -{ - return(0); -} - - -static uint8_t -null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - return(0x13); -} - - -static int -null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - *len = 0; - - return(0); -} - - -static int -null_readtoc(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single) -{ - return(0); -} - - -static int -null_readtoc_session(uint8_t id, uint8_t *b, int msf, int maxlen) -{ - return(0); -} - - -static int -null_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) -{ - return(0); -} - - -static uint32_t -null_size(uint8_t id) -{ - return(0); -} - - -static int -null_status(uint8_t id) -{ - return(CD_STATUS_EMPTY); -} - - -void -cdrom_null_reset(uint8_t id) -{ -} - - -void cdrom_set_null_handler(uint8_t id); - -int -cdrom_null_open(uint8_t id) -{ - cdrom_set_null_handler(id); - - return(0); -} - - -void -null_close(uint8_t id) -{ -} - - -static -void null_exit(uint8_t id) -{ -} - - -static int -null_media_type_id(uint8_t id) -{ - return(0x70); -} - - -void -cdrom_set_null_handler(uint8_t id) -{ - cdrom[id]->handler = &null_cdrom; - cdrom_drives[id].host_drive = 0; - memset(cdrom_image[id].image_path, 0, sizeof(cdrom_image[id].image_path)); -} - - -static CDROM null_cdrom = { - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, - null_readtoc, - null_readtoc_session, - null_readtoc_raw, - null_getcurrentsubchannel, - null_readsector_raw, - NULL, - NULL, - NULL, - null_size, - null_status, - NULL, - null_exit -}; diff --git a/src - Cópia/cdrom/cdrom_null.h b/src - Cópia/cdrom/cdrom_null.h deleted file mode 100644 index 480acb29c..000000000 --- a/src - Cópia/cdrom/cdrom_null.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the CD-ROM null interface for unmounted - * guest CD-ROM drives. - * - * Version: @(#)cdrom_null.h 1.0.4 2018/03/31 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef EMU_CDROM_NULL_H -#define EMU_CDROM_NULL_H - - -extern int cdrom_null_open(uint8_t id); -extern void cdrom_null_reset(uint8_t id); -extern void null_close(uint8_t id); - - -#endif /*EMU_CDROM_NULL_H*/ diff --git a/src - Cópia/config.c b/src - Cópia/config.c deleted file mode 100644 index f1207c90d..000000000 --- a/src - Cópia/config.c +++ /dev/null @@ -1,2174 +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. - * - * Configuration file handler. - * - * Version: @(#)config.c 1.0.48 2018/05/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - * - * NOTE: Forcing config files to be in Unicode encoding breaks - * it on Windows XP, and possibly also Vista. Use the - * -DANSI_CFG for use on these systems. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu/cpu.h" -#include "device.h" -#include "nvr.h" -#include "config.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 "mouse.h" -#include "network/network.h" -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "disk/zip.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_dbopl.h" -#include "sound/snd_mpu401.h" -#include "sound/snd_opl.h" -#include "sound/sound.h" -#include "video/video.h" -#include "plat.h" -#include "plat_midi.h" -#include "ui.h" - - -typedef struct _list_ { - struct _list_ *next; -} list_t; - -typedef struct { - list_t list; - - char name[128]; - - list_t entry_head; -} section_t; - -typedef struct { - list_t list; - - char name[128]; - char data[256]; - wchar_t wdata[512]; -} entry_t; - -#define list_add(new, head) { \ - list_t *next = head; \ - \ - while (next->next != NULL) \ - next = next->next; \ - \ - (next)->next = new; \ - (new)->next = NULL; \ -} - -#define list_delete(old, head) { \ - list_t *next = head; \ - \ - while ((next)->next != old) { \ - next = (next)->next; \ - } \ - \ - (next)->next = (old)->next; \ -} - - -static list_t config_head; - - -#ifdef ENABLE_CONFIG_LOG -int config_do_log = ENABLE_CONFIG_LOG; -#endif - - -static void -config_log(const char *format, ...) -{ -#ifdef ENABLE_CONFIG_LOG - va_list ap; - - if (config_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static section_t * -find_section(char *name) -{ - section_t *sec; - char blank[] = ""; - - sec = (section_t *)config_head.next; - if (name == NULL) - name = blank; - - while (sec != NULL) { - if (! strncmp(sec->name, name, sizeof(sec->name))) - return(sec); - - sec = (section_t *)sec->list.next; - } - - return(NULL); -} - - -static entry_t * -find_entry(section_t *section, char *name) -{ - entry_t *ent; - - ent = (entry_t *)section->entry_head.next; - - while (ent != NULL) { - if (! strncmp(ent->name, name, sizeof(ent->name))) - return(ent); - - ent = (entry_t *)ent->list.next; - } - - return(NULL); -} - - -static int -entries_num(section_t *section) -{ - entry_t *ent; - int i = 0; - - ent = (entry_t *)section->entry_head.next; - - while (ent != NULL) { - if (strlen(ent->name) > 0) i++; - - ent = (entry_t *)ent->list.next; - } - - return(i); -} - - -static void -delete_section_if_empty(char *head) -{ - section_t *section; - - section = find_section(head); - if (section == NULL) return; - - if (entries_num(section) == 0) { - list_delete(§ion->list, &config_head); - free(section); - } -} - - -static section_t * -create_section(char *name) -{ - section_t *ns = malloc(sizeof(section_t)); - - memset(ns, 0x00, sizeof(section_t)); - strncpy(ns->name, name, sizeof(ns->name)); - list_add(&ns->list, &config_head); - - return(ns); -} - - -static entry_t * -create_entry(section_t *section, char *name) -{ - entry_t *ne = malloc(sizeof(entry_t)); - - memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, name, sizeof(ne->name)); - list_add(&ne->list, §ion->entry_head); - - return(ne); -} - - -#if 0 -static void -config_free(void) -{ - section_t *sec, *ns; - entry_t *ent; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - ns = (section_t *)sec->list.next; - ent = (entry_t *)sec->entry_head.next; - - while (ent != NULL) { - entry_t *nent = (entry_t *)ent->list.next; - - free(ent); - ent = nent; - } - - free(sec); - sec = ns; - } -} -#endif - - -/* Read and parse the configuration file into memory. */ -static int -config_read(wchar_t *fn) -{ - char sname[128], ename[128]; - wchar_t buff[1024]; - section_t *sec, *ns; - entry_t *ne; - int c, d; - FILE *f; - -#if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, L"rt"); -#else - f = plat_fopen(fn, L"rt, ccs=UNICODE"); -#endif - if (f == NULL) return(0); - - sec = malloc(sizeof(section_t)); - memset(sec, 0x00, sizeof(section_t)); - memset(&config_head, 0x00, sizeof(list_t)); - list_add(&sec->list, &config_head); - - while (1) { - memset(buff, 0x00, sizeof(buff)); - fgetws(buff, sizeof_w(buff), f); - if (feof(f)) break; - - /* Make sure there are no stray newlines or hard-returns in there. */ - if (buff[wcslen(buff)-1] == L'\n') buff[wcslen(buff)-1] = L'\0'; - if (buff[wcslen(buff)-1] == L'\r') buff[wcslen(buff)-1] = L'\0'; - - /* Skip any leading whitespace. */ - c = 0; - while ((buff[c] == L' ') || (buff[c] == L'\t')) - c++; - - /* Skip empty lines. */ - if (buff[c] == L'\0') continue; - - /* Skip lines that (only) have a comment. */ - if ((buff[c] == L'#') || (buff[c] == L';')) continue; - - if (buff[c] == L'[') { /*Section*/ - c++; - d = 0; - while (buff[c] != L']' && buff[c]) - wctomb(&(sname[d++]), buff[c++]); - sname[d] = L'\0'; - - /* Is the section name properly terminated? */ - if (buff[c] != L']') continue; - - /* 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)); - list_add(&ns->list, &config_head); - - /* New section is now the current one. */ - sec = ns; - continue; - } - - /* Get the variable name. */ - d = 0; - while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c]) - wctomb(&(ename[d++]), buff[c++]); - ename[d] = L'\0'; - - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; - - /* Look for =, skip whitespace. */ - while ((buff[c] == L'=' || buff[c] == L' ') && buff[c]) - c++; - - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; - - /* This is where the value part starts. */ - d = c; - - /* Allocate a new variable entry.. */ - ne = malloc(sizeof(entry_t)); - memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, ename, sizeof(ne->name)); - 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)); - ne->data[sizeof(ne->data)-1] = '\0'; - - /* .. and insert it. */ - list_add(&ne->list, &sec->entry_head); - } - - (void)fclose(f); - - if (do_dump_config) - config_dump(); - - return(1); -} - - -/* - * Write the in-memory configuration to disk. - * This is a public function, because the Settings UI - * want to directly write the configuration after it - * has changed it. - */ -void -config_write(wchar_t *fn) -{ - wchar_t wtemp[512]; - section_t *sec; - FILE *f; - int fl = 0; - -#if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, L"wt"); -#else - f = plat_fopen(fn, L"wt, ccs=UNICODE"); -#endif - if (f == NULL) return; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - entry_t *ent; - - if (sec->name[0]) { - mbstowcs(wtemp, sec->name, strlen(sec->name)+1); - if (fl) - fwprintf(f, L"\n[%ls]\n", wtemp); - else - fwprintf(f, L"[%ls]\n", wtemp); - fl++; - } - - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - if (ent->name[0] != '\0') { - mbstowcs(wtemp, ent->name, sizeof_w(wtemp)); - if (ent->wdata[0] == L'\0') - fwprintf(f, L"%ls = \n", wtemp); - else - fwprintf(f, L"%ls = %ls\n", wtemp, ent->wdata); - fl++; - } - - ent = (entry_t *)ent->list.next; - } - - sec = (section_t *)sec->list.next; - } - - (void)fclose(f); -} - - -#if NOT_USED -static void -config_new(void) -{ -#if defined(ANSI_CFG) || !defined(_WIN32) - FILE *f = _wfopen(config_file, L"wt"); -#else - FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); -#endif - - if (file != NULL) - (void)fclose(f); -} -#endif - - -/* Load "General" section. */ -static void -load_general(void) -{ - char *cat = "General"; - char temp[512]; - char *p; - - vid_resize = !!config_get_int(cat, "vid_resize", 0); - - memset(temp, '\0', sizeof(temp)); - p = config_get_string(cat, "vid_renderer", "default"); - vid_api = plat_vidapi(p); - config_delete_var(cat, "vid_api"); - - video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); - - video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); - - force_43 = !!config_get_int(cat, "force_43", 0); - scale = config_get_int(cat, "scale", 1); - if (scale > 3) - scale = 3; - - enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 0); - video_grayscale = config_get_int(cat, "video_grayscale", 0); - video_graytype = config_get_int(cat, "video_graytype", 0); - - rctrl_is_lalt = config_get_int(cat, "rctrl_is_lalt", 0); - update_icons = config_get_int(cat, "update_icons", 1); - - window_remember = config_get_int(cat, "window_remember", 0); - if (window_remember) { - p = config_get_string(cat, "window_coordinates", NULL); - if (p == NULL) - p = "0, 0, 0, 0"; - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } else { - config_delete_var(cat, "window_remember"); - config_delete_var(cat, "window_coordinates"); - - window_w = window_h = window_x = window_y = 0; - } - - sound_gain = config_get_int(cat, "sound_gain", 0); - -#ifdef USE_LANGUAGE - /* - * Currently, 86Box is English (US) only, but in the future - * (version 3.0 at the earliest) other languages will be - * added, therefore it is better to future-proof the code. - */ - plat_langid = config_get_hex16(cat, "language", 0x0409); -#endif -} - - -/* Load "Machine" section. */ -static void -load_machine(void) -{ - char *cat = "Machine"; - char *p; - - p = config_get_string(cat, "machine", NULL); - if (p != NULL) - machine = machine_get_machine_from_internal_name(p); - else - machine = 0; - if (machine >= machine_count()) - machine = machine_count() - 1; - - /* This is for backwards compatibility. */ - p = config_get_string(cat, "model", NULL); - if (p != NULL) { - /* Detect the old model typos and fix them. */ - if (! strcmp(p, "p55r2p4")) { - machine = machine_get_machine_from_internal_name("p55t2p4"); - } else { - machine = machine_get_machine_from_internal_name(p); - } - config_delete_var(cat, "model"); - } - if (machine >= machine_count()) - machine = machine_count() - 1; - - romset = machine_getromset(); - cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); - cpu = config_get_int(cat, "cpu", 0); - cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - - mem_size = config_get_int(cat, "mem_size", 4096); - if (mem_size < (((machines[machine].flags & MACHINE_AT) && - (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) - mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); - if (mem_size > 1048576) - mem_size = 1048576; - - cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); - - enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); - - enable_sync = !!config_get_int(cat, "enable_sync", 1); - - /* Remove this after a while.. */ - config_delete_var(cat, "nvr_path"); -} - - -/* Load "Video" section. */ -static void -load_video(void) -{ - char *cat = "Video"; - char *p; - - if (machines[machine].fixed_gfxcard) { - config_delete_var(cat, "gfxcard"); - gfxcard = GFX_INTERNAL; - } else { - p = config_get_string(cat, "gfxcard", NULL); - if (p == NULL) { - if (machines[machine].flags & MACHINE_VIDEO) { - p = (char *)malloc((strlen("internal")+1)*sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *)malloc((strlen("none")+1)*sizeof(char)); - strcpy(p, "none"); - } - } - gfxcard = video_get_video_from_internal_name(p); - } - - voodoo_enabled = !!config_get_int(cat, "voodoo", 0); -} - - -/* Load "Input Devices" section. */ -static void -load_input_devices(void) -{ - char *cat = "Input devices"; - char temp[512]; - int c, d; - char *p; - - p = config_get_string(cat, "mouse_type", NULL); - if (p != NULL) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - joystick_type = config_get_int(cat, "joystick_type", 7); - - for (c=0; c max_spt) - hdd[c].spt = max_spt; - if (hdd[c].hpc > max_hpc) - hdd[c].hpc = max_hpc; - if (hdd[c].tracks > max_tracks) - hdd[c].tracks = max_tracks; - - /* MFM/RLL */ - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - if (hdd[c].bus == HDD_BUS_MFM) - hdd[c].mfm_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* XTA */ - sprintf(temp, "hdd_%02i_xta_channel", c+1); - if (hdd[c].bus == HDD_BUS_XTA) - hdd[c].xta_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* ESDI */ - sprintf(temp, "hdd_%02i_esdi_channel", c+1); - if (hdd[c].bus == HDD_BUS_ESDI) - hdd[c].esdi_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* IDE */ - // FIXME: Remove in a month. - sprintf(temp, "hdd_%02i_xtide_channel", c+1); - if (hdd[c].bus == HDD_BUS_IDE) - hdd[c].ide_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channel", c+1); - if (hdd[c].bus == HDD_BUS_IDE) { - sprintf(tmp2, "%01u:%01u", c>>1, c&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - hdd[c].ide_channel = (board<<1) + dev; - - if (hdd[c].ide_channel > 7) - hdd[c].ide_channel = 7; - } else { - config_delete_var(cat, temp); - } - - /* SCSI */ - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (hdd[c].bus == HDD_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c, 0); - p = config_get_string(cat, temp, tmp2); - - sscanf(p, "%02i:%02i", - (int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun); - - if (hdd[c].scsi_id > 15) - hdd[c].scsi_id = 15; - if (hdd[c].scsi_lun > 7) - hdd[c].scsi_lun = 7; - } else { - config_delete_var(cat, temp); - } - - memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); - memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); - sprintf(temp, "hdd_%02i_fn", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the CFG path. Just strip - * that off for now... - */ - wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); - } else -#endif - wcsncpy(hdd[c].fn, wp, sizeof_w(hdd[c].fn)); - - /* If disk is empty or invalid, mark it for deletion. */ - if (! hdd_is_valid(c)) { - sprintf(temp, "hdd_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_preide_channels", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channels", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - } -} - - -/* Load "Floppy Drives" section. */ -static void -load_floppy_drives(void) -{ - char *cat = "Floppy drives"; - char temp[512], *p; - wchar_t *wp; - int c; - - for (c=0; c 13) - fdd_set_type(c, 13); - - sprintf(temp, "fdd_%02i_fn", c + 1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else -#endif - wcsncpy(floppyfns[c], wp, sizeof_w(floppyfns[c])); - - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ - sprintf(temp, "fdd_%02i_writeprot", c+1); - ui_writeprot[c] = !!config_get_int(cat, temp, 0); - sprintf(temp, "fdd_%02i_turbo", c + 1); - fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); - sprintf(temp, "fdd_%02i_check_bpb", c+1); - fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); - - /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ - if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) { - sprintf(temp, "fdd_%02i_type", c+1); - config_delete_var(cat, temp); - } - if (wcslen(floppyfns[c]) == 0) { - sprintf(temp, "fdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } - if (ui_writeprot[c] == 0) { - sprintf(temp, "fdd_%02i_writeprot", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_turbo(c) == 0) { - sprintf(temp, "fdd_%02i_turbo", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_check_bpb(c) == 1) { - sprintf(temp, "fdd_%02i_check_bpb", c+1); - config_delete_var(cat, temp); - } - } -} - - -/* Load "Other Removable Devices" section. */ -static void -load_other_removable_devices(void) -{ - char *cat = "Other removable devices"; - char temp[512], tmp2[512], *p; - char s[512]; - unsigned int board = 0, dev = 0; - wchar_t *wp; - int c; - - memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - cdrom_drives[c].ide_channel = (board<<1)+dev; - - if (cdrom_drives[c].ide_channel > 7) - cdrom_drives[c].ide_channel = 7; - } else { - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &cdrom_drives[c].scsi_device_id, - &cdrom_drives[c].scsi_device_lun); - - if (cdrom_drives[c].scsi_device_id > 15) - cdrom_drives[c].scsi_device_id = 15; - if (cdrom_drives[c].scsi_device_lun > 7) - cdrom_drives[c].scsi_device_lun = 7; - } else { - config_delete_var(cat, temp); - } - } - - sprintf(temp, "cdrom_%02i_image_path", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom_image[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom_image[c].image_path)); - } else -#endif - wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path)); - - if (cdrom_drives[c].host_drive < 'A') - cdrom_drives[c].host_drive = 0; - - if ((cdrom_drives[c].host_drive == 0x200) && - (wcslen(cdrom_image[c].image_path) == 0)) - cdrom_drives[c].host_drive = 0; - - /* If the CD-ROM is disabled, delete all its variables. */ - if (cdrom_drives[c].bus_type == CDROM_BUS_DISABLED) { - sprintf(temp, "cdrom_%02i_host_drive", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_image_path", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "cdrom_%02i_iso_path", c+1); - config_delete_var(cat, temp); - } - - memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - zip_drives[c].ide_channel = (board<<1)+dev; - - if (zip_drives[c].ide_channel > 7) - zip_drives[c].ide_channel = 7; - } else { - sprintf(temp, "zip_%02i_scsi_location", c+1); - if (zip_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &zip_drives[c].scsi_device_id, - &zip_drives[c].scsi_device_lun); - - if (zip_drives[c].scsi_device_id > 15) - zip_drives[c].scsi_device_id = 15; - if (zip_drives[c].scsi_device_lun > 7) - zip_drives[c].scsi_device_lun = 7; - } else { - config_delete_var(cat, temp); - } - } - - sprintf(temp, "zip_%02i_image_path", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); - } else -#endif - wcsncpy(zip_drives[c].image_path, wp, sizeof_w(zip_drives[c].image_path)); - - /* If the CD-ROM is disabled, delete all its variables. */ - if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { - sprintf(temp, "zip_%02i_host_drive", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_image_path", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "zip_%02i_iso_path", c+1); - config_delete_var(cat, temp); - } -} - - -/* Load the specified or a default configuration file. */ -void -config_load(void) -{ - int i; - - config_log("Loading config file '%ls'..\n", cfg_path); - - memset(hdd, 0, sizeof(hard_disk_t)); - memset(cdrom_drives, 0, sizeof(cdrom_drive_t) * CDROM_NUM); - memset(cdrom_image, 0, sizeof(cdrom_image_t) * CDROM_NUM); -#ifdef USE_IOCTL - memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM); -#endif - memset(zip_drives, 0, sizeof(zip_drive_t)); - - if (! config_read(cfg_path)) { - cpu = 0; -#ifdef USE_LANGUAGE - plat_langid = 0x0409; -#endif - scale = 1; - machine = machine_get_machine_from_internal_name("ibmpc"); - gfxcard = GFX_CGA; - vid_api = plat_vidapi("default"); - enable_sync = 1; - joystick_type = 7; - if (hdc_name) { - free(hdc_name); - hdc_name = NULL; - } - hdc_name = (char *) malloc((strlen("none")+1) * sizeof(char)); - strcpy(hdc_name, "none"); - serial_enabled[0] = 1; - serial_enabled[1] = 1; - lpt_enabled = 1; - for (i = 0; i < FDD_NUM; i++) { - if (i < 2) - fdd_set_type(i, 2); - else - fdd_set_type(i, 0); - - fdd_set_turbo(i, 0); - fdd_set_check_bpb(i, 1); - } - mem_size = 640; - opl_type = 0; - - config_log("Config file not present or invalid!\n"); - return; - } - - load_general(); /* General */ - load_machine(); /* Machine */ - load_video(); /* Video */ - load_input_devices(); /* Input devices */ - load_sound(); /* Sound */ - load_network(); /* Network */ - load_ports(); /* Ports (COM & LPT) */ - load_other_peripherals(); /* Other peripherals */ - load_hard_disks(); /* Hard disks */ - load_floppy_drives(); /* Floppy drives */ - load_other_removable_devices(); /* Other removable devices */ - - /* Mark the configuration as changed. */ - config_changed = 1; - - config_log("Config loaded.\n\n"); -} - - -/* Save "General" section. */ -static void -save_general(void) -{ - char *cat = "General"; - char temp[512]; - - char *va_name; - - config_set_int(cat, "vid_resize", vid_resize); - if (vid_resize == 0) - config_delete_var(cat, "vid_resize"); - - va_name = plat_vidapi_name(vid_api); - if (!strcmp(va_name, "default")) { - config_delete_var(cat, "vid_renderer"); - } else { - config_set_string(cat, "vid_renderer", va_name); - } - - if (video_fullscreen_scale == 0) - config_delete_var(cat, "video_fullscreen_scale"); - else - config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); - - if (video_fullscreen_first == 0) - config_delete_var(cat, "video_fullscreen_first"); - else - config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - - if (force_43 == 0) - config_delete_var(cat, "force_43"); - else - config_set_int(cat, "force_43", force_43); - - if (scale == 1) - config_delete_var(cat, "scale"); - else - config_set_int(cat, "scale", scale); - - if (enable_overscan == 0) - config_delete_var(cat, "enable_overscan"); - else - config_set_int(cat, "enable_overscan", enable_overscan); - - if (vid_cga_contrast == 0) - config_delete_var(cat, "vid_cga_contrast"); - else - config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); - - if (video_grayscale == 0) - config_delete_var(cat, "video_grayscale"); - else - config_set_int(cat, "video_grayscale", video_grayscale); - - if (video_graytype == 0) - config_delete_var(cat, "video_graytype"); - else - config_set_int(cat, "video_graytype", video_graytype); - - if (rctrl_is_lalt == 0) - config_delete_var(cat, "rctrl_is_lalt"); - else - config_set_int(cat, "rctrl_is_lalt", rctrl_is_lalt); - - if (update_icons == 1) - config_delete_var(cat, "update_icons"); - else - config_set_int(cat, "update_icons", update_icons); - - if (window_remember) { - config_set_int(cat, "window_remember", window_remember); - - sprintf(temp, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string(cat, "window_coordinates", temp); - } else { - config_delete_var(cat, "window_remember"); - config_delete_var(cat, "window_coordinates"); - } - - if (sound_gain != 0) - config_set_int(cat, "sound_gain", sound_gain); - else - config_delete_var(cat, "sound_gain"); - -#ifdef USE_LANGUAGE - if (plat_langid == 0x0409) - config_delete_var(cat, "language"); - else - config_set_hex16(cat, "language", plat_langid); -#endif - - delete_section_if_empty(cat); -} - - -/* Save "Machine" section. */ -static void -save_machine(void) -{ - char *cat = "Machine"; - - config_set_string(cat, "machine", machine_get_internal_name()); - - if (cpu_manufacturer == 0) - config_delete_var(cat, "cpu_manufacturer"); - else - config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); - - if (cpu == 0) - config_delete_var(cat, "cpu"); - else - config_set_int(cat, "cpu", cpu); - - if (cpu_waitstates == 0) - config_delete_var(cat, "cpu_waitstates"); - else - config_set_int(cat, "cpu_waitstates", cpu_waitstates); - - if (mem_size == 4096) - config_delete_var(cat, "mem_size"); - else - config_set_int(cat, "mem_size", mem_size); - - config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - - if (enable_external_fpu == 0) - config_delete_var(cat, "cpu_enable_fpu"); - else - config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); - - if (enable_sync == 1) - config_delete_var(cat, "enable_sync"); - else - config_set_int(cat, "enable_sync", enable_sync); - - delete_section_if_empty(cat); -} - - -/* Save "Video" section. */ -static void -save_video(void) -{ - char *cat = "Video"; - - config_set_string(cat, "gfxcard", - video_get_internal_name(video_old_to_new(gfxcard))); - - if (voodoo_enabled == 0) - config_delete_var(cat, "voodoo"); - else - config_set_int(cat, "voodoo", voodoo_enabled); - - delete_section_if_empty(cat); -} - - -/* Save "Input Devices" section. */ -static void -save_input_devices(void) -{ - char *cat = "Input devices"; - char temp[512], tmp2[512]; - int c, d; - - config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - - if ((joystick_type == 0) || (joystick_type == 7)) { - if (joystick_type == 7) - config_delete_var(cat, "joystick_type"); - else - config_set_int(cat, "joystick_type", joystick_type); - - for (c=0; c<16; c++) { - sprintf(tmp2, "joystick_%i_nr", c); - config_delete_var(cat, tmp2); - - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_axis_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_button_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_pov_%i", c, d); - config_delete_var(cat, tmp2); - } - } - } else { - config_set_int(cat, "joystick_type", joystick_type); - - for (c=0; c> 1, hdd[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_SCSI)) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "hdd_%02i_fn", c+1); - if (hdd_is_valid(c) && (wcslen(hdd[c].fn) != 0)) - config_set_wstring(cat, temp, hdd[c].fn); - else - config_delete_var(cat, temp); - } - - delete_section_if_empty(cat); -} - - -/* Save "Floppy Drives" section. */ -static void -save_floppy_drives(void) -{ - char *cat = "Floppy drives"; - char temp[512]; - int c; - - for (c=0; c 'Z') && (cdrom_drives[c].host_drive != 200))) { - config_delete_var(cat, temp); - } else { - config_set_int(cat, temp, cdrom_drives[c].host_drive); - } - - sprintf(temp, "cdrom_%02i_speed", c+1); - if ((cdrom_drives[c].bus_type == 0) || (cdrom_drives[c].speed == 8)) { - config_delete_var(cat, temp); - } else { - config_set_int(cat, temp, cdrom_drives[c].speed); - } - - sprintf(temp, "cdrom_%02i_parameters", c+1); - if (cdrom_drives[c].bus_type == 0) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%u, %s", cdrom_drives[c].sound_on, - hdd_bus_to_string(cdrom_drives[c].bus_type, 1)); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - if (cdrom_drives[c].bus_type != CDROM_BUS_ATAPI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%01u", cdrom_drives[c].ide_channel>>1, - cdrom_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_scsi_location", c + 1); - if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", cdrom_drives[c].scsi_device_id, - cdrom_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_image_path", c + 1); - if ((cdrom_drives[c].bus_type == 0) || - (wcslen(cdrom_image[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_wstring(cat, temp, cdrom_image[c].image_path); - } - } - - for (c=0; c>1, - zip_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "zip_%02i_scsi_location", c + 1); - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", zip_drives[c].scsi_device_id, - zip_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || - (wcslen(zip_drives[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_wstring(cat, temp, zip_drives[c].image_path); - } - } - - delete_section_if_empty(cat); -} - - -void -config_save(void) -{ - save_general(); /* General */ - save_machine(); /* Machine */ - save_video(); /* Video */ - save_input_devices(); /* Input devices */ - save_sound(); /* Sound */ - save_network(); /* Network */ - save_ports(); /* Ports (COM & LPT) */ - save_other_peripherals(); /* Other peripherals */ - save_hard_disks(); /* Hard disks */ - save_floppy_drives(); /* Floppy drives */ - save_other_removable_devices(); /* Other removable devices */ - - config_write(cfg_path); -} - - -void -config_dump(void) -{ - section_t *sec; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - entry_t *ent; - - if (sec->name && sec->name[0]) - config_log("[%s]\n", sec->name); - - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - config_log("%s = %ls\n", ent->name, ent->wdata); - - ent = (entry_t *)ent->list.next; - } - - sec = (section_t *)sec->list.next; - } -} - - -void -config_delete_var(char *head, char *name) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) return; - - entry = find_entry(section, name); - if (entry != NULL) { - list_delete(&entry->list, §ion->entry_head); - free(entry); - } -} - - -int -config_get_int(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%i", &value); - - return(value); -} - - -int -config_get_hex16(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%04X", &value); - - return(value); -} - - -int -config_get_hex20(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%05X", &value); - - return(value); -} - - -int -config_get_mac(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int val0 = 0, val1 = 0, val2 = 0; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2); - - return((val0 << 16) + (val1 << 8) + val2); -} - - -char * -config_get_string(char *head, char *name, char *def) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - return(entry->data); -} - - -wchar_t * -config_get_wstring(char *head, char *name, wchar_t *def) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - return(entry->wdata); -} - - -void -config_set_int(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%i", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_hex16(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%04X", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_hex20(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%05X", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_mac(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%02x:%02x:%02x", - (val>>16)&0xff, (val>>8)&0xff, val&0xff); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_string(char *head, char *name, char *val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - strncpy(ent->data, val, sizeof(ent->data)); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_wstring(char *head, char *name, wchar_t *val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - memcpy(ent->wdata, val, sizeof_w(ent->wdata)); - wcstombs(ent->data, ent->wdata, sizeof(ent->data)); -} diff --git a/src - Cópia/config.h b/src - Cópia/config.h deleted file mode 100644 index 138748585..000000000 --- a/src - Cópia/config.h +++ /dev/null @@ -1,54 +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. - * - * Configuration file handler header. - * - * Version: @(#)config.h 1.0.6 2017/12/03 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef EMU_CONFIG_H -# define EMU_CONFIG_H - - -#ifdef __cplusplus -extern "C" { -#endif - -extern void config_load(void); -extern void config_save(void); -extern void config_write(wchar_t *fn); -extern void config_dump(void); - -extern void config_delete_var(char *head, char *name); -extern int config_get_int(char *head, char *name, int def); -extern int config_get_hex16(char *head, char *name, int def); -extern int config_get_hex20(char *head, char *name, int def); -extern int config_get_mac(char *head, char *name, int def); -extern char *config_get_string(char *head, char *name, char *def); -extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); -extern void config_set_int(char *head, char *name, int val); -extern void config_set_hex16(char *head, char *name, int val); -extern void config_set_hex20(char *head, char *name, int val); -extern void config_set_mac(char *head, char *name, int val); -extern void config_set_string(char *head, char *name, char *val); -extern void config_set_wstring(char *head, char *name, wchar_t *val); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_CONFIG_H*/ diff --git a/src - Cópia/cpu/386.c b/src - Cópia/cpu/386.c deleted file mode 100644 index 60012df57..000000000 --- a/src - Cópia/cpu/386.c +++ /dev/null @@ -1,284 +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 "x86.h" -#include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "386_common.h" - - -#define CPU_BLOCK_END() - -extern int codegen_flags_changed; - -extern int nmi_enable; - -int inscounts[256]; -uint32_t oldpc2; - -int trap; - -uint16_t flags,eflags; -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; - -x86seg gdt,ldt,idt,tr; -x86seg _cs,_ds,_es,_ss,_fs,_gs; -x86seg _oldds; - - - -extern int cpl_override; - -extern int fpucount; -uint16_t rds; -uint16_t ea_rseg; - -int cgate32; - -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; - -uint32_t rmdat32; -#define rmdat rmdat32 -#define fetchdat rmdat32 -uint32_t backupregs[16]; -extern int oddeven; -int inttype; - - -uint32_t oldcs2; -uint32_t oldecx; - -uint32_t *eal_r, *eal_w; - -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; - - -#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) || (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) || (eflags & VM_FLAG))\ - { \ - x86_int(6); \ - break; \ - } - - -#ifdef ENABLE_386_LOG -int x386_do_log = ENABLE_386_LOG; -#endif - - -static void -x386_log(const char *fmt, ...) -{ -#ifdef ENABLE_386_LOG - va_list ap; - - if (x386_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void exec386(int cycs) -{ - uint8_t temp; - uint32_t addr; - int tempi; - int cycdiff; - int oldcyc; - - cycles+=cycs; - /* output=3; */ - while (cycles>0) - { - int cycle_period = (timer_count >> TIMER_SHIFT) + 1; - - x86_was_reset = 0; - cycdiff=0; - oldcyc=cycles; - timer_start_period(cycles << TIMER_SHIFT); - while (cycdiff < cycle_period) - { - /* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX; - testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/ -/* testr[8]=flags;*/ - /* oldcs2=oldcs; */ - /* oldpc2=oldpc; */ - oldcs=CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; - cpu_state.op32 = use32; - - x86_was_reset = 0; - -dontprint=0; - - cpu_state.ea_seg = &_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - trap = flags & T_FLAG; - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - 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"); - } - } - } - cycdiff=oldcyc-cycles; - - if (trap) - { - flags_rebuild(); - /* oldpc=pc; */ - /* oldcs=CS; */ - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - flags&=~I_FLAG; - 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 ((flags&I_FLAG) && pic_intpending) - { - temp=picinterrupt(); - if (temp!=0xFF) - { - flags_rebuild(); - if (msw&1) - { - pmodeint(temp,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (temp << 2) + idt.base; - flags&=~I_FLAG; - 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"); - } - } - - tsc += cycdiff; - - timer_end_period(cycles << TIMER_SHIFT); - } -} diff --git a/src - Cópia/cpu/386.h b/src - Cópia/cpu/386.h deleted file mode 100644 index e207d48ca..000000000 --- a/src - Cópia/cpu/386.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern void cpu_386_flags_extract(); -extern void cpu_386_flags_rebuild(); diff --git a/src - Cópia/cpu/386_common.h b/src - Cópia/cpu/386_common.h deleted file mode 100644 index c7abc9793..000000000 --- a/src - Cópia/cpu/386_common.h +++ /dev/null @@ -1,266 +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. - * - * Common 386 CPU code. - * - * Version: @(#)386_common.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -extern uint16_t ea_rseg; - -#undef readmemb -#undef writememb - - -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((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 || (s)==0xFFFFFFFF) writememb386l(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)==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 - - -#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - x86gpf("check_io_perm(): no permission",0); \ - return 1; \ - } \ - } - -#define checkio_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \ - { \ - tempi = checkio(port); \ - if (cpu_state.abrt) break; \ - if (tempi) \ - { \ - x86gpf("checkio_perm(): no permission",0); \ - break; \ - } \ - } - -#define CHECK_READ(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \ - { \ - x86gpf("Limit check (READ)", 0); \ - return 1; \ - } \ - if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } - -#define CHECK_WRITE(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((chseg)->access & 8))) \ - { \ - x86gpf("Limit check (WRITE)", 0); \ - return 1; \ - } \ - if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } - -#define CHECK_WRITE_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (WRITE REP)", 0); \ - break; \ - } \ - if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } - - -#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 1; \ - } - - - - -static __inline uint8_t fastreadb(uint32_t a) -{ - uint8_t *t; - - if ((a >> 12) == pccache) - return *((uint8_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache = a >> 12; - pccache2 = t; - return *((uint8_t *)&pccache2[a]); -} - -static __inline uint16_t fastreadw(uint32_t a) -{ - uint8_t *t; - uint16_t val; - if ((a&0xFFF)>0xFFE) - { - val = fastreadb(a); - val |= (fastreadb(a + 1) << 8); - return val; - } - if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - - pccache = a >> 12; - pccache2 = t; - return *((uint16_t *)&pccache2[a]); -} - -static __inline uint32_t fastreadl(uint32_t a) -{ - uint8_t *t; - uint32_t val; - if ((a&0xFFF)<0xFFD) - { - if ((a>>12)!=pccache) - { - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache2 = t; - pccache=a>>12; - /* return *((uint32_t *)&pccache2[a]); */ - } - return *((uint32_t *)&pccache2[a]); - } - val = fastreadw(a); - val |= (fastreadw(a + 2) << 16); - return val; -} - -static __inline uint8_t getbyte() -{ - cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); -} - -static __inline uint16_t getword() -{ - cpu_state.pc+=2; - return fastreadw(cs+(cpu_state.pc-2)); -} - -static __inline uint32_t getlong() -{ - cpu_state.pc+=4; - return fastreadl(cs+(cpu_state.pc-4)); -} - -static __inline uint64_t getquad() -{ - cpu_state.pc+=8; - return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32); -} - - - -static __inline uint8_t geteab() -{ - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; - if (eal_r) - return *(uint8_t *)eal_r; - return readmemb(easeg, cpu_state.eaaddr); -} - -static __inline uint16_t geteaw() -{ - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - /* cycles-=3; */ - if (eal_r) - return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); -} - -static __inline uint32_t geteal() -{ - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].l; - /* cycles-=3; */ - if (eal_r) - return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); -} - -static __inline uint64_t geteaq() -{ - return readmemq(easeg, cpu_state.eaaddr); -} - -static __inline uint8_t geteab_mem() -{ - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,cpu_state.eaaddr); -} -static __inline uint16_t geteaw_mem() -{ - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,cpu_state.eaaddr); -} -static __inline uint32_t geteal_mem() -{ - if (eal_r) return *eal_r; - return readmeml(easeg,cpu_state.eaaddr); -} - -static __inline void seteaq(uint64_t v) -{ - writememql(easeg, cpu_state.eaaddr, v); -} - -#define seteab(v) if (cpu_mod!=3) { 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) { 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) { if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v - -#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); - -#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 rmdat rmdat32 -#define fetchdat rmdat32 - -void x86_int(int num); diff --git a/src - Cópia/cpu/386_dynarec.c b/src - Cópia/cpu/386_dynarec.c deleted file mode 100644 index a3ff0c0ee..000000000 --- a/src - Cópia/cpu/386_dynarec.c +++ /dev/null @@ -1,937 +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 "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" -#ifdef USE_DYNAREC -#include "codegen.h" -#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; -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; - -int cpu_block_end = 0; - -int nmi_enable = 1; - -int inscounts[256]; -uint32_t oldpc2; - -int trap; - - - -int cpl_override=0; - -int fpucount=0; -uint16_t rds; -uint16_t ea_rseg; - -int cgate32; - -uint32_t rmdat32; -uint32_t backupregs[16]; -int oddeven=0; -int inttype; - - -uint32_t oldcs2; -uint32_t oldecx; - -uint32_t *eal_r, *eal_w; - -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; - - -#ifdef ENABLE_386_DYNAREC_LOG -int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; -#endif - - -static void -x386_dynarec_log(const char *fmt, ...) -{ -#ifdef ENABLE_386_DYNAREC_LOG - va_list ap; - - if (x386_dynarec_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static __inline void fetch_ea_32_long(uint32_t rmdat) -{ - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; - 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; - ea_rseg = SS; - cpu_state.ea_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; - ea_rseg = SS; - cpu_state.ea_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; - ea_rseg = cpu_state.ea_seg->seg; - 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; - ea_rseg = SS; - cpu_state.ea_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" - -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(); - x386_dynarec_log("Triple fault in real mode - reset\n"); - } - else - x86_int(8); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - flags&=~I_FLAG; - 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,flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - flags&=~I_FLAG; - 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),flags); if (cpu_state.abrt) {x386_dynarec_log("abrt5\n"); return 1; } - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {x386_dynarec_log("abrt6\n"); return 1; } - SP-=6; - - eflags &= ~VIF_FLAG; - 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. - - 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; -} - -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() - - -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; - -#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)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG)) - -#ifdef USE_DYNAREC -static int cycles_main = 0; - -void exec386_dynarec(int cycs) -{ - uint8_t temp; - 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; - - timer_start_period(cycles << TIMER_SHIFT); - 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 = &_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) - { - trap = flags & T_FLAG; - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - - 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 (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 = &_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) - { - trap = flags & T_FLAG; - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - - 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 (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 = &_ds; - cpu_state.ssegs = 0; - - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - trap = flags & T_FLAG; - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - - 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 (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; - x386_dynarec_log("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - x386_dynarec_log("Triple fault - reset\n"); - } - } - } - - if (trap) - { - - flags_rebuild(); - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - flags&=~I_FLAG; - 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 ((flags&I_FLAG) && pic_intpending) - { - temp=picinterrupt(); - if (temp!=0xFF) - { - CPU_BLOCK_END(); - flags_rebuild(); - if (msw&1) - { - pmodeint(temp,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr=temp<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - } - } - timer_end_period(cycles << TIMER_SHIFT); - cycles_main -= (cycles_start - cycles); - } -} -#endif diff --git a/src - Cópia/cpu/386_dynarec_ops.c b/src - Cópia/cpu/386_dynarec_ops.c deleted file mode 100644 index d3dd4688d..000000000 --- a/src - Cópia/cpu/386_dynarec_ops.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#ifndef INFINITY -# define INFINITY (__builtin_inff()) -#endif -#include "../86box.h" -#include "cpu.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 "codegen.h" -#include "../pic.h" - -#define CPU_BLOCK_END() cpu_block_end = 1 - -#include "386_common.h" - - -extern uint16_t *mod1add[2][8]; -extern uint32_t *mod1seg[8]; - -static __inline void fetch_ea_32_long(uint32_t rmdat) -{ - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; - 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; - ea_rseg = cpu_state.ea_seg->seg; - 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++; 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) -#define PREFETCH_PREFIX() -#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 - Cópia/cpu/386_ops.h b/src - Cópia/cpu/386_ops.h deleted file mode 100644 index d961bd4ac..000000000 --- a/src - Cópia/cpu/386_ops.h +++ /dev/null @@ -1,1637 +0,0 @@ -/* - * 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. - * - * 286/386+ instruction handlers list. - * - * Version: @(#)386_ops.h 1.0.3 2018/05/21 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * leilei, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include "x86_ops.h" - - -#define ILLEGAL_ON(cond) \ - do \ - { \ - if ((cond)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 0; \ - } \ - } while (0) - -static __inline void PUSH_W(uint16_t val) -{ - if (stack32) - { - writememw(ss, ESP - 2, val); if (cpu_state.abrt) return; - ESP -= 2; - cpu_state.last_ea = ESP; - } - else - { - writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 2; - cpu_state.last_ea = SP; - } -} - -static __inline void PUSH_L(uint32_t val) -{ - if (stack32) - { - writememl(ss, ESP - 4, val); if (cpu_state.abrt) return; - ESP -= 4; - cpu_state.last_ea = ESP; - } - else - { - writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 4; - cpu_state.last_ea = SP; - } -} - -static __inline uint16_t POP_W() -{ - uint16_t ret; - if (stack32) - { - ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - cpu_state.last_ea = ESP; - } - else - { - ret = readmemw(ss, SP); if (cpu_state.abrt) return 0; - SP += 2; - cpu_state.last_ea = SP; - } - return ret; -} - -static __inline uint32_t POP_L() -{ - uint32_t ret; - if (stack32) - { - ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - cpu_state.last_ea = ESP; - } - else - { - ret = readmeml(ss, SP); if (cpu_state.abrt) return 0; - SP += 4; - cpu_state.last_ea = SP; - } - return ret; -} - -static __inline uint16_t POP_W_seg(uint32_t seg) -{ - uint16_t ret; - if (stack32) - { - ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - cpu_state.last_ea = ESP; - } - else - { - ret = readmemw(seg, SP); if (cpu_state.abrt) return 0; - SP += 2; - cpu_state.last_ea = SP; - } - return ret; -} - -static __inline uint32_t POP_L_seg(uint32_t seg) -{ - uint32_t ret; - if (stack32) - { - ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - cpu_state.last_ea = ESP; - } - else - { - ret = readmeml(seg, SP); if (cpu_state.abrt) return 0; - SP += 4; - cpu_state.last_ea = SP; - } - return ret; -} - -static int fopcode; - -static int ILLEGAL(uint32_t fetchdat) -{ - cpu_state.pc = cpu_state.oldpc; - - pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode); - x86illegal(); - return 0; -} - -#if 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 - -#include "x86seg.h" -#if defined(DEV_BRANCH) && defined(USE_AMD_K) -# include "x86_ops_amd.h" -#endif -#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" -#include "x86_ops_int.h" -#include "x86_ops_io.h" -#include "x86_ops_jump.h" -#include "x86_ops_misc.h" -#include "x87_ops.h" -#if defined(DEV_BRANCH) && defined(USE_I686) -# include "x86_ops_i686.h" -#endif -#include "x86_ops_mmx.h" -#include "x86_ops_mmx_arith.h" -#include "x86_ops_mmx_cmp.h" -#include "x86_ops_mmx_logic.h" -#include "x86_ops_mmx_mov.h" -#include "x86_ops_mmx_pack.h" -#include "x86_ops_mmx_shift.h" -#include "x86_ops_mov.h" -#include "x86_ops_mov_ctrl.h" -#include "x86_ops_mov_seg.h" -#include "x86_ops_movx.h" -#include "x86_ops_msr.h" -#include "x86_ops_mul.h" -#include "x86_ops_pmode.h" -#include "x86_ops_prefix.h" -#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" - - -static int op0F_w_a16(uint32_t fetchdat) -{ - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; - - PREFETCH_PREFIX(); - - return x86_opcodes_0f[opcode](fetchdat >> 8); -} -static int op0F_l_a16(uint32_t fetchdat) -{ - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; - - PREFETCH_PREFIX(); - - return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); -} -static int op0F_w_a32(uint32_t fetchdat) -{ - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; - - PREFETCH_PREFIX(); - - return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); -} -static int op0F_l_a32(uint32_t fetchdat) -{ - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; - - PREFETCH_PREFIX(); - - return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); -} - - -const OpFn OP_TABLE(286_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_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*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, - - /*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_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*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, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*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, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*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, -}; - -const OpFn OP_TABLE(386_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, 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, - -/*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*/ 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, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, 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, 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, - - /*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, 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, - -/*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*/ 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, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, 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, 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, - - /*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, 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_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*/ 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*/ 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, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, 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, 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, - - /*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, 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_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*/ 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*/ 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, ILLEGAL, 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*/ ILLEGAL, ILLEGAL, 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, 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, -}; - -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, -/*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, - -/*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*/ 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, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, -/*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, - - /*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, 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, - -/*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*/ 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, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, -/*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, - - /*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, 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_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*/ 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*/ 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, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, -/*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, - - /*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, 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_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*/ 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*/ 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, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, -/*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, -}; - -const OpFn OP_TABLE(winchip_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, -/*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, 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, 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, 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, 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, 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, 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, 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, -}; - -const OpFn OP_TABLE(pentium_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, -/*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, 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*/ 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, 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, - - /*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, 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, 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*/ 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, 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, - - /*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, 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, 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*/ 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, 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, - - /*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, 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, 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*/ 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, 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, -}; - -const OpFn OP_TABLE(pentiummmx_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, -/*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, 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, 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, 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, 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, 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, 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, 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, -}; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) -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, 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, 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, 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, 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, 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, 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, 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(c6x86mx_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, -/*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*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, -/*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, 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*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, -/*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, 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*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, -/*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, 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*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, -/*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, -}; - -#ifdef DEV_BRANCH -#ifdef USE_I686 -const OpFn OP_TABLE(pentiumpro_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, opNOP, 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*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, -/*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*/ 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, 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, - - /*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, opNOP, 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*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, -/*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*/ 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, 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, - - /*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, opNOP, 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*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, -/*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*/ 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, 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, - - /*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, opNOP, 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*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, -/*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*/ 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, 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, -}; - -#if 0 -const OpFn OP_TABLE(pentium2_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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, -/*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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, -/*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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, -/*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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, -/*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(pentium2d_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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, -/*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,opFXSAVESTOR_a16,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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, -/*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,opFXSAVESTOR_a16,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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, -/*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,opFXSAVESTOR_a32,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, opNOP, 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, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, -/*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,opFXSAVESTOR_a32,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 -#endif - -const OpFn OP_TABLE(286)[1024] = -{ - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, -/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, -/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, -/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, -/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, -/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, -/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, -/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, -/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, -}; - -const OpFn OP_TABLE(386)[1024] = -{ - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, -/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, opFS_w_a16, opGS_w_a16, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_w_a16, op80_a16, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, -/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a16,opADD_l_rmw_a16,opADD_b_rm_a16, opADD_l_rm_a16, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a16, opOR_l_rmw_a16, opOR_b_rm_a16, opOR_l_rm_a16, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a16, -/*10*/ opADC_b_rmw_a16,opADC_l_rmw_a16,opADC_b_rm_a16, opADC_l_rm_a16, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a16,opSBB_l_rmw_a16,opSBB_b_rm_a16, opSBB_l_rm_a16, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, -/*20*/ opAND_b_rmw_a16,opAND_l_rmw_a16,opAND_b_rm_a16, opAND_l_rm_a16, opAND_AL_imm, opAND_EAX_imm, opES_l_a16, opDAA, opSUB_b_rmw_a16,opSUB_l_rmw_a16,opSUB_b_rm_a16, opSUB_l_rm_a16, opSUB_AL_imm, opSUB_EAX_imm, opCS_l_a16, opDAS, -/*30*/ opXOR_b_rmw_a16,opXOR_l_rmw_a16,opXOR_b_rm_a16, opXOR_l_rm_a16, opXOR_AL_imm, opXOR_EAX_imm, opSS_l_a16, opAAA, opCMP_b_rmw_a16,opCMP_l_rmw_a16,opCMP_b_rm_a16, opCMP_l_rm_a16, opCMP_AL_imm, opCMP_EAX_imm, opDS_l_a16, opAAS, - -/*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, -/*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, -/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a16, opARPL_a16, opFS_l_a16, opGS_l_a16, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a16,opPUSH_imm_bl, opIMUL_l_ib_a16,opINSB_a16, opINSL_a16, opOUTSB_a16, opOUTSL_a16, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a16, op81_l_a16, op80_a16, op83_l_a16, opTEST_b_a16, opTEST_l_a16, opXCHG_b_a16, opXCHG_l_a16, opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, opMOV_l_seg_a16,opLEA_l_a16, opMOV_seg_w_a16,opPOPL_a16, -/*90*/ opNOP, opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE, opCDQ, opCALL_far_l, opWAIT, opPUSHFD, opPOPFD, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a16, opMOV_EAX_a16, opMOV_a16_AL, opMOV_a16_EAX, opMOVSB_a16, opMOVSL_a16, opCMPSB_a16, opCMPSL_a16, opTEST_AL, opTEST_EAX, opSTOSB_a16, opSTOSL_a16, opLODSB_a16, opLODSL_a16, opSCASB_a16, opSCASL_a16, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_EAX_imm, opMOV_ECX_imm, opMOV_EDX_imm, opMOV_EBX_imm, opMOV_ESP_imm, opMOV_EBP_imm, opMOV_ESI_imm, opMOV_EDI_imm, - -/*c0*/ opC0_a16, opC1_l_a16, opRET_l_imm, opRET_l, opLES_l_a16, opLDS_l_a16, opMOV_b_imm_a16,opMOV_l_imm_a16,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, -/*d0*/ opD0_a16, opD1_l_a16, opD2_a16, opD3_l_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, -/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, -/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a32,opADD_w_rmw_a32,opADD_b_rm_a32, opADD_w_rm_a32, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a32, opOR_w_rmw_a32, opOR_b_rm_a32, opOR_w_rm_a32, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a32, -/*10*/ opADC_b_rmw_a32,opADC_w_rmw_a32,opADC_b_rm_a32, opADC_w_rm_a32, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a32,opSBB_w_rmw_a32,opSBB_b_rm_a32, opSBB_w_rm_a32, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, -/*20*/ opAND_b_rmw_a32,opAND_w_rmw_a32,opAND_b_rm_a32, opAND_w_rm_a32, opAND_AL_imm, opAND_AX_imm, opES_w_a32, opDAA, opSUB_b_rmw_a32,opSUB_w_rmw_a32,opSUB_b_rm_a32, opSUB_w_rm_a32, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a32, opDAS, -/*30*/ opXOR_b_rmw_a32,opXOR_w_rmw_a32,opXOR_b_rm_a32, opXOR_w_rm_a32, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a32, opAAA, opCMP_b_rmw_a32,opCMP_w_rmw_a32,opCMP_b_rm_a32, opCMP_w_rm_a32, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a32, opAAS, - -/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, -/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, -/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a32, opARPL_a32, opFS_w_a32, opGS_w_a32, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a32,opPUSH_imm_bw, opIMUL_w_ib_a32,opINSB_a32, opINSW_a32, opOUTSB_a32, opOUTSW_a32, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a32, op81_w_a32, op80_a32, op83_w_a32, opTEST_b_a32, opTEST_w_a32, opXCHG_b_a32, opXCHG_w_a32, opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, opMOV_w_seg_a32,opLEA_w_a32, opMOV_seg_w_a32,opPOPW_a32, -/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a32, opMOV_AX_a32, opMOV_a32_AL, opMOV_a32_AX, opMOVSB_a32, opMOVSW_a32, opCMPSB_a32, opCMPSW_a32, opTEST_AL, opTEST_AX, opSTOSB_a32, opSTOSW_a32, opLODSB_a32, opLODSW_a32, opSCASB_a32, opSCASW_a32, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, - -/*c0*/ opC0_a32, opC1_w_a32, opRET_w_imm, opRET_w, opLES_w_a32, opLDS_w_a32, opMOV_b_imm_a32,opMOV_w_imm_a32,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, -/*d0*/ opD0_a32, opD1_w_a32, opD2_a32, opD3_w_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, -/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ opADD_b_rmw_a32,opADD_l_rmw_a32,opADD_b_rm_a32, opADD_l_rm_a32, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a32, opOR_l_rmw_a32, opOR_b_rm_a32, opOR_l_rm_a32, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a32, -/*10*/ opADC_b_rmw_a32,opADC_l_rmw_a32,opADC_b_rm_a32, opADC_l_rm_a32, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a32,opSBB_l_rmw_a32,opSBB_b_rm_a32, opSBB_l_rm_a32, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, -/*20*/ opAND_b_rmw_a32,opAND_l_rmw_a32,opAND_b_rm_a32, opAND_l_rm_a32, opAND_AL_imm, opAND_EAX_imm, opES_l_a32, opDAA, opSUB_b_rmw_a32,opSUB_l_rmw_a32,opSUB_b_rm_a32, opSUB_l_rm_a32, opSUB_AL_imm, opSUB_EAX_imm, opCS_l_a32, opDAS, -/*30*/ opXOR_b_rmw_a32,opXOR_l_rmw_a32,opXOR_b_rm_a32, opXOR_l_rm_a32, opXOR_AL_imm, opXOR_EAX_imm, opSS_l_a32, opAAA, opCMP_b_rmw_a32,opCMP_l_rmw_a32,opCMP_b_rm_a32, opCMP_l_rm_a32, opCMP_AL_imm, opCMP_EAX_imm, opDS_l_a32, opAAS, - -/*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, -/*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, -/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a32, opARPL_a32, opFS_l_a32, opGS_l_a32, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a32,opPUSH_imm_bl, opIMUL_l_ib_a32,opINSB_a32, opINSL_a32, opOUTSB_a32, opOUTSL_a32, -/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, - -/*80*/ op80_a32, op81_l_a32, op80_a32, op83_l_a32, opTEST_b_a32, opTEST_l_a32, opXCHG_b_a32, opXCHG_l_a32, opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, opMOV_l_seg_a32,opLEA_l_a32, opMOV_seg_w_a32,opPOPL_a32, -/*90*/ opNOP, opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE, opCDQ, opCALL_far_l, opWAIT, opPUSHFD, opPOPFD, opSAHF, opLAHF, -/*a0*/ opMOV_AL_a32, opMOV_EAX_a32, opMOV_a32_AL, opMOV_a32_EAX, opMOVSB_a32, opMOVSL_a32, opCMPSB_a32, opCMPSL_a32, opTEST_AL, opTEST_EAX, opSTOSB_a32, opSTOSL_a32, opLODSB_a32, opLODSL_a32, opSCASB_a32, opSCASL_a32, -/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_EAX_imm, opMOV_ECX_imm, opMOV_EDX_imm, opMOV_EBX_imm, opMOV_ESP_imm, opMOV_EBP_imm, opMOV_ESI_imm, opMOV_EDI_imm, - -/*c0*/ opC0_a32, opC1_l_a32, opRET_l_imm, opRET_l, opLES_l_a32, opLDS_l_a32, opMOV_b_imm_a32,opMOV_l_imm_a32,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, -/*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, -/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, -/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, -}; - -const OpFn OP_TABLE(REPE)[1024] = -{ - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a16,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a16,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a16,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a16,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a32,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a32,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a32,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a32,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const OpFn OP_TABLE(REPNE)[1024] = -{ - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a16,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a16,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a16,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a16,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a32,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a32,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a32,0, -/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a32,0, - -/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*60*/ 0, 0, 0, 0, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, -/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; diff --git a/src - Cópia/cpu/808x.c b/src - Cópia/cpu/808x.c deleted file mode 100644 index 53e2403cc..000000000 --- a/src - Cópia/cpu/808x.c +++ /dev/null @@ -1,3324 +0,0 @@ -/* - * 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. - * - * 808x CPU emulation. - * - * SHR AX,1 - * - * 4 clocks - fetch opcode - * 4 clocks - fetch mod/rm - * 2 clocks - execute 2 clocks - fetch opcode 1 - * 2 clocks - fetch opcode 2 - * 4 clocks - fetch mod/rm - * 2 clocks - fetch opcode 1 2 clocks - execute - * 2 clocks - fetch opcode 2 etc - * - * Version: @(#)808x.c 1.0.5 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_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 "../plat.h" - - -int xt_cpu_multi; -int nmi = 0; -int nmi_auto_clear = 0; - -int nextcyc=0; -int cycdiff; -int is8086=0; - -int memcycs; -int nopageerrors=0; - -void FETCHCOMPLETE(); - -uint8_t readmembl(uint32_t addr); -void writemembl(uint32_t addr, uint8_t val); -uint16_t readmemwl(uint32_t seg, uint32_t addr); -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); -uint32_t readmemll(uint32_t seg, uint32_t addr); -void writememll(uint32_t seg, uint32_t addr, uint32_t val); - - -#ifdef ENABLE_808X_LOG -int x808x_do_log = ENABLE_808X_LOG; -#endif - - -static void -x808x_log(const char *fmt, ...) -{ -#ifdef ENABLE_808X_LOG - va_list ap; - - if (x808x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -#undef readmemb -#undef readmemw -uint8_t readmemb(uint32_t a) -{ - if (a!=(cs+cpu_state.pc)) memcycs+=4; - if (readlookup2 == NULL) return readmembl(a); - if (readlookup2[(a)>>12]==-1) return readmembl(a); - else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); -} - -uint8_t readmembf(uint32_t a) -{ - if (readlookup2 == NULL) return readmembl(a); - if (readlookup2[(a)>>12]==-1) return readmembl(a); - else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); -} - -uint16_t readmemw(uint32_t s, uint16_t a) -{ - if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); - if (readlookup2 == NULL) return readmemwl(s,a); - if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s,a); - else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); -} - -void refreshread() { FETCHCOMPLETE(); memcycs+=4; } - -#undef fetchea -#define fetchea() { rmdat=FETCH(); \ - cpu_reg=(rmdat>>3)&7; \ - cpu_mod=(rmdat>>6)&3; \ - cpu_rm=rmdat&7; \ - if (cpu_mod!=3) fetcheal(); } - -void writemembl(uint32_t addr, uint8_t val); -void writememb(uint32_t a, uint8_t v) -{ - memcycs+=4; - if (writelookup2 == NULL) writemembl(a,v); - if (writelookup2[(a)>>12]==-1) writemembl(a,v); - else *(uint8_t *)(writelookup2[a >> 12] + a) = v; -} -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); -void writememw(uint32_t s, uint32_t a, uint16_t v) -{ - memcycs+=(8>>is8086); - if (writelookup2 == NULL) writememwl(s,a,v); - if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s,a,v); - else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; -} -void writememll(uint32_t seg, uint32_t addr, uint32_t val); -void writememl(uint32_t s, uint32_t a, uint32_t v) -{ - if (writelookup2 == NULL) writememll(s,a,v); - if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s,a,v); - else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; -} - - -void dumpregs(int); -uint16_t oldcs; -int oldcpl; - -int tempc; -uint8_t opcode; -uint16_t pc2,pc3; -int noint=0; - -int output=0; - -#if 0 -/* Also in mem.c */ -int shadowbios=0; -#endif - -int ins=0; - -int fetchcycles=0,memcycs,fetchclocks; - -uint8_t prefetchqueue[6]; -uint16_t prefetchpc; -int prefetchw=0; -static __inline uint8_t FETCH() -{ - uint8_t temp; -/* temp=prefetchqueue[0]; - prefetchqueue[0]=prefetchqueue[1]; - prefetchqueue[1]=prefetchqueue[2]; - prefetchqueue[2]=prefetchqueue[3]; - prefetchqueue[3]=prefetchqueue[4]; - prefetchqueue[4]=prefetchqueue[5]; - if (prefetchw<=((is8086)?4:3)) - { - prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; - if (is8086 && (prefetchpc&1)) - { - prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; - } - }*/ - - if (prefetchw==0) - { - cycles-=(4-(fetchcycles&3)); - fetchclocks+=(4-(fetchcycles&3)); - fetchcycles=4; - temp=readmembf(cs+cpu_state.pc); - prefetchpc = cpu_state.pc = cpu_state.pc + 1; - if (is8086 && (cpu_state.pc&1)) - { - prefetchqueue[0]=readmembf(cs+cpu_state.pc); - prefetchpc++; - prefetchw++; - } - } - else - { - temp=prefetchqueue[0]; - prefetchqueue[0]=prefetchqueue[1]; - prefetchqueue[1]=prefetchqueue[2]; - prefetchqueue[2]=prefetchqueue[3]; - prefetchqueue[3]=prefetchqueue[4]; - prefetchqueue[4]=prefetchqueue[5]; - prefetchw--; - fetchcycles-=4; - cpu_state.pc++; - } - return temp; -} - -static __inline void FETCHADD(int c) -{ - int d; - if (c<0) return; - if (prefetchw>((is8086)?4:3)) return; - d=c+(fetchcycles&3); - while (d>3 && prefetchw<((is8086)?6:4)) - { - d-=4; - if (is8086 && !(prefetchpc&1)) - { - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw++; - } - if (prefetchw<6) - { - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw++; - } - } - fetchcycles+=c; - if (fetchcycles>16) fetchcycles=16; -} - -void FETCHCOMPLETE() -{ - if (!(fetchcycles&3)) return; - if (prefetchw>((is8086)?4:3)) return; - if (!prefetchw) nextcyc=(4-(fetchcycles&3)); - cycles-=(4-(fetchcycles&3)); - fetchclocks+=(4-(fetchcycles&3)); - if (is8086 && !(prefetchpc&1)) - { - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw++; - } - if (prefetchw<6) - { - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw++; - } - fetchcycles+=(4-(fetchcycles&3)); -} - -static __inline void FETCHCLEAR() -{ - prefetchpc=cpu_state.pc; - prefetchw=0; - memcycs=cycdiff-cycles; - fetchclocks=0; -} - -static uint16_t getword() -{ - uint8_t temp=FETCH(); - return temp|(FETCH()<<8); -} - - -/*EA calculation*/ - -/*R/M - bits 0-2 - R/M bits 3-5 - Reg bits 6-7 - mod - From 386 programmers manual : -r8(/r) AL CL DL BL AH CH DH BH -r16(/r) AX CX DX BX SP BP SI DI -r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI -/digit (Opcode) 0 1 2 3 4 5 6 7 -REG = 000 001 010 011 100 101 110 111 - ����Address -disp8 denotes an 8-bit displacement following the ModR/M byte, to be -sign-extended and added to the index. disp16 denotes a 16-bit displacement -following the ModR/M byte, to be added to the index. Default segment -register is SS for the effective addresses containing a BP index, DS for -other effective addresses. - �Ŀ �Mod R/M� ���������ModR/M Values in Hexadecimal�������Ŀ - -[BX + SI] 000 00 08 10 18 20 28 30 38 -[BX + DI] 001 01 09 11 19 21 29 31 39 -[BP + SI] 010 02 0A 12 1A 22 2A 32 3A -[BP + DI] 011 03 0B 13 1B 23 2B 33 3B -[SI] 00 100 04 0C 14 1C 24 2C 34 3C -[DI] 101 05 0D 15 1D 25 2D 35 3D -disp16 110 06 0E 16 1E 26 2E 36 3E -[BX] 111 07 0F 17 1F 27 2F 37 3F - -[BX+SI]+disp8 000 40 48 50 58 60 68 70 78 -[BX+DI]+disp8 001 41 49 51 59 61 69 71 79 -[BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A -[BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B -[SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C -[DI]+disp8 101 45 4D 55 5D 65 6D 75 7D -[BP]+disp8 110 46 4E 56 5E 66 6E 76 7E -[BX]+disp8 111 47 4F 57 5F 67 6F 77 7F - -[BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8 -[BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9 -[BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA -[BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB -[SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC -[DI]+disp16 101 85 8D 95 9D A5 AD B5 BD -[BP]+disp16 110 86 8E 96 9E A6 AE B6 BE -[BX]+disp16 111 87 8F 97 9F A7 AF B7 BF - -EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8 -ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9 -EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA -EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB -ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC -EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD -ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE -EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF - -mod = 11 - register - 10 - address + 16 bit displacement - 01 - address + 8 bit displacement - 00 - address - -reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers) - 0=AX/AL 1=CX/CL 2=DX/DL 3=BX/BL - 4=SP/AH 5=BP/CH 6=SI/DH 7=DI/BH - - Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB - selects whether BX/BP are used at all (0=used). - - mod=00 is an exception though - 6=16 bit displacement only - 7=[BX] - - Usage varies with instructions. - - MOV AL,BL has ModR/M as C3, for example. - mod=11, reg=0, r/m=3 - MOV uses reg as dest, and r/m as src. - reg 0 is AL, reg 3 is BL - - If BP or SP are in address calc, seg is SS, else DS -*/ - -uint32_t easeg; -int rmdat; - -uint16_t zero=0; -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; - -int slowrm[8]; - -void makemod1table() -{ - mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP; - mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX; - mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI; - mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero; - slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0; - mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss; - mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds; -} - -static void fetcheal() -{ - if (!cpu_mod && cpu_rm==6) { cpu_state.eaaddr=getword(); easeg=ds; FETCHADD(6); } - else - { - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr=0; - if (cpu_rm&4) FETCHADD(5); - else FETCHADD(7+slowrm[cpu_rm]); - break; - case 1: - cpu_state.eaaddr=(uint16_t)(int8_t)FETCH(); - if (cpu_rm&4) FETCHADD(9); - else FETCHADD(11+slowrm[cpu_rm]); - break; - case 2: - cpu_state.eaaddr=getword(); - if (cpu_rm&4) FETCHADD(9); - else FETCHADD(11+slowrm[cpu_rm]); - break; - } - cpu_state.eaaddr+=(*mod1add[0][cpu_rm])+(*mod1add[1][cpu_rm]); - easeg=*mod1seg[cpu_rm]; - cpu_state.eaaddr&=0xFFFF; - } - - cpu_state.last_ea = cpu_state.eaaddr; -} - -static __inline uint8_t geteab() -{ - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; - return readmemb(easeg+cpu_state.eaaddr); -} - -static __inline uint16_t geteaw() -{ - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - return readmemw(easeg,cpu_state.eaaddr); -} - -#if 0 -static __inline uint16_t geteaw2() -{ - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - return readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); -} -#endif - -static __inline void seteab(uint8_t val) -{ - if (cpu_mod == 3) - { - if (cpu_rm & 4) - cpu_state.regs[cpu_rm & 3].b.h = val; - else - cpu_state.regs[cpu_rm & 3].b.l = val; - } - else - { - writememb(easeg+cpu_state.eaaddr,val); - } -} - -static __inline void seteaw(uint16_t val) -{ - if (cpu_mod == 3) - cpu_state.regs[cpu_rm].w = val; - else - { - writememw(easeg,cpu_state.eaaddr,val); - } -} - -#undef getr8 -#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) - -#undef setr8 -#define setr8(r,v) if (r & 4) cpu_state.regs[r & 3].b.h = v; \ - else cpu_state.regs[r & 3].b.l = v; - - -/*Flags*/ -uint8_t znptable8[256]; -uint16_t znptable16[65536]; - -void makeznptable() -{ - int c,d; - for (c=0;c<256;c++) - { - d=0; - if (c&1) d++; - if (c&2) d++; - if (c&4) d++; - if (c&8) d++; - if (c&16) d++; - if (c&32) d++; - if (c&64) d++; - if (c&128) d++; - if (d&1) - { - znptable8[c]=0; - } - else - { - znptable8[c]=P_FLAG; - } - if (c == 0xb1) x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); - if (!c) znptable8[c]|=Z_FLAG; - if (c&0x80) znptable8[c]|=N_FLAG; - } - for (c=0;c<65536;c++) - { - d=0; - if (c&1) d++; - if (c&2) d++; - if (c&4) d++; - if (c&8) d++; - if (c&16) d++; - if (c&32) d++; - if (c&64) d++; - if (c&128) d++; - if (d&1) - znptable16[c]=0; - else - znptable16[c]=P_FLAG; - if (c == 0xb1) x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); - if (!c) znptable16[c]|=Z_FLAG; - if (c&0x8000) znptable16[c]|=N_FLAG; - } -} -#if 1 -/* Also in mem.c */ -int timetolive=0; -#endif - -extern uint32_t oldcs2; -extern uint32_t oldpc2; - -int indump = 0; - -void dumpregs(int force) -{ - int c,d=0,e=0; -#ifndef RELEASE_BUILD - FILE *f; -#endif - - /* Only dump when needed, and only once.. */ - if (indump || (!force && !dump_on_exit)) return; - -#ifndef RELEASE_BUILD - indump = 1; - output=0; - (void)plat_chdir(usr_path); - nopageerrors=1; - f=fopen("ram.dmp","wb"); - fwrite(ram,mem_size*1024,1,f); - fclose(f); - x808x_log("Dumping rram.dmp\n"); - f=fopen("rram.dmp","wb"); - for (c=0;c<0x1000000;c++) putc(readmemb(c),f); - fclose(f); - x808x_log("Dumping rram4.dmp\n"); - f=fopen("rram4.dmp","wb"); - for (c=0;c<0x0050000;c++) - { - cpu_state.abrt = 0; - putc(readmemb386l(0,c+0x80000000),f); - } - fclose(f); - x808x_log("Dumping done\n"); -#endif - if (is386) - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP); - else - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP); - x808x_log("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags); - x808x_log("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2); - x808x_log("%i ins\n",ins); - if (is386) - x808x_log("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); - else - x808x_log("In %s mode\n",(msw&1)?"protected":"real"); - x808x_log("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high); - x808x_log("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high); - x808x_log("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high); - if (is386) - { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high); - } - x808x_log("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n",idt.base,idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - if (is386) - { - x808x_log("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit"); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4); - } - x808x_log("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum); - for (c=0;c<1024*1024;c++) - { - if (readlookup2[c]!=0xFFFFFFFF) d++; - if (writelookup2[c]!=0xFFFFFFFF) e++; - } - x808x_log("Entries in readlookup : %i writelookup : %i\n",d,e); - x87_dumpregs(); - indump = 0; -} - -int resets = 0; -int x86_was_reset = 0; -void resetx86() -{ - x808x_log("x86 reset\n"); - resets++; - ins = 0; - use32=0; - cpu_cur_status = 0; - stack32=0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw=0; - if (is486) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - eflags=0; - cgate32=0; - if(AT) - { - loadcs(0xF000); - cpu_state.pc=0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } - else - { - loadcs(0xFFFF); - cpu_state.pc=0; - rammask = 0xfffff; - } - idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; - flags=2; - makeznptable(); - resetreadlookup(); - makemod1table(); - resetmcr(); - FETCHCLEAR(); - x87_reset(); - cpu_set_edx(); - EAX = 0; - ESP=0; - mmu_perm=4; - memset(inscounts, 0, sizeof(inscounts)); - x86seg_reset(); -#ifdef USE_DYNAREC - codegen_reset(); -#endif - x86_was_reset = 1; - port_92_clear_reset(); -} - -void softresetx86() -{ - use32=0; - stack32=0; - cpu_cur_status = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw=0; - if (is486) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - eflags=0; - cgate32=0; - if(AT) - { - loadcs(0xF000); - cpu_state.pc=0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } - else - { - loadcs(0xFFFF); - cpu_state.pc=0; - rammask = 0xfffff; - } - flags=2; - idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; - x86seg_reset(); - x86_was_reset = 1; - port_92_clear_reset(); -} - -static void setznp8(uint8_t val) -{ - flags&=~0xC4; - flags|=znptable8[val]; -} - -static void setznp16(uint16_t val) -{ - flags&=~0xC4; - flags|=znptable16[val]; -} - -static void setadd8(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static void setadd8nc(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b; - flags&=~0x8D4; - flags|=znptable8[c&0xFF]; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static void setadc8(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static void setadd16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static void setadd16nc(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b; - flags&=~0x8D4; - flags|=znptable16[c&0xFFFF]; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static void setadc16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} - -static void setsub8(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a-(uint16_t)b; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static void setsub8nc(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a-(uint16_t)b; - flags&=~0x8D4; - flags|=znptable8[c&0xFF]; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static void setsbc8(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static void setsub16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a-(uint32_t)b; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static void setsub16nc(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a-(uint32_t)b; - flags&=~0x8D4; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static void setsbc16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); - flags&=~0x8D5; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if (c&0x10000) flags|=C_FLAG; - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} - -int current_diff = 0; -void clockhardware() -{ - int diff = cycdiff - cycles - current_diff; - - current_diff += diff; - - timer_end_period(cycles*xt_cpu_multi); -} - -static int takeint = 0; - - -int firstrepcycle=1; - -void rep(int fv) -{ - uint8_t temp = 0; - int c=CX; - uint8_t temp2; - uint16_t tempw,tempw2; - uint16_t ipc=cpu_state.oldpc; - int changeds=0; - uint32_t oldds = 0; - startrep: - temp=FETCH(); - - switch (temp) - { - case 0x08: - cpu_state.pc=ipc+1; - cycles-=2; - FETCHCLEAR(); - break; - case 0x26: /*ES:*/ - oldds=ds; - ds=es; - changeds=1; - cycles-=2; - goto startrep; - break; - case 0x2E: /*CS:*/ - oldds=ds; - ds=cs; - changeds=1; - cycles-=2; - goto startrep; - break; - case 0x36: /*SS:*/ - oldds=ds; - ds=ss; - changeds=1; - cycles-=2; - goto startrep; - break; - case 0x6E: /*REP OUTSB*/ - if (c>0) - { - temp2=readmemb(ds+SI); - outb(DX,temp2); - if (flags&D_FLAG) SI--; - else SI++; - c--; - cycles-=5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } - else firstrepcycle=1; - break; - case 0xA4: /*REP MOVSB*/ - while (c>0 && !IRQTEST) - { - temp2=readmemb(ds+SI); - writememb(es+DI,temp2); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - c--; - cycles-=17; - clockhardware(); - FETCHADD(17-memcycs); - } - if (IRQTEST && c>0) cpu_state.pc=ipc; - break; - case 0xA5: /*REP MOVSW*/ - while (c>0 && !IRQTEST) - { - memcycs=0; - tempw=readmemw(ds,SI); - writememw(es,DI,tempw); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } - c--; - cycles-=17; - clockhardware(); - FETCHADD(17 - memcycs); - } - if (IRQTEST && c>0) cpu_state.pc=ipc; - break; - case 0xA6: /*REP CMPSB*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) - { - memcycs=0; - temp=readmemb(ds+SI); - temp2=readmemb(es+DI); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - c--; - cycles -= 30; - setsub8(temp,temp2); - clockhardware(); - FETCHADD(30 - memcycs); - } - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; - break; - case 0xA7: /*REP CMPSW*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) - { - memcycs=0; - tempw=readmemw(ds,SI); - tempw2=readmemw(es,DI); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } - c--; - cycles -= 30; - setsub16(tempw,tempw2); - clockhardware(); - FETCHADD(30 - memcycs); - } - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; - break; - case 0xAA: /*REP STOSB*/ - while (c>0 && !IRQTEST) - { - memcycs=0; - writememb(es+DI,AL); - if (flags&D_FLAG) DI--; - else DI++; - c--; - cycles -= 10; - clockhardware(); - FETCHADD(10 - memcycs); - } - if (IRQTEST && c>0) cpu_state.pc=ipc; - break; - case 0xAB: /*REP STOSW*/ - while (c>0 && !IRQTEST) - { - memcycs=0; - writememw(es,DI,AX); - if (flags&D_FLAG) DI-=2; - else DI+=2; - c--; - cycles -= 10; - clockhardware(); - FETCHADD(10 - memcycs); - } - if (IRQTEST && c>0) cpu_state.pc=ipc; - break; - case 0xAC: /*REP LODSB*/ - if (c>0) - { - temp2=readmemb(ds+SI); - if (flags&D_FLAG) SI--; - else SI++; - c--; - cycles-=4; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } - else firstrepcycle=1; - break; - case 0xAD: /*REP LODSW*/ - if (c>0) - { - tempw2=readmemw(ds,SI); - if (flags&D_FLAG) SI-=2; - else SI+=2; - c--; - cycles-=4; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } - else firstrepcycle=1; - break; - case 0xAE: /*REP SCASB*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) - { - temp2=readmemb(es+DI); - setsub8(AL,temp2); - if (flags&D_FLAG) DI--; - else DI++; - c--; - cycles -= 15; - } - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { cpu_state.pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } - else firstrepcycle=1; - break; - case 0xAF: /*REP SCASW*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) - { - tempw=readmemw(es,DI); - setsub16(AX,tempw); - if (flags&D_FLAG) DI-=2; - else DI+=2; - c--; - cycles -= 15; - } - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { cpu_state.pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } - else firstrepcycle=1; - break; - default: - cpu_state.pc = ipc+1; - cycles-=20; - FETCHCLEAR(); - } - CX=c; - if (changeds) ds=oldds; - if (IRQTEST) - takeint = 1; -} - - -int inhlt=0; -uint16_t lastpc,lastcs; -int firstrepcycle; -int skipnextprint=0; - -int instime=0; -void execx86(int cycs) -{ - uint8_t temp = 0,temp2; - uint16_t addr,tempw,tempw2,tempw3,tempw4; - int8_t offset; - int tempws; - uint32_t templ; - unsigned int c; - int tempi; - int trap; - - cycles+=cycs; - while (cycles>0) - { - cycdiff=cycles; - timer_start_period(cycles*xt_cpu_multi); - current_diff = 0; - cycles-=nextcyc; - nextcyc=0; - fetchclocks=0; - oldcs=CS; - cpu_state.oldpc=cpu_state.pc; - opcodestart: - opcode=FETCH(); - tempc=flags&C_FLAG; - trap=flags&T_FLAG; - cpu_state.pc--; - if (output) - { - if (!skipnextprint) x808x_log("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]); - skipnextprint=0; - } - cpu_state.pc++; - inhlt=0; - switch (opcode) - { - case 0x00: /*ADD 8,reg*/ - fetchea(); - temp=geteab(); - setadd8(temp,getr8(cpu_reg)); - temp+=getr8(cpu_reg); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x01: /*ADD 16,reg*/ - fetchea(); - tempw=geteaw(); - setadd16(tempw, cpu_state.regs[cpu_reg].w); - tempw += cpu_state.regs[cpu_reg].w; - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x02: /*ADD cpu_reg,8*/ - fetchea(); - temp=geteab(); - setadd8(getr8(cpu_reg),temp); - setr8(cpu_reg,getr8(cpu_reg)+temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x03: /*ADD cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - setadd16(cpu_state.regs[cpu_reg].w,tempw); - cpu_state.regs[cpu_reg].w+=tempw; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x04: /*ADD AL,#8*/ - temp=FETCH(); - setadd8(AL,temp); - AL+=temp; - cycles-=4; - break; - case 0x05: /*ADD AX,#16*/ - tempw=getword(); - setadd16(AX,tempw); - AX+=tempw; - cycles-=4; - break; - - case 0x06: /*PUSH ES*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),ES); - SP-=2; - cpu_state.last_ea = SP; - cycles-=14; - break; - case 0x07: /*POP ES*/ - if (cpu_state.ssegs) ss=oldss; - tempw=readmemw(ss,SP); - loadseg(tempw,&_es); - SP+=2; - cpu_state.last_ea = SP; - cycles-=12; - break; - - case 0x08: /*OR 8,reg*/ - fetchea(); - temp=geteab(); - temp|=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x09: /*OR 16,reg*/ - fetchea(); - tempw=geteaw(); - tempw|=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x0A: /*OR cpu_reg,8*/ - fetchea(); - temp=geteab(); - temp|=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - setr8(cpu_reg,temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x0B: /*OR reg,16*/ - fetchea(); - tempw=geteaw(); - tempw|=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cpu_state.regs[cpu_reg].w=tempw; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x0C: /*OR AL,#8*/ - AL|=FETCH(); - setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - case 0x0D: /*OR AX,#16*/ - AX|=getword(); - setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - - case 0x0E: /*PUSH CS*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),CS); - SP-=2; - cpu_state.last_ea = SP; - cycles-=14; - break; - case 0x0F: /*POP CS - 8088/8086 only*/ - if (cpu_state.ssegs) ss=oldss; - tempw=readmemw(ss,SP); - loadseg(tempw,&_cs); - SP+=2; - cpu_state.last_ea = SP; - cycles-=12; - break; - - case 0x10: /*ADC 8,reg*/ - fetchea(); - temp=geteab(); - temp2=getr8(cpu_reg); - setadc8(temp,temp2); - temp+=temp2+tempc; - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x11: /*ADC 16,reg*/ - fetchea(); - tempw=geteaw(); - tempw2=cpu_state.regs[cpu_reg].w; - setadc16(tempw,tempw2); - tempw+=tempw2+tempc; - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x12: /*ADC cpu_reg,8*/ - fetchea(); - temp=geteab(); - setadc8(getr8(cpu_reg),temp); - setr8(cpu_reg,getr8(cpu_reg)+temp+tempc); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x13: /*ADC cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - setadc16(cpu_state.regs[cpu_reg].w,tempw); - cpu_state.regs[cpu_reg].w+=tempw+tempc; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x14: /*ADC AL,#8*/ - tempw=FETCH(); - setadc8(AL,tempw & 0xff); - AL+=tempw+tempc; - cycles-=4; - break; - case 0x15: /*ADC AX,#16*/ - tempw=getword(); - setadc16(AX,tempw); - AX+=tempw+tempc; - cycles-=4; - break; - - case 0x16: /*PUSH SS*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),SS); - SP-=2; - cycles-=14; - cpu_state.last_ea = SP; - break; - case 0x17: /*POP SS*/ - if (cpu_state.ssegs) ss=oldss; - tempw=readmemw(ss,SP); - loadseg(tempw,&_ss); - SP+=2; - cpu_state.last_ea = SP; - noint=1; - cycles-=12; - break; - - case 0x18: /*SBB 8,reg*/ - fetchea(); - temp=geteab(); - temp2=getr8(cpu_reg); - setsbc8(temp,temp2); - temp-=(temp2+tempc); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x19: /*SBB 16,reg*/ - fetchea(); - tempw=geteaw(); - tempw2=cpu_state.regs[cpu_reg].w; - setsbc16(tempw,tempw2); - tempw-=(tempw2+tempc); - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x1A: /*SBB cpu_reg,8*/ - fetchea(); - temp=geteab(); - setsbc8(getr8(cpu_reg),temp); - setr8(cpu_reg,getr8(cpu_reg)-(temp+tempc)); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x1B: /*SBB cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - tempw2=cpu_state.regs[cpu_reg].w; - setsbc16(tempw2,tempw); - tempw2-=(tempw+tempc); - cpu_state.regs[cpu_reg].w=tempw2; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x1C: /*SBB AL,#8*/ - temp=FETCH(); - setsbc8(AL,temp); - AL-=(temp+tempc); - cycles-=4; - break; - case 0x1D: /*SBB AX,#16*/ - tempw=getword(); - setsbc16(AX,tempw); - AX-=(tempw+tempc); - cycles-=4; - break; - - case 0x1E: /*PUSH DS*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),DS); - SP-=2; - cpu_state.last_ea = SP; - cycles-=14; - break; - case 0x1F: /*POP DS*/ - if (cpu_state.ssegs) ss=oldss; - tempw=readmemw(ss,SP); - loadseg(tempw,&_ds); - if (cpu_state.ssegs) oldds=ds; - SP+=2; - cpu_state.last_ea = SP; - cycles-=12; - break; - - case 0x20: /*AND 8,reg*/ - fetchea(); - temp=geteab(); - temp&=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x21: /*AND 16,reg*/ - fetchea(); - tempw=geteaw(); - tempw&=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x22: /*AND cpu_reg,8*/ - fetchea(); - temp=geteab(); - temp&=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - setr8(cpu_reg,temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x23: /*AND cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - tempw&=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cpu_state.regs[cpu_reg].w=tempw; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x24: /*AND AL,#8*/ - AL&=FETCH(); - setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - case 0x25: /*AND AX,#16*/ - AX&=getword(); - setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - - case 0x26: /*ES:*/ - oldss=ss; - oldds=ds; - ds=ss=es; - cpu_state.ssegs=2; - cycles-=4; - goto opcodestart; - - case 0x27: /*DAA*/ - if ((flags&A_FLAG) || ((AL&0xF)>9)) - { - tempi=((uint16_t)AL)+6; - AL+=6; - flags|=A_FLAG; - if (tempi&0x100) flags|=C_FLAG; - } - if ((flags&C_FLAG) || (AL>0x9F)) - { - AL+=0x60; - flags|=C_FLAG; - } - setznp8(AL); - cycles-=4; - break; - - case 0x28: /*SUB 8,reg*/ - fetchea(); - temp=geteab(); - setsub8(temp,getr8(cpu_reg)); - temp-=getr8(cpu_reg); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x29: /*SUB 16,reg*/ - fetchea(); - tempw=geteaw(); - setsub16(tempw,cpu_state.regs[cpu_reg].w); - tempw-=cpu_state.regs[cpu_reg].w; - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x2A: /*SUB cpu_reg,8*/ - fetchea(); - temp=geteab(); - setsub8(getr8(cpu_reg),temp); - setr8(cpu_reg,getr8(cpu_reg)-temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x2B: /*SUB cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - setsub16(cpu_state.regs[cpu_reg].w,tempw); - cpu_state.regs[cpu_reg].w-=tempw; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x2C: /*SUB AL,#8*/ - temp=FETCH(); - setsub8(AL,temp); - AL-=temp; - cycles-=4; - break; - case 0x2D: /*SUB AX,#16*/ - tempw=getword(); - setsub16(AX,tempw); - AX-=tempw; - cycles-=4; - break; - case 0x2E: /*CS:*/ - oldss=ss; - oldds=ds; - ds=ss=cs; - cpu_state.ssegs=2; - cycles-=4; - goto opcodestart; - case 0x2F: /*DAS*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) - { - tempi=((uint16_t)AL)-6; - AL-=6; - flags|=A_FLAG; - if (tempi&0x100) flags|=C_FLAG; - } - if ((flags&C_FLAG)||(AL>0x9F)) - { - AL-=0x60; - flags|=C_FLAG; - } - setznp8(AL); - cycles-=4; - break; - case 0x30: /*XOR 8,reg*/ - fetchea(); - temp=geteab(); - temp^=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x31: /*XOR 16,reg*/ - fetchea(); - tempw=geteaw(); - tempw^=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x32: /*XOR cpu_reg,8*/ - fetchea(); - temp=geteab(); - temp^=getr8(cpu_reg); - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - setr8(cpu_reg,temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x33: /*XOR cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - tempw^=cpu_state.regs[cpu_reg].w; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cpu_state.regs[cpu_reg].w=tempw; - cycles-=((cpu_mod==3)?3:13); - break; - case 0x34: /*XOR AL,#8*/ - AL^=FETCH(); - setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - case 0x35: /*XOR AX,#16*/ - AX^=getword(); - setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=4; - break; - - case 0x36: /*SS:*/ - oldss=ss; - oldds=ds; - ds=ss=ss; - cpu_state.ssegs=2; - cycles-=4; - goto opcodestart; - - case 0x37: /*AAA*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) - { - AL+=6; - AH++; - flags|=(A_FLAG|C_FLAG); - } - else - flags&=~(A_FLAG|C_FLAG); - AL&=0xF; - cycles-=8; - break; - - case 0x38: /*CMP 8,reg*/ - fetchea(); - temp=geteab(); - setsub8(temp,getr8(cpu_reg)); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x39: /*CMP 16,reg*/ - fetchea(); - tempw=geteaw(); - setsub16(tempw,cpu_state.regs[cpu_reg].w); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x3A: /*CMP cpu_reg,8*/ - fetchea(); - temp=geteab(); - setsub8(getr8(cpu_reg),temp); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x3B: /*CMP cpu_reg,16*/ - fetchea(); - tempw=geteaw(); - setsub16(cpu_state.regs[cpu_reg].w,tempw); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x3C: /*CMP AL,#8*/ - temp=FETCH(); - setsub8(AL,temp); - cycles-=4; - break; - case 0x3D: /*CMP AX,#16*/ - tempw=getword(); - setsub16(AX,tempw); - cycles-=4; - break; - - case 0x3E: /*DS:*/ - oldss=ss; - oldds=ds; - ds=ss=ds; - cpu_state.ssegs=2; - cycles-=4; - goto opcodestart; - - case 0x3F: /*AAS*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) - { - AL-=6; - AH--; - flags|=(A_FLAG|C_FLAG); - } - else - flags&=~(A_FLAG|C_FLAG); - AL&=0xF; - cycles-=8; - break; - - case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ - case 0x44: case 0x45: case 0x46: case 0x47: - setadd16nc(cpu_state.regs[opcode&7].w,1); - cpu_state.regs[opcode&7].w++; - cycles-=3; - break; - case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/ - case 0x4C: case 0x4D: case 0x4E: case 0x4F: - setsub16nc(cpu_state.regs[opcode&7].w,1); - cpu_state.regs[opcode&7].w--; - cycles-=3; - break; - - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ - case 0x54: case 0x55: case 0x56: case 0x57: - if (cpu_state.ssegs) ss=oldss; - SP-=2; - cpu_state.last_ea = SP; - writememw(ss,SP,cpu_state.regs[opcode&7].w); - cycles-=15; - break; - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ - case 0x5C: case 0x5D: case 0x5E: case 0x5F: - if (cpu_state.ssegs) ss=oldss; - SP+=2; - cpu_state.last_ea = SP; - cpu_state.regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF); - cycles-=12; - break; - - - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - offset=(int8_t)FETCH(); - if (flags&V_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x61: /*JNO alias*/ - case 0x71: /*JNO*/ - offset=(int8_t)FETCH(); - if (!(flags&V_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x62: /*JB alias*/ - case 0x72: /*JB*/ - offset=(int8_t)FETCH(); - if (flags&C_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x63: /*JNB alias*/ - case 0x73: /*JNB*/ - offset=(int8_t)FETCH(); - if (!(flags&C_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x64: /*JE alias*/ - case 0x74: /*JE*/ - offset=(int8_t)FETCH(); - if (flags&Z_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x65: /*JNE alias*/ - case 0x75: /*JNE*/ - offset=(int8_t)FETCH(); - cycles-=4; - if (!(flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - break; - case 0x66: /*JBE alias*/ - case 0x76: /*JBE*/ - offset=(int8_t)FETCH(); - if (flags&(C_FLAG|Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x67: /*JNBE alias*/ - case 0x77: /*JNBE*/ - offset=(int8_t)FETCH(); - if (!(flags&(C_FLAG|Z_FLAG))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x68: /*JS alias*/ - case 0x78: /*JS*/ - offset=(int8_t)FETCH(); - if (flags&N_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x69: /*JNS alias*/ - case 0x79: /*JNS*/ - offset=(int8_t)FETCH(); - if (!(flags&N_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - offset=(int8_t)FETCH(); - if (flags&P_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6B: /*JNP alias*/ - case 0x7B: /*JNP*/ - offset=(int8_t)FETCH(); - if (!(flags&P_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6C: /*JL alias*/ - case 0x7C: /*JL*/ - offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if (temp!=temp2) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6D: /*JNL alias*/ - case 0x7D: /*JNL*/ - offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if (temp==temp2) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6E: /*JLE alias*/ - case 0x7E: /*JLE*/ - offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if ((flags&Z_FLAG) || (temp!=temp2)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - case 0x6F: /*JNLE alias*/ - case 0x7F: /*JNLE*/ - offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if (!((flags&Z_FLAG) || (temp!=temp2))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=4; - break; - - case 0x80: case 0x82: - fetchea(); - temp=geteab(); - temp2=FETCH(); - switch (rmdat&0x38) - { - case 0x00: /*ADD b,#8*/ - setadd8(temp,temp2); - seteab(temp+temp2); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x08: /*OR b,#8*/ - temp|=temp2; - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x10: /*ADC b,#8*/ - setadc8(temp,temp2); - seteab(temp+temp2+tempc); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x18: /*SBB b,#8*/ - setsbc8(temp,temp2); - seteab(temp-(temp2+tempc)); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x20: /*AND b,#8*/ - temp&=temp2; - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x28: /*SUB b,#8*/ - setsub8(temp,temp2); - seteab(temp-temp2); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x30: /*XOR b,#8*/ - temp^=temp2; - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteab(temp); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x38: /*CMP b,#8*/ - setsub8(temp,temp2); - cycles-=((cpu_mod==3)?4:14); - break; - } - break; - - case 0x81: - fetchea(); - tempw=geteaw(); - tempw2=getword(); - switch (rmdat&0x38) - { - case 0x00: /*ADD w,#16*/ - setadd16(tempw,tempw2); - tempw+=tempw2; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x08: /*OR w,#16*/ - tempw|=tempw2; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x10: /*ADC w,#16*/ - setadc16(tempw,tempw2); - tempw+=tempw2+tempc; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x20: /*AND w,#16*/ - tempw&=tempw2; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x18: /*SBB w,#16*/ - setsbc16(tempw,tempw2); - seteaw(tempw-(tempw2+tempc)); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x28: /*SUB w,#16*/ - setsub16(tempw,tempw2); - tempw-=tempw2; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x30: /*XOR w,#16*/ - tempw^=tempw2; - setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x38: /*CMP w,#16*/ - setsub16(tempw,tempw2); - cycles-=((cpu_mod==3)?4:14); - break; - } - break; - - case 0x83: - fetchea(); - tempw=geteaw(); - tempw2=FETCH(); - if (tempw2&0x80) tempw2|=0xFF00; - switch (rmdat&0x38) - { - case 0x00: /*ADD w,#8*/ - setadd16(tempw,tempw2); - tempw+=tempw2; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x08: /*OR w,#8*/ - tempw|=tempw2; - setznp16(tempw); - seteaw(tempw); - flags&=~(C_FLAG|A_FLAG|V_FLAG); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x10: /*ADC w,#8*/ - setadc16(tempw,tempw2); - tempw+=tempw2+tempc; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x18: /*SBB w,#8*/ - setsbc16(tempw,tempw2); - tempw-=(tempw2+tempc); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x20: /*AND w,#8*/ - tempw&=tempw2; - setznp16(tempw); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - flags&=~(C_FLAG|A_FLAG|V_FLAG); - break; - case 0x28: /*SUB w,#8*/ - setsub16(tempw,tempw2); - tempw-=tempw2; - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - break; - case 0x30: /*XOR w,#8*/ - tempw^=tempw2; - setznp16(tempw); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:23); - flags&=~(C_FLAG|A_FLAG|V_FLAG); - break; - case 0x38: /*CMP w,#8*/ - setsub16(tempw,tempw2); - cycles-=((cpu_mod==3)?4:14); - break; - } - break; - - case 0x84: /*TEST b,reg*/ - fetchea(); - temp=geteab(); - temp2=getr8(cpu_reg); - setznp8(temp&temp2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x85: /*TEST w,reg*/ - fetchea(); - tempw=geteaw(); - tempw2=cpu_state.regs[cpu_reg].w; - setznp16(tempw&tempw2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=((cpu_mod==3)?3:13); - break; - case 0x86: /*XCHG b,reg*/ - fetchea(); - temp=geteab(); - seteab(getr8(cpu_reg)); - setr8(cpu_reg,temp); - cycles-=((cpu_mod==3)?4:25); - break; - case 0x87: /*XCHG w,reg*/ - fetchea(); - tempw=geteaw(); - seteaw(cpu_state.regs[cpu_reg].w); - cpu_state.regs[cpu_reg].w=tempw; - cycles-=((cpu_mod==3)?4:25); - break; - - case 0x88: /*MOV b,reg*/ - fetchea(); - seteab(getr8(cpu_reg)); - cycles-=((cpu_mod==3)?2:13); - break; - case 0x89: /*MOV w,reg*/ - fetchea(); - seteaw(cpu_state.regs[cpu_reg].w); - cycles-=((cpu_mod==3)?2:13); - break; - case 0x8A: /*MOV cpu_reg,b*/ - fetchea(); - temp=geteab(); - setr8(cpu_reg,temp); - cycles-=((cpu_mod==3)?2:12); - break; - case 0x8B: /*MOV cpu_reg,w*/ - fetchea(); - tempw=geteaw(); - cpu_state.regs[cpu_reg].w=tempw; - cycles-=((cpu_mod==3)?2:12); - break; - - case 0x8C: /*MOV w,sreg*/ - fetchea(); - switch (rmdat&0x38) - { - case 0x00: /*ES*/ - seteaw(ES); - break; - case 0x08: /*CS*/ - seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_state.ssegs) ds=oldds; - seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_state.ssegs) ss=oldss; - seteaw(SS); - break; - } - cycles-=((cpu_mod==3)?2:13); - break; - - case 0x8D: /*LEA*/ - fetchea(); - cpu_state.regs[cpu_reg].w=(cpu_mod == 3)?cpu_state.last_ea:cpu_state.eaaddr; - cycles-=2; - break; - - case 0x8E: /*MOV sreg,w*/ - fetchea(); - switch (rmdat&0x38) - { - case 0x00: /*ES*/ - tempw=geteaw(); - loadseg(tempw,&_es); - break; - case 0x08: /*CS - 8088/8086 only*/ - tempw=geteaw(); - loadseg(tempw,&_cs); - break; - case 0x18: /*DS*/ - tempw=geteaw(); - loadseg(tempw,&_ds); - if (cpu_state.ssegs) oldds=ds; - break; - case 0x10: /*SS*/ - tempw=geteaw(); - loadseg(tempw,&_ss); - if (cpu_state.ssegs) oldss=ss; - break; - } - cycles-=((cpu_mod==3)?2:12); - skipnextprint=1; - noint=1; - break; - - case 0x8F: /*POPW*/ - fetchea(); - if (cpu_state.ssegs) ss=oldss; - tempw=readmemw(ss,SP); - SP+=2; - cpu_state.last_ea = SP; - seteaw(tempw); - cycles-=25; - break; - - case 0x90: /*NOP*/ - cycles-=3; - break; - - case 0x91: case 0x92: case 0x93: /*XCHG AX*/ - case 0x94: case 0x95: case 0x96: case 0x97: - tempw=AX; - AX=cpu_state.regs[opcode&7].w; - cpu_state.regs[opcode&7].w=tempw; - cycles-=3; - break; - - case 0x98: /*CBW*/ - AH=(AL&0x80)?0xFF:0; - cycles-=2; - break; - case 0x99: /*CWD*/ - DX=(AX&0x8000)?0xFFFF:0; - cycles-=5; - break; - case 0x9A: /*CALL FAR*/ - tempw=getword(); - tempw2=getword(); - tempw3=CS; - tempw4=cpu_state.pc; - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=tempw; - loadcs(tempw2); - writememw(ss,(SP-2)&0xFFFF,tempw3); - writememw(ss,(SP-4)&0xFFFF,tempw4); - SP-=4; - cpu_state.last_ea = SP; - cycles-=36; - FETCHCLEAR(); - break; - case 0x9B: /*WAIT*/ - cycles-=4; - break; - case 0x9C: /*PUSHF*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); - SP-=2; - cpu_state.last_ea = SP; - cycles-=14; - break; - case 0x9D: /*POPF*/ - if (cpu_state.ssegs) ss=oldss; - flags=readmemw(ss,SP)&0xFFF; - SP+=2; - cpu_state.last_ea = SP; - cycles-=12; - break; - case 0x9E: /*SAHF*/ - flags=(flags&0xFF00)|AH; - cycles-=4; - break; - case 0x9F: /*LAHF*/ - AH=flags&0xFF; - cycles-=4; - break; - - case 0xA0: /*MOV AL,(w)*/ - addr=getword(); - AL=readmemb(ds+addr); - cycles-=14; - break; - case 0xA1: /*MOV AX,(w)*/ - addr=getword(); - AX=readmemw(ds,addr); - cycles-=14; - break; - case 0xA2: /*MOV (w),AL*/ - addr=getword(); - writememb(ds+addr,AL); - cycles-=14; - break; - case 0xA3: /*MOV (w),AX*/ - addr=getword(); - writememw(ds,addr,AX); - cycles-=14; - break; - - case 0xA4: /*MOVSB*/ - temp=readmemb(ds+SI); - writememb(es+DI,temp); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - cycles-=18; - break; - case 0xA5: /*MOVSW*/ - tempw=readmemw(ds,SI); - writememw(es,DI,tempw); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } - cycles-=18; - break; - case 0xA6: /*CMPSB*/ - temp =readmemb(ds+SI); - temp2=readmemb(es+DI); - setsub8(temp,temp2); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - cycles-=30; - break; - case 0xA7: /*CMPSW*/ - tempw =readmemw(ds,SI); - tempw2=readmemw(es,DI); - setsub16(tempw,tempw2); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } - cycles-=30; - break; - case 0xA8: /*TEST AL,#8*/ - temp=FETCH(); - setznp8(AL&temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=5; - break; - case 0xA9: /*TEST AX,#16*/ - tempw=getword(); - setznp16(AX&tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=5; - break; - case 0xAA: /*STOSB*/ - writememb(es+DI,AL); - if (flags&D_FLAG) DI--; - else DI++; - cycles-=11; - break; - case 0xAB: /*STOSW*/ - writememw(es,DI,AX); - if (flags&D_FLAG) DI-=2; - else DI+=2; - cycles-=11; - break; - case 0xAC: /*LODSB*/ - AL=readmemb(ds+SI); - if (flags&D_FLAG) SI--; - else SI++; - cycles-=16; - break; - case 0xAD: /*LODSW*/ - AX=readmemw(ds,SI); - if (flags&D_FLAG) SI-=2; - else SI+=2; - cycles-=16; - break; - case 0xAE: /*SCASB*/ - temp=readmemb(es+DI); - setsub8(AL,temp); - if (flags&D_FLAG) DI--; - else DI++; - cycles-=19; - break; - case 0xAF: /*SCASW*/ - tempw=readmemw(es,DI); - setsub16(AX,tempw); - if (flags&D_FLAG) DI-=2; - else DI+=2; - cycles-=19; - break; - - case 0xB0: /*MOV AL,#8*/ - AL=FETCH(); - cycles-=4; - break; - case 0xB1: /*MOV CL,#8*/ - CL=FETCH(); - cycles-=4; - break; - case 0xB2: /*MOV DL,#8*/ - DL=FETCH(); - cycles-=4; - break; - case 0xB3: /*MOV BL,#8*/ - BL=FETCH(); - cycles-=4; - break; - case 0xB4: /*MOV AH,#8*/ - AH=FETCH(); - cycles-=4; - break; - case 0xB5: /*MOV CH,#8*/ - CH=FETCH(); - cycles-=4; - break; - case 0xB6: /*MOV DH,#8*/ - DH=FETCH(); - cycles-=4; - break; - case 0xB7: /*MOV BH,#8*/ - BH=FETCH(); - cycles-=4; - break; - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV cpu_reg,#16*/ - case 0xBC: case 0xBD: case 0xBE: case 0xBF: - cpu_state.regs[opcode&7].w=getword(); - cycles-=4; - break; - - case 0xC0: /*RET alias*/ - case 0xC2: /*RET*/ - tempw=getword(); - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=readmemw(ss,SP); - SP+=2+tempw; - cycles-=24; - FETCHCLEAR(); - break; - case 0xC1: /*RET alias*/ - case 0xC3: /*RET*/ - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=readmemw(ss,SP); - SP+=2; - cycles-=20; - FETCHCLEAR(); - break; - case 0xC4: /*LES*/ - fetchea(); - cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); - tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); - loadseg(tempw,&_es); - cycles-=24; - break; - case 0xC5: /*LDS*/ - fetchea(); - cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); - tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); - loadseg(tempw,&_ds); - if (cpu_state.ssegs) oldds=ds; - cycles-=24; - break; - case 0xC6: /*MOV b,#8*/ - fetchea(); - temp=FETCH(); - seteab(temp); - cycles-=((cpu_mod==3)?4:14); - break; - case 0xC7: /*MOV w,#16*/ - fetchea(); - tempw=getword(); - seteaw(tempw); - cycles-=((cpu_mod==3)?4:14); - break; - - case 0xC8: /*RETF alias*/ - case 0xCA: /*RETF*/ - tempw=getword(); - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=readmemw(ss,SP); - loadcs(readmemw(ss,SP+2)); - SP+=4; - SP+=tempw; - cycles-=33; - FETCHCLEAR(); - break; - case 0xC9: /*RETF alias*/ - case 0xCB: /*RETF*/ - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=readmemw(ss,SP); - loadcs(readmemw(ss,SP+2)); - SP+=4; - cycles-=34; - FETCHCLEAR(); - break; - case 0xCC: /*INT 3*/ - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - addr=3<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - FETCHCLEAR(); - cycles-=72; - break; - case 0xCD: /*INT*/ - lastpc=cpu_state.pc; - lastcs=CS; - temp=FETCH(); - - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - flags&=~T_FLAG; - SP-=6; - addr=temp<<2; - cpu_state.pc=readmemw(0,addr); - - loadcs(readmemw(0,addr+2)); - FETCHCLEAR(); - - cycles-=71; - break; - case 0xCF: /*IRET*/ - if (cpu_state.ssegs) ss=oldss; - tempw=CS; - tempw2=cpu_state.pc; - cpu_state.pc=readmemw(ss,SP); - loadcs(readmemw(ss,((SP+2)&0xFFFF))); - flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF; - SP+=6; - cycles-=44; - FETCHCLEAR(); - nmi_enable = 1; - break; - case 0xD0: - fetchea(); - temp=geteab(); - switch (rmdat&0x38) - { - case 0x00: /*ROL b,1*/ - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - temp<<=1; - if (flags&C_FLAG) temp|=1; - seteab(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x08: /*ROR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; - temp>>=1; - if (flags&C_FLAG) temp|=0x80; - seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x10: /*RCL b,1*/ - temp2=flags&C_FLAG; - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - temp<<=1; - if (temp2) temp|=1; - seteab(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x18: /*RCR b,1*/ - temp2=flags&C_FLAG; - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; - temp>>=1; - if (temp2) temp|=0x80; - seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x20: case 0x30: /*SHL b,1*/ - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - if ((temp^(temp<<1))&0x80) flags|=V_FLAG; - else flags&=~V_FLAG; - temp<<=1; - seteab(temp); - setznp8(temp); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - break; - case 0x28: /*SHR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; - if (temp&0x80) flags|=V_FLAG; - else flags&=~V_FLAG; - temp>>=1; - seteab(temp); - setznp8(temp); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - break; - case 0x38: /*SAR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; - temp>>=1; - if (temp&0x40) temp|=0x80; - seteab(temp); - setznp8(temp); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - flags&=~V_FLAG; - break; - } - break; - - case 0xD1: - fetchea(); - tempw=geteaw(); - switch (rmdat&0x38) - { - case 0x00: /*ROL w,1*/ - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw<<=1; - if (flags&C_FLAG) tempw|=1; - seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x08: /*ROR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw>>=1; - if (flags&C_FLAG) tempw|=0x8000; - seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x10: /*RCL w,1*/ - temp2=flags&C_FLAG; - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw<<=1; - if (temp2) tempw|=1; - seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x18: /*RCR w,1*/ - temp2=flags&C_FLAG; - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw>>=1; - if (temp2) tempw|=0x8000; - seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?2:23); - break; - case 0x20: case 0x30: /*SHL w,1*/ - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; - else flags&=~V_FLAG; - tempw<<=1; - seteaw(tempw); - setznp16(tempw); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - break; - case 0x28: /*SHR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - if (tempw&0x8000) flags|=V_FLAG; - else flags&=~V_FLAG; - tempw>>=1; - seteaw(tempw); - setznp16(tempw); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - break; - - case 0x38: /*SAR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw>>=1; - if (tempw&0x4000) tempw|=0x8000; - seteaw(tempw); - setznp16(tempw); - cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - flags&=~V_FLAG; - break; - } - break; - - case 0xD2: - fetchea(); - temp=geteab(); - c=CL; - if (!c) break; - switch (rmdat&0x38) - { - case 0x00: /*ROL b,CL*/ - temp2=(temp&0x80)?1:0; - if (!c) - { - cycles-=((cpu_mod==3)?8:28); - break; - } - while (c>0) - { - temp2=(temp&0x80)?1:0; - temp=(temp<<1)|temp2; - c--; - cycles-=4; - } - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; - seteab(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x08: /*ROR b,CL*/ - temp2=temp&1; - if (!c) - { - cycles-=((cpu_mod==3)?8:28); - break; - } - while (c>0) - { - temp2=temp&1; - temp>>=1; - if (temp2) temp|=0x80; - c--; - cycles-=4; - } - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; - seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x10: /*RCL b,CL*/ - while (c>0) - { - templ=flags&C_FLAG; - temp2=temp&0x80; - temp<<=1; - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; - if (templ) temp|=1; - c--; - cycles-=4; - } - seteab(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x18: /*RCR b,CL*/ - while (c>0) - { - templ=flags&C_FLAG; - temp2=temp&1; - temp>>=1; - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; - if (templ) temp|=0x80; - c--; - cycles-=4; - } - seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x20: case 0x30: /*SHL b,CL*/ - if (c > 8) - { - temp = 0; - flags &= ~C_FLAG; - } - else - { - if ((temp<<(c-1))&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - temp<<=c; - } - seteab(temp); - setznp8(temp); - cycles-=(c*4); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - case 0x28: /*SHR b,CL*/ - if (c > 8) - { - temp = 0; - flags &= ~C_FLAG; - } - else - { - if ((temp>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - temp>>=c; - } - seteab(temp); - setznp8(temp); - cycles-=(c*4); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - case 0x38: /*SAR b,CL*/ - if ((temp>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - while (c>0) - { - temp>>=1; - if (temp&0x40) temp|=0x80; - c--; - cycles-=4; - } - seteab(temp); - setznp8(temp); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - } - break; - - case 0xD3: - fetchea(); - tempw=geteaw(); - c=CL; - if (!c) break; - switch (rmdat&0x38) - { - case 0x00: /*ROL w,CL*/ - while (c>0) - { - temp=(tempw&0x8000)?1:0; - tempw=(tempw<<1)|temp; - c--; - cycles-=4; - } - if (temp) flags|=C_FLAG; - else flags&=~C_FLAG; - seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x08: /*ROR w,CL*/ - tempw2=(tempw&1)?0x8000:0; - if (!c) - { - cycles-=((cpu_mod==3)?8:28); - break; - } - while (c>0) - { - tempw2=(tempw&1)?0x8000:0; - tempw=(tempw>>1)|tempw2; - c--; - cycles-=4; - } - if (tempw2) flags|=C_FLAG; - else flags&=~C_FLAG; - seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x10: /*RCL w,CL*/ - while (c>0) - { - templ=flags&C_FLAG; - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw=(tempw<<1)|templ; - c--; - cycles-=4; - } - if (temp) flags|=C_FLAG; - else flags&=~C_FLAG; - seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - case 0x18: /*RCR w,CL*/ - templ=flags&C_FLAG; - tempw2=(templ&1)?0x8000:0; - if (!c) - { - cycles-=((cpu_mod==3)?8:28); - break; - } - while (c>0) - { - templ=flags&C_FLAG; - tempw2=(templ&1)?0x8000:0; - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw=(tempw>>1)|tempw2; - c--; - cycles-=4; - } - if (tempw2) flags|=C_FLAG; - else flags&=~C_FLAG; - seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; - cycles-=((cpu_mod==3)?8:28); - break; - - case 0x20: case 0x30: /*SHL w,CL*/ - if (c>16) - { - tempw=0; - flags&=~C_FLAG; - } - else - { - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw<<=c; - } - seteaw(tempw); - setznp16(tempw); - cycles-=(c*4); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - - case 0x28: /*SHR w,CL*/ - if (c > 16) - { - tempw = 0; - flags &= ~C_FLAG; - } - else - { - if ((tempw>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw>>=c; - } - seteaw(tempw); - setznp16(tempw); - cycles-=(c*4); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - - case 0x38: /*SAR w,CL*/ - tempw2=tempw&0x8000; - if ((tempw>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - while (c>0) - { - tempw=(tempw>>1)|tempw2; - c--; - cycles-=4; - } - seteaw(tempw); - setznp16(tempw); - cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; - break; - } - break; - - case 0xD4: /*AAM*/ - tempws=FETCH(); - AH=AL/tempws; - AL%=tempws; - setznp16(AX); - cycles-=83; - break; - case 0xD5: /*AAD*/ - tempws=FETCH(); - AL=(AH*tempws)+AL; - AH=0; - setznp16(AX); - cycles-=60; - break; - case 0xD6: /*SETALC*/ - AL = (flags & C_FLAG) ? 0xff : 0; - cycles -= 4; - break; - case 0xD7: /*XLAT*/ - addr=BX+AL; - cpu_state.last_ea = addr; - AL=readmemb(ds+addr); - cycles-=11; - break; - case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ - case 0xDC: case 0xDE: case 0xDF: case 0xD8: - fetchea(); - geteab(); - break; - - case 0xE0: /*LOOPNE*/ - offset=(int8_t)FETCH(); - CX--; - if (CX && !(flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=6; - break; - case 0xE1: /*LOOPE*/ - offset=(int8_t)FETCH(); - CX--; - if (CX && (flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=6; - break; - case 0xE2: /*LOOP*/ - offset=(int8_t)FETCH(); - CX--; - if (CX) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=5; - break; - case 0xE3: /*JCXZ*/ - offset=(int8_t)FETCH(); - if (!CX) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } - cycles-=6; - break; - - case 0xE4: /*IN AL*/ - temp=FETCH(); - AL=inb(temp); - cycles-=14; - break; - case 0xE5: /*IN AX*/ - temp=FETCH(); - AL=inb(temp); - AH=inb(temp+1); - cycles-=14; - break; - case 0xE6: /*OUT AL*/ - temp=FETCH(); - outb(temp,AL); - cycles-=14; - break; - case 0xE7: /*OUT AX*/ - temp=FETCH(); - outb(temp,AL); - outb(temp+1,AH); - cycles-=14; - break; - - case 0xE8: /*CALL rel 16*/ - tempw=getword(); - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),cpu_state.pc); - SP-=2; - cpu_state.last_ea = SP; - cpu_state.pc+=tempw; - cycles-=23; - FETCHCLEAR(); - break; - case 0xE9: /*JMP rel 16*/ - tempw = getword(); - cpu_state.pc += tempw; - cycles-=15; - FETCHCLEAR(); - break; - case 0xEA: /*JMP far*/ - addr=getword(); - tempw=getword(); - cpu_state.pc=addr; - loadcs(tempw); - cycles-=15; - FETCHCLEAR(); - break; - case 0xEB: /*JMP rel*/ - offset=(int8_t)FETCH(); - cpu_state.pc+=offset; - cycles-=15; - FETCHCLEAR(); - break; - case 0xEC: /*IN AL,DX*/ - AL=inb(DX); - cycles-=12; - break; - case 0xED: /*IN AX,DX*/ - AL=inb(DX); - AH=inb(DX+1); - cycles-=12; - break; - case 0xEE: /*OUT DX,AL*/ - outb(DX,AL); - cycles-=12; - break; - case 0xEF: /*OUT DX,AX*/ - outb(DX,AL); - outb(DX+1,AH); - cycles-=12; - break; - - case 0xF0: /*LOCK*/ - case 0xF1: /*LOCK alias*/ - cycles-=4; - break; - - case 0xF2: /*REPNE*/ - rep(0); - break; - case 0xF3: /*REPE*/ - rep(1); - break; - - case 0xF4: /*HLT*/ - inhlt=1; - cpu_state.pc--; - FETCHCLEAR(); - cycles-=2; - break; - case 0xF5: /*CMC*/ - flags^=C_FLAG; - cycles-=2; - break; - - case 0xF6: - fetchea(); - temp=geteab(); - switch (rmdat&0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - temp2=FETCH(); - temp&=temp2; - setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=((cpu_mod==3)?5:11); - break; - case 0x10: /*NOT b*/ - temp=~temp; - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x18: /*NEG b*/ - setsub8(0,temp); - temp=0-temp; - seteab(temp); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x20: /*MUL AL,b*/ - setznp8(AL); - AX=AL*temp; - if (AX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (AH) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); - cycles-=70; - break; - case 0x28: /*IMUL AL,b*/ - setznp8(AL); - tempws=(int)((int8_t)AL)*(int)((int8_t)temp); - AX=tempws&0xFFFF; - if (AX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (AH) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); - cycles-=80; - break; - case 0x30: /*DIV AL,b*/ - tempw=AX; - if (temp) - { - tempw2=tempw%temp; - AH=tempw2 & 0xff; - tempw/=temp; - AL=tempw&0xFF; - } - else - { - x808x_log("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; - cpu_state.pc=readmemw(0,0); - loadcs(readmemw(0,2)); - FETCHCLEAR(); - } - cycles-=80; - break; - case 0x38: /*IDIV AL,b*/ - tempws=(int)AX; - if (temp) - { - tempw2=tempws%(int)((int8_t)temp); - AH=tempw2&0xFF; - tempws/=(int)((int8_t)temp); - AL=tempws&0xFF; - } - else - { - x808x_log("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; - cpu_state.pc=readmemw(0,0); - loadcs(readmemw(0,2)); - FETCHCLEAR(); - } - cycles-=101; - break; - } - break; - - case 0xF7: - fetchea(); - tempw=geteaw(); - switch (rmdat&0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - tempw2=getword(); - setznp16(tempw&tempw2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); - cycles-=((cpu_mod==3)?5:11); - break; - case 0x10: /*NOT w*/ - seteaw(~tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x18: /*NEG w*/ - setsub16(0,tempw); - tempw=0-tempw; - seteaw(tempw); - cycles-=((cpu_mod==3)?3:24); - break; - case 0x20: /*MUL AX,w*/ - setznp16(AX); - templ=AX*tempw; - AX=templ&0xFFFF; - DX=templ>>16; - if (AX|DX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (DX) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); - cycles-=118; - break; - case 0x28: /*IMUL AX,w*/ - setznp16(AX); - tempws=(int)((int16_t)AX)*(int)((int16_t)tempw); - if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); - AX=tempws&0xFFFF; - tempws=(uint16_t)(tempws>>16); - DX=tempws&0xFFFF; - if (AX|DX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - cycles-=128; - break; - case 0x30: /*DIV AX,w*/ - templ=(DX<<16)|AX; - if (tempw) - { - tempw2=templ%tempw; - DX=tempw2; - templ/=tempw; - AX=templ&0xFFFF; - } - else - { - x808x_log("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; - cpu_state.pc=readmemw(0,0); - loadcs(readmemw(0,2)); - FETCHCLEAR(); - } - cycles-=144; - break; - case 0x38: /*IDIV AX,w*/ - tempws=(int)((DX<<16)|AX); - if (tempw) - { - tempw2=tempws%(int)((int16_t)tempw); - DX=tempw2; - tempws/=(int)((int16_t)tempw); - AX=tempws&0xFFFF; - } - else - { - x808x_log("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; - cpu_state.pc=readmemw(0,0); - loadcs(readmemw(0,2)); - FETCHCLEAR(); - } - cycles-=165; - break; - } - break; - - case 0xF8: /*CLC*/ - flags&=~C_FLAG; - cycles-=2; - break; - case 0xF9: /*STC*/ - flags|=C_FLAG; - cycles-=2; - break; - case 0xFA: /*CLI*/ - flags&=~I_FLAG; - cycles-=3; - break; - case 0xFB: /*STI*/ - flags|=I_FLAG; - cycles-=2; - break; - case 0xFC: /*CLD*/ - flags&=~D_FLAG; - cycles-=2; - break; - case 0xFD: /*STD*/ - flags|=D_FLAG; - cycles-=2; - break; - - case 0xFE: /*INC/DEC b*/ - fetchea(); - temp=geteab(); - flags&=~V_FLAG; - if (rmdat&0x38) - { - setsub8nc(temp,1); - temp2=temp-1; - if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; - } - else - { - setadd8nc(temp,1); - temp2=temp+1; - if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; - } - seteab(temp2); - cycles-=((cpu_mod==3)?3:23); - break; - - case 0xFF: - fetchea(); - switch (rmdat&0x38) - { - case 0x00: /*INC w*/ - tempw=geteaw(); - setadd16nc(tempw,1); - seteaw(tempw+1); - cycles-=((cpu_mod==3)?3:23); - break; - case 0x08: /*DEC w*/ - tempw=geteaw(); - setsub16nc(tempw,1); - seteaw(tempw-1); - cycles-=((cpu_mod==3)?3:23); - break; - case 0x10: /*CALL*/ - tempw=geteaw(); - if (cpu_state.ssegs) ss=oldss; - writememw(ss,(SP-2)&0xFFFF,cpu_state.pc); - SP-=2; - cpu_state.last_ea = SP; - cpu_state.pc=tempw; - cycles-=((cpu_mod==3)?20:29); - FETCHCLEAR(); - break; - case 0x18: /*CALL far*/ - tempw=readmemw(easeg,cpu_state.eaaddr); - tempw2=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); - tempw3=CS; - tempw4=cpu_state.pc; - if (cpu_state.ssegs) ss=oldss; - cpu_state.pc=tempw; - loadcs(tempw2); - writememw(ss,(SP-2)&0xFFFF,tempw3); - writememw(ss,((SP-4)&0xFFFF),tempw4); - SP-=4; - cpu_state.last_ea = SP; - cycles-=53; - FETCHCLEAR(); - break; - case 0x20: /*JMP*/ - cpu_state.pc=geteaw(); - cycles-=((cpu_mod==3)?11:18); - FETCHCLEAR(); - break; - case 0x28: /*JMP far*/ - cpu_state.pc=readmemw(easeg,cpu_state.eaaddr); - loadcs(readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF)); - cycles-=24; - FETCHCLEAR(); - break; - case 0x30: /*PUSH w*/ - case 0x38: /*PUSH w alias, reported by reenigne*/ - tempw=geteaw(); - if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),tempw); - SP-=2; - cpu_state.last_ea = SP; - cycles-=((cpu_mod==3)?15:24); - break; - } - break; - - default: - FETCH(); - cycles-=8; - break; - } - cpu_state.pc&=0xFFFF; - - if (cpu_state.ssegs) - { - ds=oldds; - ss=oldss; - cpu_state.ssegs=0; - } - - FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks); - if ((cycdiff-cycles) -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "cpu.h" -#include "x86_ops.h" -#include "codegen.h" - -void (*codegen_timing_start)(); -void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); -void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); -void (*codegen_timing_block_start)(); -void (*codegen_timing_block_end)(); - -void codegen_timing_set(codegen_timing_t *timing) -{ - codegen_timing_start = timing->start; - codegen_timing_prefix = timing->prefix; - codegen_timing_opcode = timing->opcode; - codegen_timing_block_start = timing->block_start; - codegen_timing_block_end = timing->block_end; -} - -int codegen_in_recompile; diff --git a/src - Cópia/cpu/codegen.h b/src - Cópia/cpu/codegen.h deleted file mode 100644 index e613ecbed..000000000 --- a/src - Cópia/cpu/codegen.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * This file is part of the VARCem Project. - * - * Definitions for the code generator. - * - * Version: @(#)codegen.h 1.0.2 2018/03/14 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef _CODEGEN_H_ -#define _CODEGEN_H_ - -#include "../mem.h" -#include "x86_ops.h" - -#ifdef __amd64__ -#include "codegen_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 -#include "codegen_x86.h" -#else -#error Dynamic recompiler not implemented on your platform -#endif - -/*Handling self-modifying code (of which there is a lot on x86) : - - PCem tracks a 'dirty mask' for each physical page, in which each bit - represents 64 bytes. This is only tracked for pages that have code in - when a - page first has a codeblock generated, it is evicted from the writelookup and - added to the page_lookup for this purpose. When in the page_lookup, each write - will go through the mem_write_ram*_page() functions and set the dirty mask - appropriately. - - Each codeblock also contains a code mask (actually two masks, one for each - page the block is/may be in), again with each bit representing 64 bytes. - - Each page has a list of codeblocks present in it. As each codeblock can span - up to two pages, two lists are present. - - When a codeblock is about to be executed, the code masks are compared with the - dirty masks for the relevant pages. If either intersect, then - codegen_check_flush() is called on the affected page(s), and all affected - blocks are evicted. - - The 64 byte granularity appears to work reasonably well for most cases, - avoiding most unnecessary evictions (eg when code & data are stored in the - same page). -*/ - -typedef struct codeblock_t -{ - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; - uint64_t cmp; - - /*Previous and next pointers, for the codeblock list associated with - each physical page. Two sets of pointers, as a codeblock can be - present in two pages.*/ - struct codeblock_t *prev, *next; - struct codeblock_t *prev_2, *next_2; - - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - struct codeblock_t *parent, *left, *right; - - int pnt; - int ins; - - int valid; - - int was_recompiled; - int TOP; - - uint32_t pc; - uint32_t _cs; - uint32_t endpc; - uint32_t phys, phys_2; - uint32_t status; - uint32_t flags; - - uint8_t data[2048]; -} codeblock_t; - -/*Code block uses FPU*/ -#define CODEBLOCK_HAS_FPU 1 -/*Code block is always entered with the same FPU top-of-stack*/ -#define CODEBLOCK_STATIC_TOP 2 - -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) -{ - codeblock_t *block = pages[phys >> 12].head; - uint64_t a = _cs | ((uint64_t)phys << 32); - - while (block) - { - if (a == block->cmp) - { - if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) - break; - } - if (a < block->cmp) - block = block->left; - else - block = block->right; - } - - return block; -} - -static inline void codeblock_tree_add(codeblock_t *new_block) -{ - codeblock_t *block = pages[new_block->phys >> 12].head; - uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - new_block->cmp = a; - - if (!block) - { - pages[new_block->phys >> 12].head = new_block; - new_block->parent = new_block->left = new_block->right = NULL; - } - else - { - codeblock_t *old_block = NULL; - - while (block) - { - old_block = block; - if (a < old_block->cmp) - block = block->left; - else - block = block->right; - } - - if (a < old_block->cmp) - old_block->left = new_block; - else - old_block->right = new_block; - - new_block->parent = old_block; - new_block->left = new_block->right = NULL; - } -} - -static inline void codeblock_tree_delete(codeblock_t *block) -{ - codeblock_t *parent = block->parent; - - if (!block->left && !block->right) - { - /*Easy case - remove from parent*/ - if (!parent) - pages[block->phys >> 12].head = NULL; - else - { - if (parent->left == block) - parent->left = NULL; - if (parent->right == block) - parent->right = NULL; - } - return; - } - else if (!block->left) - { - /*Only right node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->right; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->right; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->right; - parent->right->parent = parent; - } - } - return; - } - else if (!block->right) - { - /*Only left node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->left; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->left; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->left; - parent->right->parent = parent; - } - } - return; - } - else - { - /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = block->right, *highest; - codeblock_t *old_parent; - - while (lowest->left) - lowest = lowest->left; - - old_parent = lowest->parent; - - /*Replace deleted node with lowest node*/ - if (!parent) - pages[block->phys >> 12].head = lowest; - else - { - if (parent->left == block) - parent->left = lowest; - if (parent->right == block) - parent->right = lowest; - } - - lowest->parent = parent; - lowest->left = block->left; - if (lowest->left) - lowest->left->parent = lowest; - - old_parent->left = NULL; - - highest = lowest->right; - if (!highest) - { - if (lowest != block->right) - { - lowest->right = block->right; - block->right->parent = lowest; - } - return; - } - - while (highest->right) - highest = highest->right; - - if (block->right && block->right != lowest) - { - highest->right = block->right; - block->right->parent = highest; - } - } -} - -#define PAGE_MASK_INDEX_MASK 3 -#define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_MASK 63 -#define PAGE_MASK_SHIFT 4 - -extern codeblock_t *codeblock; - -extern codeblock_t **codeblock_hash; - -void codegen_init(); -void codegen_reset(); -void codegen_block_init(uint32_t phys_addr); -void codegen_block_remove(); -void codegen_block_start_recompile(codeblock_t *block); -void codegen_block_end_recompile(codeblock_t *block); -void codegen_block_end(); -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); -void codegen_generate_seg_restore(); -void codegen_set_op32(); -void codegen_flush(); -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); - -extern int cpu_block_end; -extern uint32_t codegen_endpc; - -extern int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; -extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; -extern int cpu_recomp_flushes, cpu_recomp_flushes_latched; -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)(); -extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); -extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); -extern void (*codegen_timing_block_start)(); -extern void (*codegen_timing_block_end)(); - -typedef struct codegen_timing_t -{ - void (*start)(); - void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); - void (*block_start)(); - void (*block_end)(); -} codegen_timing_t; - -extern codegen_timing_t codegen_timing_pentium; -extern codegen_timing_t codegen_timing_686; -extern codegen_timing_t codegen_timing_486; -extern codegen_timing_t codegen_timing_winchip; - -void codegen_timing_set(codegen_timing_t *timing); - -extern int block_current; -extern int block_pos; - -#define CPU_BLOCK_END() cpu_block_end = 1 - -static inline void addbyte(uint8_t val) -{ - codeblock[block_current].data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addword(uint16_t val) -{ - uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addlong(uint32_t val) -{ - uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addquad(uint64_t val) -{ - uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -/*Current physical page of block being recompiled. -1 if no recompilation taking place */ -extern uint32_t recomp_page; - -extern x86seg *op_ea_seg; -extern int op_ssegs; -extern uint32_t op_old_pc; - -/*Set to 1 if flags have been changed in the block being recompiled, and hence - flags_op is known and can be relied on */ -extern int codegen_flags_changed; - -extern int codegen_fpu_entered; -extern int codegen_mmx_entered; - -extern int codegen_fpu_loaded_iq[8]; -extern int codegen_reg_loaded[8]; - -extern int codegen_in_recompile; - -#endif diff --git a/src - Cópia/cpu/codegen_ops.c b/src - Cópia/cpu/codegen_ops.c deleted file mode 100644 index 2c0ce4929..000000000 --- a/src - Cópia/cpu/codegen_ops.c +++ /dev/null @@ -1,597 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "cpu.h" -#include "x86.h" -#include "x86_ops.h" -#include "x86_flags.h" -#include "x87.h" -#include "386_common.h" -#include "cpu.h" -#include "codegen.h" -#include "codegen_ops.h" - -#ifdef __amd64__ -#include "codegen_ops_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 -#include "codegen_ops_x86.h" -#endif - -#include "codegen_ops_arith.h" -#include "codegen_ops_fpu.h" -#include "codegen_ops_jump.h" -#include "codegen_ops_logic.h" -#include "codegen_ops_misc.h" -#include "codegen_ops_mmx.h" -#include "codegen_ops_mov.h" -#include "codegen_ops_shift.h" -#include "codegen_ops_stack.h" -#include "codegen_ops_xchg.h" - -RecompOpFn recomp_opcodes[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16, -/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, -/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, - -/*40*/ ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, -/*50*/ ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE, - -/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_w, ropMOV_seg_w, NULL, -/*90*/ ropNOP, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_a, ropMOV_AX_a, ropMOV_a_AL, ropMOV_a_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, - -/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES, ropLDS, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_w, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_16, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32, -/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, -/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, - -/*40*/ ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, -/*50*/ ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE, - -/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_w_seg, ropLEA_l, ropMOV_seg_w, NULL, -/*90*/ ropNOP, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_a, ropMOV_EAX_a, ropMOV_a_AL, ropMOV_a_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, - -/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES, ropLDS, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32 -}; - -RecompOpFn recomp_opcodes_0f[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_mm_l, ropMOVQ_mm_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_l_mm, ropMOVQ_q_mm, - -/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -}; - - -RecompOpFn recomp_opcodes_d8[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, -}; - -RecompOpFn recomp_opcodes_d9[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_da[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_db[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_dc[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, -/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, -/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, -}; - -RecompOpFn recomp_opcodes_dd[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_de[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, -/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, -/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, -}; - -RecompOpFn recomp_opcodes_df[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_REPE[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_REPNE[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; diff --git a/src - Cópia/cpu/codegen_ops.h b/src - Cópia/cpu/codegen_ops.h deleted file mode 100644 index 53f5b34d2..000000000 --- a/src - Cópia/cpu/codegen_ops.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _CODEGEN_OPS_H_ -#define _CODEGEN_OPS_H_ - -#include "codegen.h" - -typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block); - -extern RecompOpFn recomp_opcodes[512]; -extern RecompOpFn recomp_opcodes_0f[512]; -extern RecompOpFn recomp_opcodes_d8[512]; -extern RecompOpFn recomp_opcodes_d9[512]; -extern RecompOpFn recomp_opcodes_da[512]; -extern RecompOpFn recomp_opcodes_db[512]; -extern RecompOpFn recomp_opcodes_dc[512]; -extern RecompOpFn recomp_opcodes_dd[512]; -extern RecompOpFn recomp_opcodes_de[512]; -extern RecompOpFn recomp_opcodes_df[512]; -RecompOpFn recomp_opcodes_REPE[512]; -RecompOpFn recomp_opcodes_REPNE[512]; - -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#define REG_AL 0 -#define REG_AH 4 -#define REG_CL 1 -#define REG_CH 5 -#define REG_DL 2 -#define REG_DH 6 -#define REG_BL 3 -#define REG_BH 7 - -#endif diff --git a/src - Cópia/cpu/codegen_ops_arith.h b/src - Cópia/cpu/codegen_ops_arith.h deleted file mode 100644 index ed2ce1ece..000000000 --- a/src - Cópia/cpu/codegen_ops_arith.h +++ /dev/null @@ -1,1028 +0,0 @@ -static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_W(opcode & 7); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - - return op_pc; -} -static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_L(opcode & 7); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - - return op_pc; -} -static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_W(opcode & 7); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - - return op_pc; -} -static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_L(opcode & 7); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - - return op_pc; -} - -#define ROP_ARITH_RMW(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } - -#define ROP_ARITH_RM(name, op, writeback) \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } - -ROP_ARITH_RMW(ADD, ADD, 1) -ROP_ARITH_RMW(SUB, SUB, 1) -ROP_ARITH_RM(ADD, ADD, 1) -ROP_ARITH_RM(SUB, SUB, 1) - -static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - dst_reg = 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - dst_reg = 0; - } \ - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - dst_reg = 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} - - -static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - ADD_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - SUB_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - } - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_B_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} - -static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadw(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 3; -} -static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - } - imm = fastreadl(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 5; -} - -static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xffffff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} diff --git a/src - Cópia/cpu/codegen_ops_fpu.h b/src - Cópia/cpu/codegen_ops_fpu.h deleted file mode 100644 index 481eadb8c..000000000 --- a/src - Cópia/cpu/codegen_ops_fpu.h +++ /dev/null @@ -1,645 +0,0 @@ -static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FXCH(opcode & 7); - - return op_pc; -} - -static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FLD(opcode & 7); - - return op_pc; -} - -static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FST(opcode & 7); - - return op_pc; -} -static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FST(opcode & 7); - FP_POP(); - - return op_pc; -} - - -static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_LOAD_S(); - - return op_pc + 1; -} -static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - - FP_LOAD_D(); - - return op_pc + 1; -} - -static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - FP_LOAD_IW(); - - return op_pc + 1; -} -static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_LOAD_IL(); - - return op_pc + 1; -} -static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - - FP_LOAD_IQ(); - - codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; - - return op_pc + 1; -} - -static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - - return op_pc + 1; -} -static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg1, host_reg2; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - FP_LOAD_REG_D(0, &host_reg1, &host_reg2); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - - return op_pc + 1; -} - -static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} - -#define ropFarith(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_ ## name); \ - \ - return op_pc + 1; \ -} - -ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); - -#define ropFcompare(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(); \ - \ - return op_pc + 1; \ -} \ -static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \ - \ - FP_POP(); \ - \ - return new_pc; \ -} - -ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); -ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); -ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW); -ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL); - -/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_ADD); - - return op_pc + 1; -} -static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_DIV); - - return op_pc + 1; -} -static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_MUL); - - return op_pc + 1; -} -static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_SUB); - - return op_pc + 1; -}*/ - - -static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - - return op_pc; -} -static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, 0, opcode & 7); - - return op_pc; -} - -static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - - return op_pc; -} - -static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - FP_POP(); - - return op_pc; -} -static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - FP_POP(); - - return op_pc; -} - -static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, 1); - FP_POP2(); - - return op_pc; -} - -static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - FP_ENTER(); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); - - return op_pc; -} - - -static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG_INT_W(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - - return op_pc + 1; -} -static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG_INT(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - - return op_pc + 1; -} - -static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg1, host_reg2; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - - FP_POP(); - - return op_pc + 1; -} - - -static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0); - UPDATE_NPXC(0); - - return op_pc + 1; -} -static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_WRITE(target_seg); - - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - - return op_pc + 1; -} - - -static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_FCHS(); - - return op_pc; -} - -#define opFLDimm(name, v) \ - static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - static double fp_imm = v; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \ - \ - return op_pc; \ - } - -opFLDimm(1, 1.0) -opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634); -opFLDimm(PI, 3.141592653589793); -opFLDimm(EG2, 0.3010299956639812); -opFLDimm(Z, 0.0) - -static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); - - return op_pc; -} diff --git a/src - Cópia/cpu/codegen_ops_jump.h b/src - Cópia/cpu/codegen_ops_jump.h deleted file mode 100644 index 0ad293744..000000000 --- a/src - Cópia/cpu/codegen_ops_jump.h +++ /dev/null @@ -1,270 +0,0 @@ -static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset); - - return -1; -} - -static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t offset = fetchdat & 0xffff; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); - - return -1; -} - -static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fastreadl(cs + op_pc); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); - - return -1; -} - - -static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } - - return op_pc+1; -} - -static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_L_RELEASE(host_reg); - TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_W_RELEASE(host_reg); - TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } - - return op_pc+1; -} - -static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)CF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); -} - -static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - int host_reg; - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - 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: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - if (not) - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)ZF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } -} - -static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)VF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); -} - -static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)PF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); -} - -static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - int host_reg; - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x8000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80000000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)NF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } -} - - -#define ropBRANCH(name, func, not) \ -static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not); \ - \ - return op_pc+1; \ -} \ -static uint32_t rop ## name ## _w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not); \ - \ - return op_pc+2; \ -} \ -static uint32_t rop ## name ## _l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not); \ - \ - return op_pc+4; \ -} - -ropBRANCH(JB, BRANCH_COND_B, 0) -ropBRANCH(JNB, BRANCH_COND_B, 1) -ropBRANCH(JE, BRANCH_COND_E, 0) -ropBRANCH(JNE, BRANCH_COND_E, 1) -ropBRANCH(JO, BRANCH_COND_O, 0) -ropBRANCH(JNO, BRANCH_COND_O, 1) -ropBRANCH(JP, BRANCH_COND_P, 0) -ropBRANCH(JNP, BRANCH_COND_P, 1) -ropBRANCH(JS, BRANCH_COND_S, 0) -ropBRANCH(JNS, BRANCH_COND_S, 1) -ropBRANCH(JL, BRANCH_COND_L, 0) -ropBRANCH(JNL, BRANCH_COND_L, 1) -ropBRANCH(JLE, BRANCH_COND_LE, 0) -ropBRANCH(JNLE, BRANCH_COND_LE, 1) -ropBRANCH(JBE, BRANCH_COND_BE, 0) -ropBRANCH(JNBE, BRANCH_COND_BE, 1) diff --git a/src - Cópia/cpu/codegen_ops_logic.h b/src - Cópia/cpu/codegen_ops_logic.h deleted file mode 100644 index c0ffa641a..000000000 --- a/src - Cópia/cpu/codegen_ops_logic.h +++ /dev/null @@ -1,564 +0,0 @@ -#define ROP_LOGIC(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } - -ROP_LOGIC(AND, AND, 1) -ROP_LOGIC(OR, OR, 1) -ROP_LOGIC(XOR, XOR, 1) - -static uint32_t ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} - -static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - AND_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - OR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 2; -} -static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 4; -} - -static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - XOR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint8_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadb(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 2; - - case 0x10: /*NOT b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_B(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xff); - STORE_REG_B_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - host_reg = LOAD_REG_B(fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_B(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_B_RELEASE(host_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint16_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST w,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadw(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 3; - - case 0x10: /*NOT w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_W(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffff); - STORE_REG_W_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - host_reg = LOAD_REG_W(fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_W_RELEASE(host_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint32_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST l,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = fastreadl(cs + op_pc + 1); - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadl(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 5; - - case 0x10: /*NOT l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_L(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffffffff); - STORE_REG_L_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - host_reg = LOAD_REG_L(fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_L(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_L_RELEASE(host_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} diff --git a/src - Cópia/cpu/codegen_ops_misc.h b/src - Cópia/cpu/codegen_ops_misc.h deleted file mode 100644 index d3039c81a..000000000 --- a/src - Cópia/cpu/codegen_ops_misc.h +++ /dev/null @@ -1,269 +0,0 @@ -static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - return op_pc; -} - -static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - CLEAR_BITS((uintptr_t)&flags, D_FLAG); - return op_pc; -} -static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - SET_BITS((uintptr_t)&flags, D_FLAG); - return op_pc; -} - -static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - CLEAR_BITS((uintptr_t)&flags, I_FLAG); - return op_pc; -} -static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - SET_BITS((uintptr_t)&flags, I_FLAG); - return op_pc; -} - -static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00) - return 0; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_B(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - } - - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_B_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - - return op_pc + 1; -} -static uint32_t codegen_temp; -static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - return op_pc + 1; - } - return 0; -} -static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_L(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - return op_pc + 1; - } - return 0; -} diff --git a/src - Cópia/cpu/codegen_ops_mmx.h b/src - Cópia/cpu/codegen_ops_mmx.h deleted file mode 100644 index 14730cb93..000000000 --- a/src - Cópia/cpu/codegen_ops_mmx.h +++ /dev/null @@ -1,277 +0,0 @@ -static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg1, host_reg2; - - MMX_ENTER(); - - LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - } - - return op_pc + 1; -} - -static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - MMX_ENTER(); - - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg1, host_reg2; - - LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); - STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_Q(target_seg); - STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); - } - - return op_pc + 1; -} - -static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - MMX_ENTER(); - - host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - MMX_ENTER(); - - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_MMX_LQ((fetchdat >> 3) & 7, 0); - } - - return op_pc + 1; -} - -#define MMX_OP(name, func) \ -static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int src_reg1, src_reg2; \ - int xmm_src, xmm_dst; \ - \ - MMX_ENTER(); \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ - } \ - xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ - STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ - \ - return op_pc + 1; \ -} - -MMX_OP(ropPAND, MMX_AND) -MMX_OP(ropPANDN, MMX_ANDN) -MMX_OP(ropPOR, MMX_OR) -MMX_OP(ropPXOR, MMX_XOR) - -MMX_OP(ropPADDB, MMX_ADDB) -MMX_OP(ropPADDW, MMX_ADDW) -MMX_OP(ropPADDD, MMX_ADDD) -MMX_OP(ropPADDSB, MMX_ADDSB) -MMX_OP(ropPADDSW, MMX_ADDSW) -MMX_OP(ropPADDUSB, MMX_ADDUSB) -MMX_OP(ropPADDUSW, MMX_ADDUSW) - -MMX_OP(ropPSUBB, MMX_SUBB) -MMX_OP(ropPSUBW, MMX_SUBW) -MMX_OP(ropPSUBD, MMX_SUBD) -MMX_OP(ropPSUBSB, MMX_SUBSB) -MMX_OP(ropPSUBSW, MMX_SUBSW) -MMX_OP(ropPSUBUSB, MMX_SUBUSB) -MMX_OP(ropPSUBUSW, MMX_SUBUSW) - -MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW); -MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD); -MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ); -MMX_OP(ropPACKSSWB, MMX_PACKSSWB); -MMX_OP(ropPCMPGTB, MMX_PCMPGTB); -MMX_OP(ropPCMPGTW, MMX_PCMPGTW); -MMX_OP(ropPCMPGTD, MMX_PCMPGTD); -MMX_OP(ropPACKUSWB, MMX_PACKUSWB); -MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW); -MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD); -MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ); -MMX_OP(ropPACKSSDW, MMX_PACKSSDW); - -MMX_OP(ropPCMPEQB, MMX_PCMPEQB); -MMX_OP(ropPCMPEQW, MMX_PCMPEQW); -MMX_OP(ropPCMPEQD, MMX_PCMPEQD); - -MMX_OP(ropPSRLW, MMX_PSRLW) -MMX_OP(ropPSRLD, MMX_PSRLD) -MMX_OP(ropPSRLQ, MMX_PSRLQ) -MMX_OP(ropPSRAW, MMX_PSRAW) -MMX_OP(ropPSRAD, MMX_PSRAD) -MMX_OP(ropPSLLW, MMX_PSLLW) -MMX_OP(ropPSLLD, MMX_PSLLD) -MMX_OP(ropPSLLQ, MMX_PSLLQ) - -MMX_OP(ropPMULLW, MMX_PMULLW); -MMX_OP(ropPMULHW, MMX_PMULHW); -MMX_OP(ropPMADDWD, MMX_PMADDWD); - -static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLW*/ - MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAW*/ - MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLW*/ - MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLD*/ - MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAD*/ - MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLD*/ - MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLQ*/ - MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAQ*/ - MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLQ*/ - MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} - -static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - codegen_mmx_entered = 0; - - return 0; -} diff --git a/src - Cópia/cpu/codegen_ops_mov.h b/src - Cópia/cpu/codegen_ops_mov.h deleted file mode 100644 index cb4498343..000000000 --- a/src - Cópia/cpu/codegen_ops_mov.h +++ /dev/null @@ -1,656 +0,0 @@ -static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); - - return op_pc + 1; -} -static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); - - return op_pc + 2; -} -static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - fetchdat = fastreadl(cs + op_pc); - - STORE_IMM_REG_L(opcode & 7, fetchdat); - - return op_pc + 4; -} - - -static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 0); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - - } - - return op_pc + 1; -} - -static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadb(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 2; -} -static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadw(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 3; -} -static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - uint32_t imm = fastreadl(cs + op_pc + 1); - - STORE_IMM_REG_L(fetchdat & 7, imm); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadl(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 5; -} - - -static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); - STORE_REG_TARGET_B_RELEASE(0, REG_AL); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); - STORE_REG_TARGET_W_RELEASE(0, REG_AX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); - STORE_REG_TARGET_L_RELEASE(0, REG_EAX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_B(REG_AL); - - MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_W(REG_AX); - - MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_L(REG_EAX); - - MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_REG_TARGET_W_RELEASE(0, dest_reg); - - return op_pc + 1; -} -static uint32_t ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_REG_TARGET_L_RELEASE(0, dest_reg); - - return op_pc + 1; -} - -static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = ZERO_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - ZERO_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = SIGN_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - SIGN_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL((uintptr_t)&ES); - break; - case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&CS); - break; - case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&DS); - break; - case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&SS); - break; - case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&FS); - break; - case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&GS); - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - if (op_32 & 0x100) - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - else - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - case 0x18: /*DS*/ - case 0x20: /*FS*/ - case 0x28: /*GS*/ - break; - case 0x10: /*SS*/ - default: - return 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - host_reg = 0; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - LOAD_SEG(host_reg, &_es); - break; - case 0x18: /*DS*/ - LOAD_SEG(host_reg, &_ds); - break; - case 0x20: /*FS*/ - LOAD_SEG(host_reg, &_fs); - break; - case 0x28: /*GS*/ - LOAD_SEG(host_reg, &_gs); - break; - } - - return op_pc + 1; -} - -#define ropLseg(seg, rseg) \ -static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - SAVE_EA(); \ - \ - if (op_32 & 0x100) \ - { \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ - } \ - else \ - { \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ - } \ - LOAD_SEG(0, &rseg); \ - if (op_32 & 0x100) \ - { \ - \ - int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ - } \ - else \ - { \ - int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ - } \ - \ - if (&rseg == &_ss) \ - CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ - return op_pc + 1; \ -} - -ropLseg(DS, _ds) -ropLseg(ES, _es) -ropLseg(FS, _fs) -ropLseg(GS, _gs) -ropLseg(SS, _ss) diff --git a/src - Cópia/cpu/codegen_ops_shift.h b/src - Cópia/cpu/codegen_ops_shift.h deleted file mode 100644 index b67c34544..000000000 --- a/src - Cópia/cpu/codegen_ops_shift.h +++ /dev/null @@ -1,125 +0,0 @@ -#define SHIFT(size, size2, res_store, immediate) \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - reg = LOAD_REG_ ## size(fetchdat & 7); \ - if (immediate) count = (fetchdat >> 8) & 0x1f; \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_ ## size(target_seg); \ - reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ - if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \ - \ - res_store((uintptr_t)&cpu_state.flags_op1, reg); \ - \ - switch (fetchdat & 0x38) \ - { \ - case 0x20: case 0x30: /*SHL*/ \ - SHL_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ - break; \ - \ - case 0x28: /*SHR*/ \ - SHR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \ - break; \ - \ - case 0x38: /*SAR*/ \ - SAR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ - break; \ - } \ - \ - res_store((uintptr_t)&cpu_state.flags_res, reg); \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_ ## size ## _RELEASE(reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \ - } - -static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); - - return op_pc + 2; -} -static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); - - return op_pc + 2; -} -static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); - - return op_pc + 2; -} - -static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); - - return op_pc + 1; -} -static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); - - return op_pc + 1; -} -static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); - - return op_pc + 1; -} diff --git a/src - Cópia/cpu/codegen_ops_stack.h b/src - Cópia/cpu/codegen_ops_stack.h deleted file mode 100644 index 96b900273..000000000 --- a/src - Cópia/cpu/codegen_ops_stack.h +++ /dev/null @@ -1,269 +0,0 @@ -static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_W(opcode & 7); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc; -} -static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_L(opcode & 7); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc; -} - -static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t imm = fetchdat & 0xffff; - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc+2; -} -static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t imm = fastreadl(cs + op_pc); - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc+4; -} - -static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t imm = fetchdat & 0xff; - int host_reg; - - if (imm & 0x80) - imm |= 0xff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc+1; -} -static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t imm = fetchdat & 0xff; - int host_reg; - - if (imm & 0x80) - imm |= 0xffffff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc+1; -} - -static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - SP_MODIFY(2); - STORE_REG_TARGET_W_RELEASE(0, opcode & 7); - - return op_pc; -} -static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - SP_MODIFY(4); - STORE_REG_TARGET_L_RELEASE(0, opcode & 7); - - return op_pc; -} - -static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2); - - return -1; -} -static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4); - - return -1; -} - -static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t offset = fetchdat & 0xffff; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2+offset); - - return -1; -} -static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t offset = fetchdat & 0xffff; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4+offset); - - return -1; -} - -static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t offset = fetchdat & 0xffff; - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc+2); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); - - return -1; -} -static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fastreadl(cs + op_pc); - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc+4); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); - - return -1; -} - -static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ - ADD_HOST_REG_IMM_W(host_reg, 2); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); - STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ - - return op_pc; -} -static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ - ADD_HOST_REG_IMM(host_reg, 4); - STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); - STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ - - return op_pc; -} - -#define ROP_PUSH_SEG(seg) \ -static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-2); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_W(&_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-4); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_L(&_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ -} - -ROP_PUSH_SEG(CS) -ROP_PUSH_SEG(DS) -ROP_PUSH_SEG(ES) -ROP_PUSH_SEG(FS) -ROP_PUSH_SEG(GS) -ROP_PUSH_SEG(SS) - -#define ROP_POP_SEG(seg, rseg) \ -static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ -} - -ROP_POP_SEG(DS, _ds) -ROP_POP_SEG(ES, _es) -ROP_POP_SEG(FS, _fs) -ROP_POP_SEG(GS, _gs) diff --git a/src - Cópia/cpu/codegen_ops_x86-64.h b/src - Cópia/cpu/codegen_ops_x86-64.h deleted file mode 100644 index de12f93d5..000000000 --- a/src - Cópia/cpu/codegen_ops_x86-64.h +++ /dev/null @@ -1,6185 +0,0 @@ -/*Register allocation : - R8-R15 - emulated registers -*/ -#include - -#define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 - -#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000) - -static inline int find_host_xmm_reg() -{ - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } - - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; -} -static inline void call(codeblock_t *block, uintptr_t func) -{ - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; - - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - if (diff >= -0x80000000 && diff < 0x7fffffff) - { - addbyte(0xE8); /*CALL*/ - addlong((uint32_t)diff); - } - else - { - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); - } -} - -static inline void call_long(uintptr_t func) -{ - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static inline void load_param_1_32(codeblock_t *block, uint32_t param) -{ -#if WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif - addlong(param); -} -static inline void load_param_1_reg_32(int reg) -{ -#if WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc0 | REG_ECX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc0 | REG_EDI | (reg << 3)); -#endif -} -#if 0 -static inline void load_param_1_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); -#if WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif - addquad(param); -} -#endif - -static inline void load_param_2_32(codeblock_t *block, uint32_t param) -{ -#if WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ -#else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ -#endif - addlong(param); -} -static inline void load_param_2_reg_32(int reg) -{ -#if WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDX, EAX*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ESI, EAX*/ - addbyte(0xc0 | REG_ESI | (reg << 3)); -#endif -} -static inline void load_param_2_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); -#if WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ -#else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ -#endif - addquad(param); -} - -static inline void load_param_3_reg_32(int reg) -{ - if (reg & 8) - { -#if WIN64 - addbyte(0x45); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x44); /*MOV EDX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } - else - { -#if WIN64 - addbyte(0x41); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x90); - addbyte(0x89); /*MOV EDX, reg*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } -} -static inline void load_param_3_reg_64(int reg) -{ - if (reg & 8) - { -#if WIN64 - addbyte(0x4d); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } - else - { -#if WIN64 - addbyte(0x49); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } -} - -static inline void CALL_FUNC(uintptr_t func) -{ - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static inline void RELEASE_REG(int host_reg) -{ -} - -static inline int LOAD_REG_B(int reg) -{ - int host_reg = reg & 3; - - if (!codegen_reg_loaded[reg & 3]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg & 3].b)); - } - - codegen_reg_loaded[reg & 3] = 1; - - if (reg & 4) - return host_reg | 0x18; - - return host_reg | 8; -} -static inline int LOAD_REG_W(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} -static inline int LOAD_REG_L(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} - -static inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = REG_EBX; - - addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ - addlong(imm); - - return host_reg; -} - -static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; - - if (guest_reg & 4) - { - if (host_reg & 8) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - if (host_reg & 0x10) - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - else - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - } - else - { - if (host_reg) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - addbyte(0x66); /*AND dest_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | dest_reg); - addword(0x00ff); - addbyte(0x66); /*OR dest_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | dest_reg); - addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (dest_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].w)); - } - else - { - if (host_reg & 8) - { - if (host_reg & 0x10) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - addbyte(0x88); /*MOV AL, AH*/ - addbyte(0xe0); - addbyte(0x41); /*MOV dest_reg, AL*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7)); - addbyte(0x88); /*MOVB regs[reg].b, AH*/ - addbyte(0x65); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - else - { - addbyte(0x45); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } - else - { - if (host_reg & 0x10) - { - addbyte(0xc1); /*SHR host_reg, 8*/ - addbyte(0xe8 | (host_reg & 7)); - addbyte(8); - } - addbyte(0x41); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } -} -static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; - - if (host_reg & 8) - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x45); - addbyte(0x89); - addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } - else - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x41); - addbyte(0x89); - addbyte(0xc0 | dest_reg | (host_reg << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } -} -static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } - else - { - addbyte(0x41); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } -} - -static inline void STORE_REG_B_RELEASE(int host_reg) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); - } - else - { - addbyte(0x44); /*MOVB [reg],host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].b)); - } -} -static inline void STORE_REG_W_RELEASE(int host_reg) -{ - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); -} -static inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x44); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].l)); -} - -static inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - if (reg & 4) - { - int host_reg = LOAD_REG_W(reg & 3) & 7; - addbyte(0x66); /*AND host_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | host_reg); - addword(0x00ff); - addbyte(0x66); /*OR host_reg, val << 8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | host_reg); - addword(val << 8); - addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 3].w)); - } - else - { - addbyte(0x41); /*MOVB reg, imm*/ - addbyte(0xb0 | reg); - addbyte(val); - addbyte(0x44); /*MOVB reg, regs[reg].b*/ - addbyte(0x88); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].b)); - } -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW reg, imm*/ - addbyte(0x41); - addbyte(0xb8 | reg); - addword(val); - addbyte(0x66); /*MOVW reg, regs[reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); -} -static inline void STORE_IMM_REG_L(int reg, uint32_t val) -{ - addbyte(0x41); /*MOVL reg, imm*/ - addbyte(0xb8 | reg); - addlong(val); - addbyte(0x44); /*MOVL reg, regs[reg].l*/ - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); -} - -static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uintptr_t)&cpu_state - 128); - addlong(val); - } - else if (addr < 0x100000000) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x04); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x48); /*MOV ESI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad(addr); - addbyte(0xc7); /*MOVL [ESI], val*/ - addbyte(0x00 | REG_ESI); - addlong(val); - } -} - - - - -static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - - if (!mod && rm == 6) - { - addbyte(0xb8); /*MOVL EAX, imm*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - int base_reg = 0, index_reg = 0; - - switch (rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; - } - if (!(rm & 4)) - { - if (rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); - } - base_reg &= 7; - index_reg &= 7; - - switch (mod) - { - case 0: - if (rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (mod || !(rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} -static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - uint32_t new_eaaddr; - - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; - - (*op_pc)++; - - if (mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - else - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - } - else - { - int base_reg; - - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(rm) & 7; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - } - return op_ea_seg; -} - -static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) -{ - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - - -static inline void CHECK_SEG_READ(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ - addlong((uint32_t)(uintptr_t)seg); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)seg); - } - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_low - (uintptr_t)seg); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_high - (uintptr_t)seg); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemb386l); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) -{ - addbyte(0x83); /*ADD EAX, offset*/ - addbyte(0xc0); - addbyte(offset); - MEM_LOAD_ADDR_EA_W(seg); -} -static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); -} - -static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememb386l); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - if (host_reg & 8) - { - addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_64(host_reg); - call_long((uintptr_t)writememql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); -} - -static inline void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 0x10) - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - addbyte(0xc1); /*SHR temp_reg, 8*/ - addbyte(0xe8 | temp_reg); - addbyte(8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb6); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - } - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static inline void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} -static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} - -static inline void AND_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - addbyte(0x66); /*OR AX, 0x00ff*/ - addbyte(0x0d); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ANDB dst_reg, AL*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*OR src_reg, 0xff*/ - addbyte(0x81); - addbyte(0xc8 | src_reg); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x20); /*ANDB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void AND_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } -} - -static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); - host_reg = REG_EDX | (host_reg & 0x10); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } - - return host_reg; -} - -static inline void OR_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ORB dst_reg, AL*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x08); /*ORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void OR_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void OR_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x09); /*ORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } -} - -static inline void XOR_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*XORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*XORB dst_reg, AL*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x30); /*XORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void XOR_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x31); /*XORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } -} - -static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ADDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ADDB dst_reg, AL*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x00); /*ADDB dst_reg, AL*/ - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} -static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} -static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} - -static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*SUBW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*SUBB dst_reg, AL*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} - -static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} - -static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*ADDB host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addbyte(imm); - } -} -static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - addbyte(0x66); /*ADDW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm); -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addlong(imm); -} - -static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*SUBB host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addbyte(imm); - } -} -static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - addbyte(0x66); /*SUBW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm); -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addlong(imm); -} - -static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = (host_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_IMM_B(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM_W(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_BP].l)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - -static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x0f); /*MOVZX host_reg,[reg]*/ - addbyte(0xb7); - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ - addbyte(0xb7); - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} -static inline int LOAD_VAR_WL(uintptr_t addr) -{ - return LOAD_VAR_W(addr); -} -static inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} - -static inline int COPY_REG(int src_reg) -{ - if (src_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); - - return REG_ECX | (src_reg & 0x10); -} - -static inline int LOAD_HOST_REG(int host_reg) -{ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); - - return REG_EBX | (host_reg & 0x10); -} - -static inline int ZERO_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static inline int SIGN_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int SIGN_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static inline void SHL_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHL AH, count*/ - addbyte(0xe0 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); - } -} -static inline void SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHL_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHR AH, count*/ - addbyte(0xe8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); - } -} -static inline void SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SHR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SAR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SAR AH, count*/ - addbyte(0xf8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); - } -} -static inline void SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} -static inline void SAR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} - -static inline void NEG_HOST_REG_B(int reg) -{ - if (reg & 0x10) - { - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV BX, reg*/ - addbyte(0xc3 | ((reg & 7) << 3)); - addbyte(0xf6); /*NEG BH*/ - addbyte(0xdf); - if (reg & 8) - addbyte(0x41); - addbyte(0x89); /*MOV reg, BX*/ - addbyte(0xd8 | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xf6); - addbyte(0xd8 | (reg & 7)); - } -} -static inline void NEG_HOST_REG_W(int reg) -{ - addbyte(0x66); - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} -static inline void NEG_HOST_REG_L(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} - - -static inline void FP_ENTER() -{ - if (codegen_fpu_entered) - return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static inline void FP_FXCH(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - reg = reg; -} - - - -static inline void FP_FLD(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x48); /*MOV ST[EBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); -} - -static inline void FP_FST(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0x48); /*MOV ST[EAX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_POP() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); -} -static inline void FP_POP2() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 2*/ - addbyte(0xc0); - addbyte(2); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); -} - -static inline void FP_LOAD_S() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_D() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_LOAD_IW() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IL() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IQ() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_LOAD_IMM_Q(uint64_t v) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(v ? 0 : 1); -} - -static inline void FP_FCHS() -{ - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf2); /*SUBSD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc0); - addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0x11); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); -} - -static inline int FP_LOAD_REG(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x66); /*MOVD EBX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0 | REG_EBX); - - return REG_EBX; -} -static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ - addbyte(0x8b); - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - *host_reg1 = REG_EBX; -} -static inline int64_t x87_fround(double b) -{ - int64_t a, c; - - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } - - return 0; -} -static inline int FP_LOAD_REG_INT_W(int reg) -{ - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x93); /*XCHG EBX, EAX*/ - - return REG_EBX; -} -static inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x93); /*XCHG EBX, EAX*/ - - return REG_EBX; -} -static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; - - return; - } - - addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_UINT64); - - addbyte(0x74); /*JZ +*/ - addbyte(5+2); - - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(6+12); - - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; -} - -#define FPU_ADD 0 -#define FPU_DIV 4 -#define FPU_DIVR 5 -#define FPU_MUL 1 -#define FPU_SUB 2 -#define FPU_SUBR 3 - -static inline void FP_OP_REG(int op, int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (dst) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - if (src) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(src); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - } - addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); -} - -static inline void FP_OP_MEM(int op) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); - - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0xc1); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc1); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc8); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0xc1); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc1); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc8); - break; - } - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} - -static inline void FP_OP_S(int op) -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_OP_MEM(op); -} -static inline void FP_OP_D(int op) -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*STMXCSR [ESP+8]*/ - addbyte(0xae); - addbyte(0x5c); - addbyte(0x24); - addbyte(0x08); - addbyte(0x8b); /*MOV EAX, [ESP+8]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x08); - addbyte(0x25); /*AND EAX, ~(3 << 13)*/ - addlong(~(3 << 10)); - addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ - addlong((cpu_state.npxc & (3 << 10)) << 3); - addbyte(0x89); /*MOV [RSP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x0c); - addbyte(0x0f); /*LDMXCSR [RSP+12]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x0c); - } - FP_OP_MEM(op); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*LDMXCSR [RSP+8]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x08); - } -} -static inline void FP_OP_IW(int op) -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} -static inline void FP_OP_IL(int op) -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - 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]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} - -static inline void FP_COMPARE_MEM() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0x66); /*COMISD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0xc1); - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} -static inline void FP_COMPARE_S() -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_D() -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IW() -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IL() -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} - -static inline void UPDATE_NPXC(int reg) -{ -} - -static inline void SET_BITS(uintptr_t addr, uint32_t val) -{ - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addbyte(val); - } - } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*OR [RAX], val*/ - addbyte(0x08); - addlong(val); - } - else - { - addbyte(0x80); /*OR [RAX], val*/ - addbyte(0x08); - addbyte(val); - } - } -} - -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) -{ - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } - } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*AND [RAX], val*/ - addbyte(0x20); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [RAX], val*/ - addbyte(0x20); - addbyte(~val); - } - } -} - -#define LOAD_Q_REG_1 REG_EAX -#define LOAD_Q_REG_2 REG_EDX - -static inline void MMX_ENTER() -{ - if (codegen_mmx_entered) - return; - - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; -} - -extern int mmx_ebx_ecx_loaded; - -static inline int LOAD_MMX_D(int guest_reg) -{ - int host_reg = REG_EBX; - - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - - return host_reg; -} -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) -{ - int host_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x8b); /*MOV RBX, reg*/ - addbyte(0x44 | ((host_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - *host_reg1 = host_reg; -} -static inline int LOAD_MMX_Q_MMX(int guest_reg) -{ - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; - - addbyte(0xf3); /*MOV XMMx, reg*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44 | ((dst_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - return dst_reg; -} - -static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) -{ - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; - - addbyte(0x66); /*MOVQ host_reg, src_reg1*/ - if (src_reg1 & 8) - addbyte(0x49); - else - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); - - return dst_reg; -} - -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) -{ - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x44); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - if (host_reg1 & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) -{ - if (host_reg1 & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x89); /*MOV [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) -{ - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); -} - -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} - -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) - -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) - -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) - -MMX_x86_OP(PUNPCKLBW, 0x60); -MMX_x86_OP(PUNPCKLWD, 0x61); -MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); - -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); - -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); - -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); - -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} - -static inline void MMX_PSRLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - - -static inline void SAVE_EA() -{ - addbyte(0x89); /*MOV [ESP+0x24], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); -} -static inline void LOAD_EA() -{ - addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); -} - -#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE - -static inline void MEM_CHECK_WRITE(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3 = NULL; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RCX, writelookup2*/ - addbyte(0xb9); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf9); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - /*slowpath:*/ - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - - - load_param_1_reg_32(REG_EDI); - load_param_2_32(&codeblock[block_current], 1); - - call(&codeblock[block_current], (uintptr_t)mmutranslatereal); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - - LOAD_EA(); -} - -static inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal); - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $fff, EBX*/ - addbyte(0xc3); - addlong(0xfff); - addbyte(0x74); /*JNE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE slowpath*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal); - addbyte(0x83); /*ADD EBX, 3*/ - addbyte(0xc3); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $ffc, EBX*/ - addbyte(0xc3); - addlong(0xffc); - addbyte(0x74); /*JE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemb386l); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemwl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemll); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} - -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememb386l); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememwl); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememll); - /*done:*/ -} - -static inline void LOAD_SEG(int host_reg, void *seg) -{ - load_param_2_64(&codeblock[block_current], (uint64_t)seg); - load_param_1_reg_32(host_reg); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} diff --git a/src - Cópia/cpu/codegen_ops_x86.h b/src - Cópia/cpu/codegen_ops_x86.h deleted file mode 100644 index 8f38b3cdf..000000000 --- a/src - Cópia/cpu/codegen_ops_x86.h +++ /dev/null @@ -1,3992 +0,0 @@ -/*Register allocation : - EBX, ECX, EDX - emulated registers - EAX - work register, EA storage - ESI, EDI - work registers - EBP - points at emulated register array -*/ -#define HOST_REG_START 1 -#define HOST_REG_END 4 -#define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 -static inline int find_host_reg() -{ - int c; - for (c = HOST_REG_START; c < HOST_REG_END; c++) - { - if (host_reg_mapping[c] == -1) - break; - } - - if (c == NR_HOST_REGS) - fatal("Out of host regs!\n"); - return c; -} -static inline int find_host_xmm_reg() -{ - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } - - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; -} - -#if 0 -static inline void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x05); - addlong(addr); - addbyte(val); -} -static inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x05); - addlong(addr); - addword(val); -} -#endif -static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uint32_t)&cpu_state - 128); - addlong(val); - } - else - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x05); - addlong(addr); - addlong(val); - } -} - -static inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x45); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - addbyte(val); -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - addword(val); -} -static inline void STORE_IMM_REG_L(int reg, uint32_t val) -{ - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); - addlong(val); -} - -static inline int LOAD_REG_B(int reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX B[reg],host_reg*/ - addbyte(0xb6); - addbyte(0x45 | (host_reg << 3)); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - - return host_reg; -} -static inline int LOAD_REG_W(int reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX W[reg],host_reg*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - - return host_reg; -} -static inline int LOAD_REG_L(int reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); - - return host_reg; -} - -static inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x66); /*MOVL host_reg,[reg]*/ - addbyte(0x8b); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} -static inline int LOAD_VAR_WL(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x0f); /*MOVZX host_reg, [addr]*/ - addbyte(0xb7); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} -static inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} - -static inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0xc7); /*MOVL host_reg, imm*/ - addbyte(0xc0 | host_reg); - addlong(imm); - - return host_reg; -} - -static inline int LOAD_HOST_REG(int host_reg) -{ - int new_host_reg = find_host_reg(); - host_reg_mapping[new_host_reg] = 0; - - addbyte(0x89); /*MOV new_host_reg, host_reg*/ - addbyte(0xc0 | (host_reg << 3) | new_host_reg); - - return new_host_reg; -} - -static inline void STORE_REG_B_RELEASE(int host_reg) -{ - addbyte(0x88); /*MOVB [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (host_reg_mapping[host_reg] & 4) - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_W_RELEASE(int host_reg) -{ - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); - host_reg_mapping[host_reg] = -1; -} - -static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x88); /*MOVB [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (guest_reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x66); /*MOVW [guest_reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].w)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x89); /*MOVL [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].l)); - host_reg_mapping[host_reg] = -1; -} - -static inline void RELEASE_REG(int host_reg) -{ - host_reg_mapping[host_reg] = -1; -} - -static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x66); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -#define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR -#define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR - -static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) -{ - addbyte(0x00); /*ADDB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) -{ - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) -{ - addbyte(0x01); /*ADDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - addbyte(0x80); /*ADDB host_reg, imm*/ - addbyte(0xC0 | host_reg); - addbyte(imm); -} -static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x83); - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x81); - addbyte(0xC0 | host_reg); - addword(imm); - } -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addlong(imm); - } -} - -#define AND_HOST_REG_B AND_HOST_REG_L -#define AND_HOST_REG_W AND_HOST_REG_L -static inline void AND_HOST_REG_L(int dst_reg, int src_reg) -{ - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addlong(imm); - } -} -static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) -{ - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - AND_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -#define OR_HOST_REG_B OR_HOST_REG_L -#define OR_HOST_REG_W OR_HOST_REG_L -static inline void OR_HOST_REG_L(int dst_reg, int src_reg) -{ - addbyte(0x09); /*ORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addlong(imm); - } -} - -static inline void NEG_HOST_REG_B(int reg) -{ - addbyte(0xf6); - addbyte(0xd8 | reg); -} -static inline void NEG_HOST_REG_W(int reg) -{ - addbyte(0x66); - addbyte(0xf7); - addbyte(0xd8 | reg); -} -static inline void NEG_HOST_REG_L(int reg) -{ - addbyte(0xf7); - addbyte(0xd8 | reg); -} - -static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) -{ - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) -{ - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) -{ - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - addbyte(0x80); /*SUBB host_reg, imm*/ - addbyte(0xE8 | host_reg); - addbyte(imm); -} -static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x83); - addbyte(0xE8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x81); - addbyte(0xE8 | host_reg); - addword(imm); - } -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addbyte(imm); - } - else - { - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addlong(imm); - } -} - -static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) -{ - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg; -} -static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) -{ - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) -{ - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - SUB_HOST_REG_IMM_B(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - SUB_HOST_REG_IMM_W(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -#define XOR_HOST_REG_B XOR_HOST_REG_L -#define XOR_HOST_REG_W XOR_HOST_REG_L -static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) -{ - addbyte(0x31); /*XORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); -} -static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addlong(imm); - } -} - -static inline void CALL_FUNC(uintptr_t dest) -{ - addbyte(0xE8); /*CALL*/ - addlong(((uintptr_t)dest - (uintptr_t)(&codeblock[block_current].data[block_pos + 4]))); -} - -static inline void SHL_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static inline void SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static inline void SHL_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static inline void SHR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static inline void SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static inline void SHR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static inline void SAR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} -static inline void SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} -static inline void SAR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} - - -static inline void CHECK_SEG_READ(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_low); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_high); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ - addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ - addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0x83); /*ADD EAX, offset*/ - addbyte(0xc0); - addbyte(offset); - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ - addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ - addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ - addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} - -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ - addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} - -static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); -} - -static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ - addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ - addlong(mem_store_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ - addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ - addlong(mem_store_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ - addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ - addlong(mem_store_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if (host_reg != REG_EBX) - { - addbyte(0x89); /*MOV EBX, host_reg*/ - addbyte(0xc0 | REG_EBX | (host_reg << 3)); - } - if (host_reg2 != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg2*/ - addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ - addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} - -static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); -} - - -static inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - if (!mod && rm == 6) - { - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - switch (mod) - { - case 0: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - break; - case 1: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 8)); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL EAX, 0xffff*/ - addlong(0xffff); - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} - -static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - uint32_t new_eaaddr; - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; - (*op_pc)++; - - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 16)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - if (stack_offset < 0x80 || stack_offset >= 0xffffff80) - { - addbyte(0x83); - addbyte(0xc0 | REG_EAX); - addbyte(stack_offset); - } - else - { - addbyte(0x05); /*ADDL EAX, stack_offset*/ - addlong(stack_offset); - } - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 2: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 3: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - } - } - } - else - { - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[rm].l)); - cpu_state.eaaddr = cpu_state.regs[rm].l; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (mod == 1) - { - addbyte(0x83); /*ADD EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); /*ADD EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - } - return op_ea_seg; -} - -static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) -{ - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - - -static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+2); - CALL_FUNC((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - - default: - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+3+5+2+3+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+3+5+2+3+2+2); - - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - - -static inline void FP_ENTER() -{ - if (codegen_fpu_entered) - return; - - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static inline void FP_FLD(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x88); /*MOV tag[-1][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static inline void FP_FST(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static inline void FP_FXCH(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[0][EBP], AH*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0xdd); /*FLD [ST+EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xbe); /*MOVL ESI, ST_int64*/ - addlong((uintptr_t)cpu_state.MM); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); - } -} - - -static inline void FP_LOAD_S() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_D() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0xdd); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IW() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0x66); /*TEST AX, AX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IL() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IQ() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0xdf); /*FILDq MM[reg][EBP]*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ - addbyte(0x6c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static inline void FP_LOAD_IMM_Q(uint64_t v) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc7); /*MOV ST[reg][EBP], v*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); - addlong(v >> 32); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(v ? 0 : 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(v ? 0 : 1); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static inline int FP_LOAD_REG(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xd9); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EAX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - - return REG_EBX; -} - -static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xdd); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, [ESP+4]*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(0x24); - addbyte(0x04); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; -} - -static inline int FP_LOAD_REG_INT_W(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - return; - } - - addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_UINT64); - addbyte(0x74); /*JZ +*/ - addbyte(4+4+2); - - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+3+3+3+4); - - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdf); /*FISTPQ [ESP]*/ - addbyte(0x3c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, 4[ESP]*/ - addbyte(0x4c); - addbyte(0x24); - addbyte(4); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; -} - -static inline void FP_POP() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 1) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 1*/ - addbyte(1); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} -static inline void FP_POP2() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP+1)&7])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 2) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 2*/ - addbyte(2); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -#define FPU_ADD 0x00 -#define FPU_DIV 0x30 -#define FPU_DIVR 0x38 -#define FPU_MUL 0x08 -#define FPU_SUB 0x20 -#define FPU_SUBR 0x28 - -static inline void FP_OP_S(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -static inline void FP_OP_D(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } - } -} -static inline void FP_OP_IW(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -static inline void FP_OP_IL(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -#if 0 -static inline void FP_OP_IQ(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -#endif -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - -static inline void FP_COMPARE_S() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_D() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_IW() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_IL() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -static inline void FP_OP_REG(int op, int dst, int src) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0xdc); /*FADD ST[src][EBP]*/ - addbyte(0x45 | op); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); - addbyte(~TAG_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EAX*8]*/ - addbyte(0x44 | op); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EBX*8]*/ - addbyte(0x44 | op); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - } -} - -static inline void FP_COMPARE_REG(int dst, int src) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP ST[src][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EAX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EBX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -static inline void FP_FCHS() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xd9); /*FCHS*/ - addbyte(0xe0); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xd9); /*FCHS*/ - addbyte(0xe0); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} - -static inline void UPDATE_NPXC(int reg) -{ - addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ - addbyte(0x81); - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addword(~0xc00); - if (reg) - { - addbyte(0x66); /*AND reg, 0xc00*/ - addbyte(0x81); - addbyte(0xe0 | reg); - addword(0xc00); - } - else - { - addbyte(0x66); /*AND AX, 0xc00*/ - addbyte(0x25); - addword(0xc00); - } - addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ - addbyte(0x09); - addbyte(0x45 | (reg << 3)); - addbyte((uint8_t)cpu_state_offset(new_npxc)); -} - -static inline int ZERO_EXTEND_W_B(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int ZERO_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int ZERO_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} - -static inline int SIGN_EXTEND_W_B(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int SIGN_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} - -static inline int COPY_REG(int src_reg) -{ - return src_reg; -} - -static inline void SET_BITS(uintptr_t addr, uint32_t val) -{ - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x0d); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); - addbyte(0x0d); - addlong(addr); - addbyte(val); - } -} -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) -{ - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } -} - -#define LOAD_Q_REG_1 REG_EAX -#define LOAD_Q_REG_2 REG_EDX - -static inline void MMX_ENTER() -{ - if (codegen_mmx_entered) - return; - - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; -} - -extern int mmx_ebx_ecx_loaded; - -static inline int LOAD_MMX_D(int guest_reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 100; - - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - - return host_reg; -} -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) -{ - if (!mmx_ebx_ecx_loaded) - { - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; - mmx_ebx_ecx_loaded = 1; - } - else - { - *host_reg1 = REG_EAX; - *host_reg2 = REG_EDX; - } - - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | ((*host_reg1) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x8b); /*MOV ECX, reg+4*/ - addbyte(0x45 | ((*host_reg2) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); -} -static inline int LOAD_MMX_Q_MMX(int guest_reg) -{ - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = guest_reg; - - addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45 | (dst_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - return dst_reg; -} - -static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) -{ - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; - - addbyte(0x66); /*MOVD dst_reg, src_reg1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | src_reg1); - addbyte(0x66); /*MOVD XMM7, src_reg2*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (7 << 3) | src_reg2); - addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | 7 | (dst_reg << 3)); - - return dst_reg; -} - -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) -{ - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) -{ - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg2 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); -} -static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) -{ - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); -} - -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} - -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) - -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) - -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) - -MMX_x86_OP(PUNPCKLBW, 0x60); -MMX_x86_OP(PUNPCKLWD, 0x61); -MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); - -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); - -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); - -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); - -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} - -static inline void MMX_PSRLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - - -static inline void SAVE_EA() -{ - addbyte(0x89); /*MOV [ESP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); -} -static inline void LOAD_EA() -{ - addbyte(0x8b); /*MOV EAX, [ESP+12]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); -} - -#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static inline void MEM_CHECK_WRITE(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write*/ - addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); -} -static inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_w*/ - addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); -} -static inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_l*/ - addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); -} - -static inline void LOAD_SEG(int host_reg, void *seg) -{ - addbyte(0xc7); /*MOV [ESP+4], seg*/ - addbyte(0x44); - addbyte(0x24); - addbyte(4); - addlong((uint32_t)seg); - addbyte(0x89); /*MOV [ESP], host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x24); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} diff --git a/src - Cópia/cpu/codegen_ops_xchg.h b/src - Cópia/cpu/codegen_ops_xchg.h deleted file mode 100644 index 597d26e1b..000000000 --- a/src - Cópia/cpu/codegen_ops_xchg.h +++ /dev/null @@ -1,93 +0,0 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ - } - -OP_XCHG_AX_(BX) -OP_XCHG_AX_(CX) -OP_XCHG_AX_(DX) -OP_XCHG_AX_(SI) -OP_XCHG_AX_(DI) -OP_XCHG_AX_(SP) -OP_XCHG_AX_(BP) - -#define OP_XCHG_EAX_(reg) \ - static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ - } - -OP_XCHG_EAX_(EBX) -OP_XCHG_EAX_(ECX) -OP_XCHG_EAX_(EDX) -OP_XCHG_EAX_(ESI) -OP_XCHG_EAX_(EDI) -OP_XCHG_EAX_(ESP) -OP_XCHG_EAX_(EBP) - -static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ -/* #ifdef __amd64__ - return 0; -#else */ - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_B(fetchdat & 7); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -/* #endif */ -} -static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_W(fetchdat & 7); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -} -static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_L(fetchdat & 7); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -} diff --git a/src - Cópia/cpu/codegen_timing_486.c b/src - Cópia/cpu/codegen_timing_486.c deleted file mode 100644 index 3f45d117e..000000000 --- a/src - Cópia/cpu/codegen_timing_486.c +++ /dev/null @@ -1,420 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "cpu.h" -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "codegen.h" -#include "codegen_ops.h" -#include "codegen_timing_common.h" - -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) - -static int *opcode_timings[256] = -{ -/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, -/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), -/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), -/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), -/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL -}; - -static int *opcode_timings_mod3[256] = -{ -/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, -/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), -/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), -/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), -/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL -}; - -static int *opcode_timings_0f[256] = -{ -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, -/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, -/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, -/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, -}; -static int *opcode_timings_0f_mod3[256] = -{ -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, -/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, -/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, -/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, -}; - -static int *opcode_timings_shift[8] = -{ - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) -}; -static int *opcode_timings_shift_mod3[8] = -{ - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) -}; - -static int *opcode_timings_f6[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f6_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f7[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_f7_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_ff[8] = -{ - &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; -static int *opcode_timings_ff_mod3[8] = -{ - &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; - -static int *opcode_timings_d8[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ - CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ - CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) -}; -static int *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FXCH*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FNOP*/ - CYCLES(3), NULL, NULL, NULL, NULL, NULL, NULL, NULL, - /*FSTP*/ - CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/* opFCHS opFABS opFTST opFXAM*/ - CYCLES(6), CYCLES(3), NULL, NULL, CYCLES(4), CYCLES(8), NULL, NULL, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/ - CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(4), NULL, -/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/ - CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3), -/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ - CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257) -}; - -static int *opcode_timings_da[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_da_mod3[8] = -{ - NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL -}; - - -static int *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil FLDe FSTPe*/ - CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6) -}; -static int *opcode_timings_db_mod3[64] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/ - NULL, CYCLES(3), CYCLES(7), CYCLES(17), CYCLES(3), CYCLES(3), NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -static int *opcode_timings_dc[8] = -{ -/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ - CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3) -}; -static int *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL -}; - -static int *opcode_timings_de[8] = -{ -/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_de_mod3[8] = -{ -/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ - CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ - CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28) -}; -static int *opcode_timings_df_mod3[8] = -{ -/* FFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL -}; - -static int *opcode_timings_8x[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_8x_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; - -static int timing_count; -static uint8_t last_prefix; -static uint32_t regmask_modified; - -static inline int COUNT(int *c, int op_32) -{ - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; -} - -void codegen_timing_486_block_start() -{ - regmask_modified = 0; -} - -void codegen_timing_486_start() -{ - timing_count = 0; - last_prefix = 0; -} - -void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) -{ - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; -} - -void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) -{ - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; - - default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); -} - -void codegen_timing_486_block_end() -{ -} - -codegen_timing_t codegen_timing_486 = -{ - codegen_timing_486_start, - codegen_timing_486_prefix, - codegen_timing_486_opcode, - codegen_timing_486_block_start, - codegen_timing_486_block_end -}; diff --git a/src - Cópia/cpu/codegen_timing_686.c b/src - Cópia/cpu/codegen_timing_686.c deleted file mode 100644 index fc818d7f1..000000000 --- a/src - Cópia/cpu/codegen_timing_686.c +++ /dev/null @@ -1,1056 +0,0 @@ -/*Elements taken into account : - - X/Y pairing - - FPU/FXCH pairing - - Prefix decode delay - - AGI stalls - Elements not taken into account : - - Branch prediction (beyond most simplistic approximation) - - FPU queue - - Out of order execution (beyond most simplistic approximation) -*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "cpu.h" -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "codegen.h" -#include "codegen_timing_common.h" - -/*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 31) - -#define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) - -/*Instruction lasts given number of cycles. Does not pair*/ -#define CYCLES(c) (c) - -/*Instruction follows either register timing, read-modify, or read-modify-write. - May be pairable*/ -#define CYCLES_REG (1 << 0) -#define CYCLES_RM (1 << 0) -#define CYCLES_RMW (1 << 0) -#define CYCLES_BRANCH (1 << 0) - -#define CYCLES_MASK ((1 << 7) - 1) - -/*Instruction does not pair*/ -#define PAIR_NP (0 << 29) -/*Instruction pairs in X pipe only*/ -#define PAIR_X (1 << 29) -/*Instruction pairs in X pipe only, and can not pair with a following instruction*/ -#define PAIR_X_BRANCH (2 << 29) -/*Instruction pairs in both X and Y pipes*/ -#define PAIR_XY (3 << 29) - -#define PAIR_MASK (3 << 29) - -#define INVALID 0 - -static int prev_full; -static uint32_t prev_opcode; -static uint32_t *prev_timings; -static uint32_t prev_op_32; -static uint32_t prev_regmask; -static uint64_t *prev_deps; -static uint32_t prev_fetchdat; - -static uint32_t last_regmask_modified; -static uint32_t regmask_modified; - -static uint32_t opcode_timings[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* ADD ADD PUSH ES POP ES*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* Jxx*/ -/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, CYCLES(3), PAIR_XY | CYCLES(1), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), -/* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV*/ -/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_XY | CYCLES(10), PAIR_XY | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_XY | CYCLES(18), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), -/* CALL JMP JMP JMP*/ - PAIR_X_BRANCH | CYCLES_REG, PAIR_X_BRANCH | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_X_BRANCH | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), -/* CLD STD INCDEC*/ - PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_RMW, INVALID -}; - -static uint32_t opcode_timings_mod3[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ADD ADD PUSH ES POP ES*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* Jxx*/ -/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*80*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), -/* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV*/ -/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_XY | CYCLES(13), PAIR_XY | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_XY | CYCLES(18), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), -/* CALL JMP JMP JMP*/ - PAIR_X_BRANCH | CYCLES_REG, PAIR_X_BRANCH | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_X_BRANCH | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), -/* CLD STD INCDEC*/ - PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_REG, INVALID -}; - -static uint32_t opcode_timings_0f[256] = -{ -/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), - INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, - PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - -/*70*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - -/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*90*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*a0*/ PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(12), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(5), INVALID, INVALID, - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - INVALID, INVALID, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, - -/*c0*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), - -/*d0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - -/*e0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - -/*f0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, -}; -static uint32_t opcode_timings_0f_mod3[256] = -{ -/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), - INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, - PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - -/*70*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - -/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*90*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*a0*/ PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(12), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(5), INVALID, INVALID, - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - INVALID, INVALID, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - -/*e0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, - INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - -/*f0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, -}; - -static uint32_t opcode_timings_shift[8] = -{ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, -}; -static uint32_t opcode_timings_shift_mod3[8] = -{ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -}; -static uint32_t opcode_timings_shift_imm[8] = -{ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, -}; -static uint32_t opcode_timings_shift_imm_mod3[8] = -{ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -}; -static uint32_t opcode_timings_shift_cl[8] = -{ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -}; -static uint32_t opcode_timings_shift_cl_mod3[8] = -{ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -}; - -static uint32_t opcode_timings_f6[8] = -{ -/* TST NOT NEG*/ - PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) -}; -static uint32_t opcode_timings_f6_mod3[8] = -{ -/* TST NOT NEG*/ - PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) -}; -static uint32_t opcode_timings_f7[8] = -{ -/* TST NOT NEG*/ - PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) -}; -static uint32_t opcode_timings_f7_mod3[8] = -{ -/* TST NOT NEG*/ - PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) -}; -static uint32_t opcode_timings_ff[8] = -{ -/* INC DEC CALL CALL far*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), -/* JMP JMP far PUSH*/ - PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID -}; -static uint32_t opcode_timings_ff_mod3[8] = -{ -/* INC DEC CALL CALL far*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), -/* JMP JMP far PUSH*/ - PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID -}; - -static uint32_t opcode_timings_d8[8] = -{ -/* FADDs FMULs FCOMs FCOMPs*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), -/* FSUBs FSUBRs FDIVs FDIVRs*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) -}; -static uint32_t opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), -/* FSUB FSUBR FDIV FDIVR*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) -}; - -static uint32_t opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs*/ - PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), -/* FLDENV FLDCW FSTENV FSTCW*/ - PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5) -}; -static uint32_t opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), - /*FXCH*/ - PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), - PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), - /*FNOP*/ - PAIR_X | CYCLES(2), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), -/* opFCHS opFABS*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), INVALID, INVALID, -/* opFTST opFXAM (oddly low) */ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - PAIR_X | CYCLES(92), PAIR_X | CYCLES(170), PAIR_X | CYCLES(129), PAIR_X | CYCLES(161), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, PAIR_X | CYCLES(4), PAIR_X | CYCLES(2), -/* opFPREM opFSQRT opFSINCOS*/ - PAIR_X | CYCLES(91), INVALID, PAIR_X | CYCLES(60), PAIR_X | CYCLES(161), -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - PAIR_X | CYCLES(20), PAIR_X | CYCLES(14), PAIR_X | CYCLES(140), PAIR_X | CYCLES(141) -}; - -static uint32_t opcode_timings_da[8] = -{ -/* FIADDl FIMULl FICOMl FICOMPl*/ - PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48) -}; -static uint32_t opcode_timings_da_mod3[8] = -{ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - INVALID, PAIR_X | CYCLES(5), INVALID, INVALID -}; - - -static uint32_t opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil*/ - PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), -/* FLDe FSTPe*/ - INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2) -}; -static uint32_t opcode_timings_db_mod3[64] = -{ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - -/* opFNOP opFCLEX opFINIT*/ - INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(5), PAIR_X | CYCLES(8), -/* opFNOP opFNOP*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static uint32_t opcode_timings_dc[8] = -{ -/* FADDd FMULd FCOMd FCOMPd*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), -/* FSUBd FSUBRd FDIVd FDIVRd*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) -}; -static uint32_t opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) -}; - -static uint32_t opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd*/ - PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), -/* FRSTOR FSAVE FSTSW*/ - PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2) -}; -static uint32_t opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP*/ - PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), -/* FUCOM FUCOMP*/ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID -}; - -static uint32_t opcode_timings_de[8] = -{ -/* FIADDw FIMULw FICOMw FICOMPw*/ - PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38) -}; -static uint32_t opcode_timings_de_mod3[8] = -{ -/* FADD FMUL FCOMPP*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7), -/* FSUB FSUBR FDIV FDIVR*/ - PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) -}; - -static uint32_t opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw*/ - PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13), -/* FILDiq FBSTP FISTPiq*/ - INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13) -}; -static uint32_t opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - PAIR_X | CYCLES(6), INVALID, INVALID, INVALID -}; - -static uint32_t opcode_timings_8x[8] = -{ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM -}; -static uint32_t opcode_timings_8x_mod3[8] = -{ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG -}; -static uint32_t opcode_timings_81[8] = -{ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM -}; -static uint32_t opcode_timings_81_mod3[8] = -{ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG -}; - -static int decode_delay; -static uint8_t last_prefix; - -static inline int COUNT(uint32_t c, int op_32) -{ - if (c & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - if (!(c & PAIR_MASK)) - return c & 0xffff; - - return c & CYCLES_MASK; -} - -void codegen_timing_686_block_start() -{ - prev_full = decode_delay = 0; - regmask_modified = last_regmask_modified = 0; -} - -void codegen_timing_686_start() -{ - decode_delay = 0; - last_prefix = 0; -} - -void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) -{ - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - - /*6x86 can decode 1 prefix per instruction per clock with no penalty. If - either instruction has more than one prefix then decode is delayed by - one cycle for each additional prefix*/ - decode_delay++; - last_prefix = prefix; -} - -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) -{ - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - - if (addr_regmask & IMPL_ESP) - addr_regmask |= (1 << REG_ESP); - - if (regmask_modified & addr_regmask) - { - regmask_modified = 0; - return 2; - } - - if (last_regmask_modified & addr_regmask) - return 1; - - return 0; -} - -void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) -{ - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; - - default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: - timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; - - if (prev_full) - { - uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); - int agi_stall = 0; - - if (regmask & IMPL_ESP) - regmask |= SRCDEP_ESP | DSTDEP_ESP; - - agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); - - /*Second instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (prev_regmask & regmask) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else - { - int t1 = COUNT(prev_timings[prev_opcode], prev_op_32); - int t2 = COUNT(timings[opcode], op_32); - int t_pair = (t1 > t2) ? t1 : t2; - - if (!t_pair) - fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += t_pair + agi_stall; - decode_delay = (-t_pair) + 1 + agi_stall; - - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; - prev_full = 0; - return; - } - } - - if (!prev_full) - { - /*First instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - { - /*Instruction not pairable*/ - int agi_stall = 0; - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - } - else - { - /*Instruction might pair with next*/ - prev_full = 1; - prev_opcode = opcode; - prev_timings = timings; - prev_op_32 = op_32; - prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - if (prev_regmask & IMPL_ESP) - prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; - prev_deps = deps; - prev_fetchdat = fetchdat; - return; - } - } -} - -void codegen_timing_686_block_end() -{ - if (prev_full) - { - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - prev_full = 0; - } -} - -codegen_timing_t codegen_timing_686 = -{ - codegen_timing_686_start, - codegen_timing_686_prefix, - codegen_timing_686_opcode, - codegen_timing_686_block_start, - codegen_timing_686_block_end -}; diff --git a/src - Cópia/cpu/codegen_timing_common.c b/src - Cópia/cpu/codegen_timing_common.c deleted file mode 100644 index f53a8fc4d..000000000 --- a/src - Cópia/cpu/codegen_timing_common.c +++ /dev/null @@ -1,684 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "cpu.h" -#include "codegen_timing_common.h" - - -uint64_t opcode_deps[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* ADD ADD PUSH ES POP ES*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* OR OR OR OR*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, - -/* ADC ADC ADC ADC*/ -/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* SBB SBB SBB SBB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, - -/* AND AND AND AND*/ -/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* SUB SUB SUB SUB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* XOR XOR XOR XOR*/ -/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* CMP CMP CMP CMP*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, -/* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, - 0, 0, 0, 0, -/* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM, -/* INSB INSW OUTSB OUTSW*/ - 0, 0, 0, 0, - -/* Jxx*/ -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, -/* TEST TEST XCHG XCHG*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* MOV MOV MOV MOV*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, -/* MOV from seg LEA MOV to seg POP*/ - MODRM, DSTDEP_REG | MODRM, MODRM, IMPL_ESP | MODRM, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, -/* XCHG XCHG XCHG XCHG*/ - SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, -/* CBW CWD CALL far WAIT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, -/* PUSHF POPF SAHF LAHF*/ - IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, - -/* MOV MOV MOV MOV*/ -/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* MOVSB MOVSW CMPSB CMPSW*/ - 0, 0, 0, 0, -/* TEST TEST STOSB STOSW*/ - SRCDEP_EAX, SRCDEP_EAX, 0, 0, -/* LODSB LODSW SCASB SCASW*/ - 0, 0, 0, 0, - -/* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, - -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM, -/* ENTER LEAVE RETF RETF*/ - IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, -/* INT3 INT INTO IRET*/ - 0, 0, 0, 0, - - -/*d0*/ 0, 0, 0, 0, -/* AAM AAD SETALC XLAT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, -/* IN AL IN AX OUT_AL OUT_AX*/ - DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* CALL JMP JMP JMP*/ - IMPL_ESP, 0, 0, 0, -/* IN AL IN AX OUT_AL OUT_AX*/ - SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, - -/* REPNE REPE*/ -/*f0*/ 0, 0, 0, 0, -/* HLT CMC*/ - 0, 0, 0, 0, -/* CLC STC CLI STI*/ - 0, 0, 0, 0, -/* CLD STD INCDEC*/ - 0, 0, MODRM, 0 -}; - -uint64_t opcode_deps_mod3[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* ADD ADD PUSH ES POP ES*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* OR OR OR OR*/ - SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, - -/* ADC ADC ADC ADC*/ -/*10*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* SBB SBB SBB SBB*/ - SRCDEP_REG |SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, - -/* AND AND AND AND*/ -/*20*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* SUB SUB SUB SUB*/ - SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* XOR XOR XOR XOR*/ -/*30*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, -/* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* CMP CMP CMP CMP*/ - SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, -/* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, - 0, 0, 0, 0, -/* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, -/* INSB INSW OUTSB OUTSW*/ - 0, 0, 0, 0, - -/* Jxx*/ -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, -/* TEST TEST XCHG XCHG*/ - SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, -/* MOV MOV MOV MOV*/ - SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, -/* MOV from seg LEA MOV to seg POP*/ - DSTDEP_RM | MODRM, DSTDEP_REG | MODRM, SRCDEP_RM | MODRM, IMPL_ESP | DSTDEP_RM | MODRM, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, -/* XCHG XCHG XCHG XCHG*/ - SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, -/* CBW CWD CALL far WAIT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, -/* PUSHF POPF SAHF LAHF*/ - IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, - -/* MOV MOV MOV MOV*/ -/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* MOVSB MOVSW CMPSB CMPSW*/ - 0, 0, 0, 0, -/* TEST TEST STOSB STOSW*/ - SRCDEP_EAX, SRCDEP_EAX, 0, 0, -/* LODSB LODSW SCASB SCASW*/ - 0, 0, 0, 0, - -/* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, - -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM, -/* ENTER LEAVE RETF RETF*/ - IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, -/* INT3 INT INTO IRET*/ - 0, 0, 0, 0, - - -/*d0*/ 0, 0, 0, 0, -/* AAM AAD SETALC XLAT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, -/* IN AL IN AX OUT_AL OUT_AX*/ - DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* CALL JMP JMP JMP*/ - IMPL_ESP, 0, 0, 0, -/* IN AL IN AX OUT_AL OUT_AX*/ - SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, - -/* REPNE REPE*/ -/*f0*/ 0, 0, 0, 0, -/* HLT CMC*/ - 0, 0, 0, 0, -/* CLC STC CLI STI*/ - 0, 0, 0, 0, -/* CLD STD INCDEC*/ - 0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0 -}; - -uint64_t opcode_deps_0f[256] = -{ -/*00*/ MODRM, MODRM, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*20*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, MODRM, - MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, 0, MODRM, MODRM, - -/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, 0, - 0, 0, 0, 0, - 0, 0, MODRM, MODRM, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*a0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*b0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - 0, 0, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*c0*/ MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, MODRM, 0, - MODRM, MODRM, MODRM, 0, -}; -uint64_t opcode_deps_0f_mod3[256] = -{ -/*00*/ MODRM, MODRM, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*20*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, MODRM, - MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, 0, MODRM, MODRM, - -/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, 0, - 0, 0, 0, 0, - 0, 0, MODRM, MODRM, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*a0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*b0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - 0, 0, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*c0*/ MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, MODRM, 0, - MODRM, MODRM, MODRM, 0, -}; - -uint64_t opcode_deps_shift[8] = -{ - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, -}; -uint64_t opcode_deps_shift_mod3[8] = -{ - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, -}; - -uint64_t opcode_deps_shift_cl[8] = -{ - MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, - MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, -}; -uint64_t opcode_deps_shift_cl_mod3[8] = -{ - SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, - SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, -}; - -uint64_t opcode_deps_f6[8] = -{ -/* TST NOT NEG*/ - MODRM, 0, MODRM, MODRM, -/* MUL IMUL DIV IDIV*/ - SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM -}; -uint64_t opcode_deps_f6_mod3[8] = -{ -/* TST NOT NEG*/ - SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, -/* MUL IMUL DIV IDIV*/ - SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM -}; -uint64_t opcode_deps_f7[8] = -{ -/* TST NOT NEG*/ - MODRM, 0, MODRM, MODRM, -/* MUL IMUL DIV IDIV*/ - SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM -}; -uint64_t opcode_deps_f7_mod3[8] = -{ -/* TST NOT NEG*/ - SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, -/* MUL IMUL DIV IDIV*/ - SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM -}; -uint64_t opcode_deps_ff[8] = -{ -/* INC DEC CALL CALL far*/ - MODRM, MODRM, MODRM | IMPL_ESP, MODRM, -/* JMP JMP far PUSH*/ - MODRM, MODRM, MODRM | IMPL_ESP, 0 -}; -uint64_t opcode_deps_ff_mod3[8] = -{ -/* INC DEC CALL CALL far*/ - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM, -/* JMP JMP far PUSH*/ - SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0 -}; - -uint64_t opcode_deps_d8[8] = -{ -/* FADDs FMULs FCOMs FCOMPs*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM, -/* FSUBs FSUBRs FDIVs FDIVRs*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM -}; -uint64_t opcode_deps_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP*/ - FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG, -/* FSUB FSUBR FDIV FDIVR*/ - FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG -}; - -uint64_t opcode_deps_d9[8] = -{ -/* FLDs FSTs FSTPs*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM, -/* FLDENV FLDCW FSTENV FSTCW*/ - MODRM, MODRM, MODRM, MODRM -}; -uint64_t opcode_deps_d9_mod3[64] = -{ - /*FLD*/ - FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, - FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, - /*FXCH*/ - FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, - FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, - /*FNOP*/ - 0, 0, 0, 0, 0, 0, 0, 0, - /*FSTP*/ - FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, - FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, -/* opFCHS opFABS*/ - 0, 0, 0, 0, -/* opFTST opFXAM*/ - 0, 0, 0, 0, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - FPU_PUSH, FPU_PUSH, FPU_PUSH, FPU_PUSH, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - FPU_PUSH, FPU_PUSH, FPU_PUSH, 0, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - 0, 0, 0, 0, -/* opFDECSTP opFINCSTP,*/ - 0, 0, 0, 0, -/* opFPREM opFSQRT opFSINCOS*/ - 0, 0, 0, 0, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - 0, 0, 0, 0 -}; - -uint64_t opcode_deps_da[8] = -{ -/* FIADDl FIMULl FICOMl FICOMPl*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM -}; -uint64_t opcode_deps_da_mod3[8] = -{ - 0, 0, 0, 0, -/* FCOMPP*/ - 0, FPU_POP2, 0, 0 -}; - - -uint64_t opcode_deps_db[8] = -{ -/* FLDil FSTil FSTPil*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FLDe FSTPe*/ - 0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM -}; -uint64_t opcode_deps_db_mod3[64] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - - 0, 0, 0, 0, 0, 0, 0, 0, - -/* opFNOP opFCLEX opFINIT*/ - 0, 0, 0, 0, -/* opFNOP opFNOP*/ - 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -uint64_t opcode_deps_dc[8] = -{ -/* FADDd FMULd FCOMd FCOMPd*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FSUBd FSUBRd FDIVd FDIVRd*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM -}; -uint64_t opcode_deps_dc_mod3[8] = -{ -/* opFADDr opFMULr*/ - FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG -}; - -uint64_t opcode_deps_dd[8] = -{ -/* FLDd FSTd FSTPd*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FRSTOR FSAVE FSTSW*/ - MODRM, 0, MODRM, MODRM -}; -uint64_t opcode_deps_dd_mod3[8] = -{ -/* FFFREE FST FSTP*/ - 0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, -/* FUCOM FUCOMP*/ - FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0 -}; - -uint64_t opcode_deps_de[8] = -{ -/* FIADDw FIMULw FICOMw FICOMPw*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM -}; -uint64_t opcode_deps_de_mod3[8] = -{ -/* FADDP FMULP FCOMPP*/ - FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2, -/* FSUBP FSUBRP FDIVP FDIVRP*/ - FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP -}; - -uint64_t opcode_deps_df[8] = -{ -/* FILDiw FISTiw FISTPiw*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FILDiq FBSTP FISTPiq*/ - 0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM -}; -uint64_t opcode_deps_df_mod3[8] = -{ - 0, 0, 0, 0, -/* FSTSW AX*/ - 0, 0, 0, 0 -}; - -uint64_t opcode_deps_81[8] = -{ - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM -}; -uint64_t opcode_deps_81_mod3[8] = -{ - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM -}; -uint64_t opcode_deps_8x[8] = -{ - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM -}; -uint64_t opcode_deps_8x_mod3[8] = -{ - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM -}; diff --git a/src - Cópia/cpu/codegen_timing_common.h b/src - Cópia/cpu/codegen_timing_common.h deleted file mode 100644 index 19856ed99..000000000 --- a/src - Cópia/cpu/codegen_timing_common.h +++ /dev/null @@ -1,226 +0,0 @@ -#include "codegen_ops.h" - -/*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1ull << 0) -/*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) -/*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1ull << 2) -/*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) - -#define SRCDEP_SHIFT 4 -#define DSTDEP_SHIFT 12 - -/*Instruction has input dependency on given register*/ -#define SRCDEP_EAX (1ull << 4) -#define SRCDEP_ECX (1ull << 5) -#define SRCDEP_EDX (1ull << 6) -#define SRCDEP_EBX (1ull << 7) -#define SRCDEP_ESP (1ull << 8) -#define SRCDEP_EBP (1ull << 9) -#define SRCDEP_ESI (1ull << 10) -#define SRCDEP_EDI (1ull << 11) - -/*Instruction modifies given register*/ -#define DSTDEP_EAX (1ull << 12) -#define DSTDEP_ECX (1ull << 13) -#define DSTDEP_EDX (1ull << 14) -#define DSTDEP_EBX (1ull << 15) -#define DSTDEP_ESP (1ull << 16) -#define DSTDEP_EBP (1ull << 17) -#define DSTDEP_ESI (1ull << 18) -#define DSTDEP_EDI (1ull << 19) - -/*Instruction has ModR/M byte*/ -#define MODRM (1ull << 20) -/*Instruction implicitly uses ESP*/ -#define IMPL_ESP (1ull << 21) - -/*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1ull << 22) -/*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) - -/*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) -/*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) -/*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) - -/*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) -/*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) -/*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) - -/*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) -/*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) -/*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) - -/*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) -/*Instruction writes to ST(reg)*/ -#define FPU_WRITE_STREG (1ull << 32) -/*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 30) - -#define FPU_FXCH (1ull << 33) - - -#define REGMASK_IMPL_ESP (1 << 8) -#define REGMASK_SHIFTPACK (1 << 9) -#define REGMASK_MULTIPLY (1 << 9) - - -extern uint64_t opcode_deps[256]; -extern uint64_t opcode_deps_mod3[256]; -extern uint64_t opcode_deps_0f[256]; -extern uint64_t opcode_deps_0f_mod3[256]; -extern uint64_t opcode_deps_shift[8]; -extern uint64_t opcode_deps_shift_mod3[8]; -extern uint64_t opcode_deps_shift_cl[8]; -extern uint64_t opcode_deps_shift_cl_mod3[8]; -extern uint64_t opcode_deps_f6[8]; -extern uint64_t opcode_deps_f6_mod3[8]; -extern uint64_t opcode_deps_f7[8]; -extern uint64_t opcode_deps_f7_mod3[8]; -extern uint64_t opcode_deps_ff[8]; -extern uint64_t opcode_deps_ff_mod3[8]; -extern uint64_t opcode_deps_d8[8]; -extern uint64_t opcode_deps_d8_mod3[8]; -extern uint64_t opcode_deps_d9[8]; -extern uint64_t opcode_deps_d9_mod3[64]; -extern uint64_t opcode_deps_da[8]; -extern uint64_t opcode_deps_da_mod3[8]; -extern uint64_t opcode_deps_db[8]; -extern uint64_t opcode_deps_db_mod3[64]; -extern uint64_t opcode_deps_dc[8]; -extern uint64_t opcode_deps_dc_mod3[8]; -extern uint64_t opcode_deps_dd[8]; -extern uint64_t opcode_deps_dd_mod3[8]; -extern uint64_t opcode_deps_de[8]; -extern uint64_t opcode_deps_de_mod3[8]; -extern uint64_t opcode_deps_df[8]; -extern uint64_t opcode_deps_df_mod3[8]; -extern uint64_t opcode_deps_81[8]; -extern uint64_t opcode_deps_81_mod3[8]; -extern uint64_t opcode_deps_8x[8]; -extern uint64_t opcode_deps_8x_mod3[8]; - - - -static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) -{ - uint32_t addr_regmask = 0; - - if (data & MODRM) - { - uint8_t modrm = fetchdat & 0xff; - - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { - uint8_t sib = (fetchdat >> 8) & 0xff; - - if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) - { - addr_regmask = 1 << (sib & 7); - if ((sib & 0x38) != 0x20) - addr_regmask |= 1 << ((sib >> 3) & 7); - } - } - else if ((modrm & 0xc7) != 5) - { - addr_regmask = 1 << (modrm & 7); - } - } - else - { - if ((modrm & 0xc7) != 0x06) - { - switch (modrm & 7) - { - case 0: addr_regmask = REG_BX | REG_SI; break; - case 1: addr_regmask = REG_BX | REG_DI; break; - case 2: addr_regmask = REG_BP | REG_SI; break; - case 3: addr_regmask = REG_BP | REG_DI; break; - case 4: addr_regmask = REG_SI; break; - case 5: addr_regmask = REG_DI; break; - case 6: addr_regmask = REG_BP; break; - case 7: addr_regmask = REG_BX; break; - } - } - } - } - } - - if (data & IMPL_ESP) - addr_regmask |= REGMASK_IMPL_ESP; - - return addr_regmask; -} - -static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) -{ - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> SRCDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - - mask |= get_addr_regmask(data, fetchdat, op_32); - - return mask; -} - -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> DSTDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - if (data & IMPL_ESP) - mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); - - return mask; -} diff --git a/src - Cópia/cpu/codegen_timing_pentium.c b/src - Cópia/cpu/codegen_timing_pentium.c deleted file mode 100644 index 60a6fbea0..000000000 --- a/src - Cópia/cpu/codegen_timing_pentium.c +++ /dev/null @@ -1,1322 +0,0 @@ -/*Elements taken into account : - - U/V integer pairing - - FPU/FXCH pairing - - Prefix decode delay (including shadowing) - - FPU latencies - - AGI stalls - Elements not taken into account : - - Branch prediction (beyond most simplistic approximation) - - PMMX decode queue - - MMX latencies -*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "cpu.h" -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "codegen.h" -#include "codegen_ops.h" -#include "codegen_timing_common.h" - - -/*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 28) - -#define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) - -/*Instruction lasts given number of cycles. Does not pair*/ -#define CYCLES(c) (c | PAIR_NP) - - -static int pair_timings[4][4] = -{ -/* Reg RM RMW Branch*/ -/*Reg*/ {1, 2, 3, 2}, -/*RM*/ {2, 2, 3, 3}, -/*RMW*/ {3, 4, 5, 4}, -/*Branch*/ {-1, -1, -1, -1} -}; - -/*Instruction follows either register timing, read-modify, or read-modify-write. - May be pairable*/ -#define CYCLES_REG (0ull << 0) -#define CYCLES_RM (1ull << 0) -#define CYCLES_RMW (2ull << 0) -#define CYCLES_BRANCH (3ull << 0) - -/*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/ -#define CYCLES_HASIMM (3ull << 2) -#define CYCLES_IMM8 (1ull << 2) -#define CYCLES_IMM1632 (2ull << 2) - -#define CYCLES_MASK ((1ull << 7) - 1) - - -/*Instruction does not pair*/ -#define PAIR_NP (0ull << 29) -/*Instruction pairs in U pipe only*/ -#define PAIR_U (1ull << 29) -/*Instruction pairs in V pipe only*/ -#define PAIR_V (2ull << 29) -/*Instruction pairs in both U and V pipes*/ -#define PAIR_UV (3ull << 29) -/*Instruction pairs in U pipe only and only with FXCH*/ -#define PAIR_FX (5ull << 29) -/*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/ -#define PAIR_FXCH (6ull << 29) - -#define PAIR_FPU (4ull << 29) - -#define PAIR_MASK (7ull << 29) - - -/*comp_time = cycles until instruction complete - i_overlap = cycles that overlap with integer - f_overlap = cycles that overlap with subsequent FPU*/ -#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t)comp_time) | ((uint64_t)i_overlap << 41) | ((uint64_t)f_overlap << 49) | PAIR_FPU - -#define FPU_COMP_TIME(timing) (timing & 0xff) -#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) -#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) - -#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) - -#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) - -#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) - - -#define INVALID 0 - -static int u_pipe_full; -static uint32_t u_pipe_opcode; -static uint64_t *u_pipe_timings; -static uint32_t u_pipe_op_32; -static uint32_t u_pipe_regmask; -static uint32_t u_pipe_fetchdat; -static int u_pipe_decode_delay_offset; -static uint64_t *u_pipe_deps; - -static uint32_t regmask_modified; - -static uint32_t addr_regmask; - -static int fpu_latency; -static int fpu_st_latency[8]; - -static uint64_t opcode_timings[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* ADD ADD PUSH ES POP ES*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, -/* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, -/* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* AND AND DAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* SUB SUB SUB SUB*/ - PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* CMP CMP CMP CMP*/ - PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(13), - -/* Jxx*/ -/*70*/ PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, CYCLES(3), PAIR_NP | CYCLES(3), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1), -/* PUSHF POPF SAHF LAHF*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), - -/* MOV*/ -/*b0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), -/* CALL JMP JMP JMP*/ - PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), -/* CLD STD INCDEC*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_RMW, INVALID -}; - -static uint64_t opcode_timings_mod3[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* ADD ADD PUSH ES POP ES*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* AND AND DAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* SUB SUB SUB SUB*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* CMP CMP CMP CMP*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(13), - -/* Jxx*/ -/*70*/ PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - -/*80*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1), -/* PUSHF POPF SAHF LAHF*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), - -/* MOV*/ -/*b0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), -/* CALL JMP JMP JMP*/ - PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), -/* CLD STD INCDEC*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_REG, INVALID -}; - -static uint64_t opcode_timings_0f[256] = -{ -/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), - INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, - PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - -/*70*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - -/*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/*90*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*a0*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(8), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), INVALID, INVALID, - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - INVALID, INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - -/*e0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - -/*f0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, -}; -static uint64_t opcode_timings_0f_mod3[256] = -{ -/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), - INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, - PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/*70*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/*90*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*a0*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(8), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), INVALID, INVALID, - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - INVALID, INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - -/*e0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, - INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - -/*f0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, -}; - -static uint64_t opcode_timings_shift[8] = -{ - PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, - PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, -}; -static uint64_t opcode_timings_shift_mod3[8] = -{ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, -}; - -static uint64_t opcode_timings_f6[8] = -{ -/* TST NOT NEG*/ - PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) -}; -static uint64_t opcode_timings_f6_mod3[8] = -{ -/* TST NOT NEG*/ - PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) -}; -static uint64_t opcode_timings_f7[8] = -{ -/* TST NOT NEG*/ - PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) -}; -static uint64_t opcode_timings_f7_mod3[8] = -{ -/* TST NOT NEG*/ - PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MUL IMUL DIV IDIV*/ - PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) -}; -static uint64_t opcode_timings_ff[8] = -{ -/* INC DEC CALL CALL far*/ - PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), -/* JMP JMP far PUSH*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID -}; -static uint64_t opcode_timings_ff_mod3[8] = -{ -/* INC DEC CALL CALL far*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), -/* JMP JMP far PUSH*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID -}; - -static uint64_t opcode_timings_d8[8] = -{ -/* FADDs FMULs FCOMs FCOMPs*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), -/* FSUBs FSUBRs FDIVs FDIVRs*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) -}; -static uint64_t opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), -/* FSUB FSUBR FDIV FDIVR*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) -}; - -static uint64_t opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs*/ - PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), -/* FLDENV FLDCW FSTENV FSTCW*/ - PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0) -}; -static uint64_t opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), - PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), - /*FXCH*/ - PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), - PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), - /*FNOP*/ - PAIR_NP | FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), -/* opFCHS opFABS*/ - PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), INVALID, INVALID, -/* opFTST opFXAM*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(21,4,0), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(2,0,0), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - PAIR_NP | FPU_CYCLES(53,2,2), PAIR_NP | FPU_CYCLES(103,2,2), PAIR_NP | FPU_CYCLES(120,36,0), PAIR_NP | FPU_CYCLES(112,2,2), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), -/* opFPREM opFSQRT opFSINCOS*/ - PAIR_NP | FPU_CYCLES(64,2,2), INVALID, PAIR_NP | FPU_CYCLES(70,69,2), PAIR_NP | FPU_CYCLES(89,2,2), -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - PAIR_NP | FPU_CYCLES(9,0,0), PAIR_NP | FPU_CYCLES(20,5,0), PAIR_NP | FPU_CYCLES(65,2,2), PAIR_NP | FPU_CYCLES(65,2,2) -}; - -static uint64_t opcode_timings_da[8] = -{ -/* FIADDl FIMULl FICOMl FICOMPl*/ - PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) -}; -static uint64_t opcode_timings_da_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID -}; - - -static uint64_t opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil*/ - PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), -/* FLDe FSTPe*/ - INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0) -}; -static uint64_t opcode_timings_db_mod3[64] = -{ - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* opFNOP opFCLEX opFINIT*/ - INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(7,0,0), PAIR_NP | FPU_CYCLES(17,0,0), -/* opFNOP opFNOP*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static uint64_t opcode_timings_dc[8] = -{ -/* FADDd FMULd FCOMd FCOMPd*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), -/* FSUBd FSUBRd FDIVd FDIVRd*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) -}; -static uint64_t opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) -}; - -static uint64_t opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd*/ - PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), -/* FRSTOR FSAVE FSTSW*/ - PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0) -}; -static uint64_t opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP*/ - PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), -/* FUCOM FUCOMP*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID -}; - -static uint64_t opcode_timings_de[8] = -{ -/* FIADDw FIMULw FICOMw FICOMPw*/ - PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) -}; -static uint64_t opcode_timings_de_mod3[8] = -{ -/* FADDP FMULP FCOMPP*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0), -/* FSUBP FSUBRP FDIVP FDIVRP*/ - PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) -}; - -static uint64_t opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw*/ - PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), -/* FILDiq FBSTP FISTPiq*/ - INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0) -}; -static uint64_t opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - PAIR_NP | FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID -}; - -static uint64_t opcode_timings_81[8] = -{ - PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, - PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632 -}; -static uint64_t opcode_timings_81_mod3[8] = -{ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG -}; -static uint64_t opcode_timings_8x[8] = -{ - PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, - PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8 -}; -static uint64_t opcode_timings_8x_mod3[8] = -{ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG -}; - -static int decode_delay, decode_delay_offset; -static uint8_t last_prefix; -static int prefixes; - -static inline int COUNT(uint64_t timings, uint64_t deps, int op_32) -{ - if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) - return FPU_I_LATENCY(timings); - if (timings & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)timings >> 8) & 0xff; - return (uintptr_t)timings & 0xff; - } - if (!(timings & PAIR_MASK)) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FX) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FXCH) - return timings & 0xffff; - if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) - timings &= 3; - switch (timings & CYCLES_MASK) - { - case CYCLES_REG: - return 1; - case CYCLES_RM: - return 2; - case CYCLES_RMW: - return 3; - case CYCLES_BRANCH: - return cpu_hasMMX ? 1 : 2; - } - - fatal("Illegal COUNT %016llx\n", timings); - - return timings; -} - -static int codegen_fpu_latencies(uint64_t deps, int reg) -{ - int latency = fpu_latency; - - if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) - latency = fpu_st_latency[0]; - if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) - latency = fpu_st_latency[1]; - if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) - latency = fpu_st_latency[reg]; - - return latency; -} - -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 - -static void codegen_fpu_latency_clock(int count) -{ - SUB_AND_CLAMP(fpu_latency, count); - SUB_AND_CLAMP(fpu_st_latency[0], count); - SUB_AND_CLAMP(fpu_st_latency[1], count); - SUB_AND_CLAMP(fpu_st_latency[2], count); - SUB_AND_CLAMP(fpu_st_latency[3], count); - SUB_AND_CLAMP(fpu_st_latency[4], count); - SUB_AND_CLAMP(fpu_st_latency[5], count); - SUB_AND_CLAMP(fpu_st_latency[6], count); - SUB_AND_CLAMP(fpu_st_latency[7], count); -} - -static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) -{ - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /*Has SIB*/ - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) - return 1; - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) - return 1; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) - return 1; - } - return 0; -} - -/*The instruction is only of interest here if it's longer than 7 bytes, as that's the - limit on Pentium MMX parallel decoding*/ -static inline int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) -{ - int len = prefixes; - if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) - { - len += 2; /*Opcode + ModR/M*/ - if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) - len++; - if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; - - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } - } - - return len; -} - -void codegen_timing_pentium_block_start() -{ - u_pipe_full = decode_delay = decode_delay_offset = 0; -} - -void codegen_timing_pentium_start() -{ - last_prefix = 0; - prefixes = 0; -} - -void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) -{ - prefixes++; - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (cpu_hasMMX && prefix == 0x0f) - { - /*On Pentium MMX 0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - if (cpu_hasMMX && (prefix == 0x66 || prefix == 0x67)) - { - /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ - decode_delay_offset += 2; - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; - last_prefix = prefix; -} - -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) -{ - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - - /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not - cause AGIs with each other, but do with instructions that use it explicitly*/ - if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) - addr_regmask |= (1 << REG_ESP); - - return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; -} - -static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) -{ - int instr_cycles, latency = 0; - - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - { -/* if (timings[opcode] & FPU_WRITE_ST0) - fatal("FPU_WRITE_ST0\n"); - if (timings[opcode] & FPU_WRITE_ST1) - fatal("FPU_WRITE_ST1\n"); - if (timings[opcode] & FPU_WRITE_STREG) - fatal("FPU_WRITE_STREG\n");*/ - instr_cycles = 0; - } - - if ((decode_delay + decode_delay_offset) > 0) - codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); - else - codegen_fpu_latency_clock(instr_cycles); - instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); - instr_cycles += exec_delay; - if ((decode_delay + decode_delay_offset) > 0) - codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; - else - codegen_block_cycles += instr_cycles; - - decode_delay = (-instr_cycles) + 1; - - if (deps[opcode] & FPU_POP) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c] = fpu_st_latency[c+1]; - fpu_st_latency[7] = 0; - } - if (deps[opcode] & FPU_POP2) - { - int c; - - for (c = 0; c < 6; c++) - fpu_st_latency[c] = fpu_st_latency[c+2]; - fpu_st_latency[6] = fpu_st_latency[7] = 0; - } - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } - - if (deps[opcode] & FPU_PUSH) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c+1] = fpu_st_latency[c]; - fpu_st_latency[0] = 0; - } - if (deps[opcode] & FPU_WRITE_ST0) - { -/* if (fpu_st_latency[0]) - fatal("Bad latency ST0\n");*/ - fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_ST1) - { -/* if (fpu_st_latency[1]) - fatal("Bad latency ST1\n");*/ - fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps[opcode] & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) - { -/* if (fpu_st_latency[reg]) - fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ - fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); - } - } -} - -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) -{ - uint64_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; - - default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (u_pipe_full) - { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) != PAIR_FXCH) - goto nopair; - - if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && - (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) - goto nopair; - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) == PAIR_FXCH) - { - int temp; - - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - - temp = fpu_st_latency[fetchdat & 7]; - fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; - fpu_st_latency[0] = temp; - - u_pipe_full = 0; - decode_delay_offset = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; - return; - } - - if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; - int t2 = timings[opcode] & CYCLES_MASK; - int t_pair; - uint64_t temp_timing; - uint64_t temp_deps = 0; - - if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) - t1 &= 3; - if (!(timings[opcode] & PAIR_FPU)) - t2 &= 3; - - if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) - fatal("Pair out of range\n"); - - t_pair = pair_timings[t1][t2]; - if (t_pair < 1) - fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); - - /*Instruction can pair with previous*/ - temp_timing = t_pair; - if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); - u_pipe_full = 0; - decode_delay_offset = 0; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; - addr_regmask = 0; - return; - } - } -nopair: - /*Instruction can not pair with previous*/ - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; - } - - if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - /*Instruction might pair with next*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - u_pipe_fetchdat = fetchdat; - u_pipe_decode_delay_offset = decode_delay_offset; - u_pipe_deps = deps; - decode_delay_offset = 0; - return; - } - } - /*Instruction can not pair and must run now*/ - if (check_agi(deps, opcode, fetchdat, op_32)) - agi_stall = 1; - codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - addr_regmask = 0; -} - -void codegen_timing_pentium_block_end() -{ - if (u_pipe_full) - { - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - codegen_block_cycles++; - codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; - u_pipe_full = 0; - } -} - -codegen_timing_t codegen_timing_pentium = -{ - codegen_timing_pentium_start, - codegen_timing_pentium_prefix, - codegen_timing_pentium_opcode, - codegen_timing_pentium_block_start, - codegen_timing_pentium_block_end -}; diff --git a/src - Cópia/cpu/codegen_timing_winchip.c b/src - Cópia/cpu/codegen_timing_winchip.c deleted file mode 100644 index 93717c4a6..000000000 --- a/src - Cópia/cpu/codegen_timing_winchip.c +++ /dev/null @@ -1,420 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "cpu.h" -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "../mem.h" -#include "codegen.h" -#include "codegen_ops.h" -#include "codegen_timing_common.h" - -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) - -static int *opcode_timings[256] = -{ -/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, -/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), -/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), -/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), -/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL -}; - -static int *opcode_timings_mod3[256] = -{ -/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, -/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), -/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), -/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), -/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL -}; - -static int *opcode_timings_0f[256] = -{ -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, -/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, -/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, -/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, -}; -static int *opcode_timings_0f_mod3[256] = -{ -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, -/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, -/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, -/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, -}; - -static int *opcode_timings_shift[8] = -{ - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) -}; -static int *opcode_timings_shift_mod3[8] = -{ - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) -}; - -static int *opcode_timings_f6[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f6_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f7[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_f7_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_ff[8] = -{ - &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; -static int *opcode_timings_ff_mod3[8] = -{ - &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; - -static int *opcode_timings_d8[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ - CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ - CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) -}; -static int *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - /*FXCH*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FNOP*/ - CYCLES(7), NULL, NULL, NULL, NULL, NULL, NULL, NULL, - /*FSTP*/ - CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/* opFCHS opFABS opFTST opFXAM*/ - CYCLES(2), CYCLES(2), NULL, NULL, CYCLES(5), CYCLES(7), NULL, NULL, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/ - CYCLES(5), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(5), NULL, -/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/ - CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3), -/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ - CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474) -}; - -static int *opcode_timings_da[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_da_mod3[8] = -{ - NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL -}; - - -static int *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil FLDe FSTPe*/ - CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) -}; -static int *opcode_timings_db_mod3[64] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/ - NULL, CYCLES(7), CYCLES(18), CYCLES(27), CYCLES(7), CYCLES(7), NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -static int *opcode_timings_dc[8] = -{ -/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ - CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74) -}; -static int *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ - CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) -}; -static int *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL -}; - -static int *opcode_timings_de[8] = -{ -/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_de_mod3[8] = -{ -/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ - CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ - CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) -}; -static int *opcode_timings_df_mod3[8] = -{ -/* FFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL -}; - -static int *opcode_timings_8x[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_8x_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; - -static int timing_count; -static uint8_t last_prefix; -static uint32_t regmask_modified; - -static inline int COUNT(int *c, int op_32) -{ - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; -} - -void codegen_timing_winchip_block_start() -{ - regmask_modified = 0; -} - -void codegen_timing_winchip_start() -{ - timing_count = 0; - last_prefix = 0; -} - -void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) -{ - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; -} - -void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) -{ - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; - - default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); -} - -void codegen_timing_winchip_block_end() -{ -} - -codegen_timing_t codegen_timing_winchip = -{ - codegen_timing_winchip_start, - codegen_timing_winchip_prefix, - codegen_timing_winchip_opcode, - codegen_timing_winchip_block_start, - codegen_timing_winchip_block_end -}; diff --git a/src - Cópia/cpu/codegen_x86-64.c b/src - Cópia/cpu/codegen_x86-64.c deleted file mode 100644 index 7f373c163..000000000 --- a/src - Cópia/cpu/codegen_x86-64.c +++ /dev/null @@ -1,1195 +0,0 @@ -#ifdef __amd64__ - -#include -#include -#include -#include -#define HAVE_STDARG_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 "386_common.h" - -#include "codegen.h" -#include "codegen_ops.h" -#include "codegen_ops_x86-64.h" - -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if WIN64 -#include -#endif - -int codegen_flat_ds, codegen_flat_ss; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_fpu_loaded_iq[8]; -int codegen_reg_loaded[8]; -x86seg *op_ea_seg; -int op_ssegs; -uint32_t op_old_pc; - -uint32_t recomp_page = -1; - -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; -codeblock_t **codeblock_hash; -int codegen_mmx_entered = 0; - -int block_current = 0; -static int block_num; -int block_pos; - -int cpu_recomp_flushes, cpu_recomp_flushes_latched; -int cpu_recomp_evicted, cpu_recomp_evicted_latched; -int cpu_recomp_reuse, cpu_recomp_reuse_latched; -int cpu_recomp_removed, cpu_recomp_removed_latched; - -uint32_t codegen_endpc; - -int codegen_block_cycles; -static int codegen_block_ins; -static int codegen_block_full_ins; - -static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; - -void codegen_init() -{ - int c; - -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - -#if WIN64 - codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif -} - -void codegen_reset() -{ - int c; - - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); - - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; -} - -void dump_block() -{ -} - -static void add_to_block_list(codeblock_t *block) -{ - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); - - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (block->next->valid == 0) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - } -} - -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (block->valid == 0) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - cpu_recomp_reuse++; - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = 0; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; -#if WIN64 - addbyte(0x48); /*XOR RCX, RCX*/ - addbyte(0x31); - addbyte(0xc9); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); -#else - addbyte(0x48); /*XOR RDI, RDI*/ - addbyte(0x31); - addbyte(0xff); - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); -#endif - call(block, (uintptr_t)x86gpf); - while (block_pos < BLOCK_EXIT_OFFSET) - addbyte(0x90); /*NOP*/ - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH RBX*/ - addbyte(0x55); /*PUSH RBP*/ - addbyte(0x56); /*PUSH RSI*/ - addbyte(0x57); /*PUSH RDI*/ - addbyte(0x41); /*PUSH R12*/ - addbyte(0x54); - addbyte(0x41); /*PUSH R13*/ - addbyte(0x55); - addbyte(0x41); /*PUSH R14*/ - addbyte(0x56); - addbyte(0x41); /*PUSH R15*/ - addbyte(0x57); - addbyte(0x48); /*SUBL $40,%rsp*/ - addbyte(0x83); - addbyte(0xEC); - addbyte(0x28); - addbyte(0x48); /*MOVL RBP, &cpu_state*/ - addbyte(0xBD); - addquad(((uintptr_t)&cpu_state) + 128); - - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; - - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); -} - -void codegen_block_remove() -{ - codeblock_t *block = &codeblock[block_current]; - - delete_block(block); - cpu_recomp_removed++; - - recomp_page = -1; -} - -void codegen_block_generate_end_mask() -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - - block->endpc = codegen_endpc; - - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - block->page_mask |= ((uint64_t)1 << start_pc); - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (block->next_2->valid == 0) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; -} - -void codegen_block_end() -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)codegen_block_cycles); - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_flush() -{ - return; -} - -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug() -{ -} - -static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - if (!cpu_mod && cpu_rm == 6) - { - addbyte(0xC7); /*MOVL $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - int base_reg = 0, index_reg = 0; - - switch (cpu_rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; - } - if (!(cpu_rm & 4)) - { - if (cpu_rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); - } - base_reg &= 7; - index_reg &= 7; - - switch (cpu_mod) - { - case 0: - if (cpu_rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (cpu_mod || !(cpu_rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} -//#if 0 -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - uint32_t new_eaaddr; - - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; - - (*op_pc)++; - - if (cpu_mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - else - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } - else - { - int base_reg; - - if (!cpu_mod && cpu_rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(cpu_rm) & 7; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (cpu_mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } - else - { - addbyte(0x44); /*MOV eaaddr, base_reg*/ - addbyte(0x89); - addbyte(0x45 | (base_reg << 3)); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } - } - return op_ea_seg; -} -//#endif -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - OpFn *op_table = x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; - - op_ea_seg = &_ds; - op_ssegs = 0; - op_old_pc = old_pc; - - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) - { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - op_pc++; - } - -generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32); - - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*Opcode is likely to cause block to exit, update cycle count*/ - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)codegen_block_cycles); - codegen_block_cycles = 0; - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - codegen_block_ins = 0; - } - } - - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } - - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); - - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; - - return; - } - } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; - addbyte(0xC6); /*MOVB $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_ssegs); - } - if ((!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - if (op_ea_seg != last_ea_seg) - { - addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)(uintptr_t)op_ea_seg); - } - - - addbyte(0xC7); /*MOVL [pc],new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc + pc_off); - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); - } - - load_param_1_32(block, fetchdat); - call(block, (uintptr_t)op); - - codegen_block_ins++; - - block->ins++; - - addbyte(0x85); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); - - codegen_endpc = (cs + cpu_state.pc) + 8; -} - -#endif diff --git a/src - Cópia/cpu/codegen_x86-64.h b/src - Cópia/cpu/codegen_x86-64.h deleted file mode 100644 index 648a30342..000000000 --- a/src - Cópia/cpu/codegen_x86-64.h +++ /dev/null @@ -1,23 +0,0 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) & 0x1ffff) - -#define BLOCK_EXIT_OFFSET 0x7e0 -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) - -#define BLOCK_MAX 1620 - -enum -{ - OP_RET = 0xc3 -}; - -#define NR_HOST_REGS 4 -extern int host_reg_mapping[NR_HOST_REGS]; -#define NR_HOST_XMM_REGS 8 -extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; diff --git a/src - Cópia/cpu/codegen_x86.c b/src - Cópia/cpu/codegen_x86.c deleted file mode 100644 index e7d53ea9f..000000000 --- a/src - Cópia/cpu/codegen_x86.c +++ /dev/null @@ -1,2179 +0,0 @@ -/* - * 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. - * - * Dynamic Recompiler for Intel 32-bit systems. - * - * Version: @(#)codegen_x86.c 1.0.3 2018/05/05 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 - -#include -#include -#include -#include -#include -#include "../86box.h" -#include "cpu.h" -#include "../mem.h" -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" - -#include "386_common.h" - -#include "codegen.h" -#include "codegen_ops.h" -#include "codegen_ops_x86.h" - -#ifdef __linux__ -#include -#include -#endif -#if defined _WIN32 -#include -#endif - -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; -uint32_t op_old_pc; - -uint32_t recomp_page = -1; - -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; -codeblock_t **codeblock_hash; - - -int block_current = 0; -static int block_num; -int block_pos; - -int cpu_recomp_flushes, cpu_recomp_flushes_latched; -int cpu_recomp_evicted, cpu_recomp_evicted_latched; -int cpu_recomp_reuse, cpu_recomp_reuse_latched; -int cpu_recomp_removed, cpu_recomp_removed_latched; - -uint32_t codegen_endpc; - -int codegen_block_cycles; -static int codegen_block_ins; -static int codegen_block_full_ins; - -static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; - -static uint32_t mem_abrt_rout; -uint32_t mem_load_addr_ea_b; -uint32_t mem_load_addr_ea_w; -uint32_t mem_load_addr_ea_l; -uint32_t mem_load_addr_ea_q; -uint32_t mem_store_addr_ea_b; -uint32_t mem_store_addr_ea_w; -uint32_t mem_store_addr_ea_l; -uint32_t mem_store_addr_ea_q; -uint32_t mem_load_addr_ea_b_no_abrt; -uint32_t mem_store_addr_ea_b_no_abrt; -uint32_t mem_load_addr_ea_w_no_abrt; -uint32_t mem_store_addr_ea_w_no_abrt; -uint32_t mem_load_addr_ea_l_no_abrt; -uint32_t mem_store_addr_ea_l_no_abrt; -uint32_t mem_check_write; -uint32_t mem_check_write_w; -uint32_t mem_check_write_l; - -static uint32_t gen_MEM_LOAD_ADDR_EA_B() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AL*/ - addbyte(0xb6); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AX*/ - addbyte(0xb7); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+4+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ - addbyte(0x54); - addbyte(0x3a); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemql*/ - addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_B() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememb386l*/ - addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = EBX/ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EDX, ESI*/ - addbyte(0xf2); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+4+1); - addbyte(0x89); /*MOV [EDI+ESI],EBX*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x52); /*PUSH EDX*/ - addbyte(0xe8); /*CALL writememql*/ - addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 16*/ - addbyte(0xc4); - addbyte(16); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AL*/ - addbyte(0xb6); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AX*/ - addbyte(0xb7); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0x83); /*SUBL 4,%esp*/ - addbyte(0xEC); - addbyte(4); - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememb386l*/ - addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 1*/ - addbyte(0xc7); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $fff, EDI*/ - addbyte(0xc7); - addlong(0xfff); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 3*/ - addbyte(0xc7); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 2-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST EDI, FFC*/ - addbyte(0xc7); - addlong(0xffc); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -void codegen_init() -{ -#ifdef __linux__ - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - -#ifdef _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - -#ifdef __linux__ - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif - - block_current = BLOCK_SIZE; - block_pos = 0; - mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; - addbyte(0x83); /*ADDL $16+4,%esp*/ - addbyte(0xC4); - addbyte(0x10+4); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l = (uint32_t)gen_MEM_LOAD_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w = (uint32_t)gen_MEM_LOAD_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b = (uint32_t)gen_MEM_LOAD_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_q = (uint32_t)gen_MEM_LOAD_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l = (uint32_t)gen_MEM_STORE_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w = (uint32_t)gen_MEM_STORE_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b = (uint32_t)gen_MEM_STORE_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_q = (uint32_t)gen_MEM_STORE_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_check_write = (uint32_t)gen_MEM_CHECK_WRITE(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_w = (uint32_t)gen_MEM_CHECK_WRITE_W(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L(); - -#ifndef _MSC_VER - asm( - "fstcw %0\n" - : "=m" (cpu_state.old_npxc) - ); -#else - __asm - { - fstcw cpu_state.old_npxc - } -#endif -} - -void codegen_reset() -{ - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); -} - -void dump_block() -{ -} - -static void add_to_block_list(codeblock_t *block) -{ - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); - - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (!block->next->valid) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - } -} - -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (!block->valid) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - cpu_recomp_reuse++; - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; - addbyte(0xc7); /*MOV [ESP],0*/ - addbyte(0x04); - addbyte(0x24); - addlong(0); - addbyte(0xc7); /*MOV [ESP+4],0*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addlong(0); - addbyte(0xe8); /*CALL x86gpf*/ - addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $16,%esp*/ - addbyte(0xEC); - addbyte(0x10); - addbyte(0xBD); /*MOVL EBP, &cpu_state*/ - addlong(((uintptr_t)&cpu_state) + 128); - - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; - - block->TOP = cpu_state.TOP; - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); -} - -void codegen_block_remove() -{ - codeblock_t *block = &codeblock[block_current]; - - delete_block(block); - cpu_recomp_removed++; - - recomp_page = -1; -} - -void codegen_block_generate_end_mask() -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - - block->endpc = codegen_endpc; - - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - { - block->page_mask |= ((uint64_t)1 << start_pc); - } - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (!block->next_2->valid) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; -} - -void codegen_block_end() -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(codegen_block_cycles); - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - codegen_block_generate_end_mask(); - add_to_block_list(block); - - if (!(block->flags & CODEBLOCK_HAS_FPU)) - block->flags &= ~CODEBLOCK_STATIC_TOP; -} - -void codegen_flush() -{ - return; -} - -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug() -{ -} - -static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - if (!cpu_mod && cpu_rm == 6) - { - addbyte(0xC7); /*MOVL $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - switch (cpu_mod) - { - case 0: - addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - break; - case 1: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((uint32_t)(int8_t)(rmdat >> 8)); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} - -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - uint32_t new_eaaddr; - - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; - (*op_pc)++; - - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 2: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 3: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - else - { - if (!cpu_mod && cpu_rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[cpu_rm].l)); - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (cpu_mod == 1) - { - addbyte(0x05); - addlong((uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - return op_ea_seg; -} - -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - const OpFn *op_table = x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; - - op_ea_seg = &_ds; - op_ssegs = 0; - op_old_pc = old_pc; - - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - mmx_ebx_ecx_loaded = 0; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) - { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; - } - -generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32); - - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*Opcode is likely to cause block to exit, update cycle count*/ - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(codegen_block_cycles); - codegen_block_cycles = 0; - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - codegen_block_ins = 0; - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - codegen_block_full_ins = 0; - } -#endif - } - - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } - - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); - - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; - - return; - } - } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; - - addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_pc + pc_off); - } - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - - if (op_ea_seg != last_ea_seg) - { - last_ea_seg = op_ea_seg; - addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)op_ea_seg); - } - - addbyte(0xC7); /*MOVL pc,new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc + pc_off); - - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); - - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); - } - - addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ - addbyte(0x04); - addbyte(0x24); - addlong(fetchdat); - - addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4]))); - - codegen_block_ins++; - - block->ins++; - - addbyte(0x09); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); - - codegen_endpc = (cs + cpu_state.pc) + 8; -} - -#endif diff --git a/src - Cópia/cpu/codegen_x86.h b/src - Cópia/cpu/codegen_x86.h deleted file mode 100644 index 3a3662d32..000000000 --- a/src - Cópia/cpu/codegen_x86.h +++ /dev/null @@ -1,42 +0,0 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) & 0x1ffff) - -#define BLOCK_EXIT_OFFSET 0x7f0 -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) - -#define BLOCK_MAX 1720 - -enum -{ - OP_RET = 0xc3 -}; - -#define NR_HOST_REGS 4 -extern int host_reg_mapping[NR_HOST_REGS]; -#define NR_HOST_XMM_REGS 8 -extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; - -extern uint32_t mem_load_addr_ea_b; -extern uint32_t mem_load_addr_ea_w; -extern uint32_t mem_load_addr_ea_l; -extern uint32_t mem_load_addr_ea_q; -extern uint32_t mem_store_addr_ea_b; -extern uint32_t mem_store_addr_ea_w; -extern uint32_t mem_store_addr_ea_l; -extern uint32_t mem_store_addr_ea_q; - -extern uint32_t mem_load_addr_ea_b_no_abrt; -extern uint32_t mem_store_addr_ea_b_no_abrt; -extern uint32_t mem_load_addr_ea_w_no_abrt; -extern uint32_t mem_store_addr_ea_w_no_abrt; -extern uint32_t mem_load_addr_ea_l_no_abrt; -extern uint32_t mem_store_addr_ea_l_no_abrt; -extern uint32_t mem_check_write; -extern uint32_t mem_check_write_w; -extern uint32_t mem_check_write_l; diff --git a/src - Cópia/cpu/cpu.c b/src - Cópia/cpu/cpu.c deleted file mode 100644 index cd5804b71..000000000 --- a/src - Cópia/cpu/cpu.c +++ /dev/null @@ -1,2277 +0,0 @@ -/* - * 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. - * - * CPU type handler. - * - * Version: @(#)cpu.c 1.0.6 2018/05/05 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * leilei, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../io.h" -#include "x86_ops.h" -#include "../mem.h" -#include "../pci.h" -#ifdef USE_DYNAREC -# include "codegen.h" -#endif - - -enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_CMPXCHG8B = (1 << 8), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) -}; - - -#ifdef USE_DYNAREC -const OpFn *x86_dynarec_opcodes; -const OpFn *x86_dynarec_opcodes_0f; -const OpFn *x86_dynarec_opcodes_d8_a16; -const OpFn *x86_dynarec_opcodes_d8_a32; -const OpFn *x86_dynarec_opcodes_d9_a16; -const OpFn *x86_dynarec_opcodes_d9_a32; -const OpFn *x86_dynarec_opcodes_da_a16; -const OpFn *x86_dynarec_opcodes_da_a32; -const OpFn *x86_dynarec_opcodes_db_a16; -const OpFn *x86_dynarec_opcodes_db_a32; -const OpFn *x86_dynarec_opcodes_dc_a16; -const OpFn *x86_dynarec_opcodes_dc_a32; -const OpFn *x86_dynarec_opcodes_dd_a16; -const OpFn *x86_dynarec_opcodes_dd_a32; -const OpFn *x86_dynarec_opcodes_de_a16; -const OpFn *x86_dynarec_opcodes_de_a32; -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; -#endif - -const OpFn *x86_opcodes; -const OpFn *x86_opcodes_0f; -const OpFn *x86_opcodes_d8_a16; -const OpFn *x86_opcodes_d8_a32; -const OpFn *x86_opcodes_d9_a16; -const OpFn *x86_opcodes_d9_a32; -const OpFn *x86_opcodes_da_a16; -const OpFn *x86_opcodes_da_a32; -const OpFn *x86_opcodes_db_a16; -const OpFn *x86_opcodes_db_a32; -const OpFn *x86_opcodes_dc_a16; -const OpFn *x86_opcodes_dc_a32; -const OpFn *x86_opcodes_dd_a16; -const OpFn *x86_opcodes_dd_a32; -const OpFn *x86_opcodes_de_a16; -const OpFn *x86_opcodes_de_a32; -const OpFn *x86_opcodes_df_a16; -const OpFn *x86_opcodes_df_a32; -const OpFn *x86_opcodes_REPE; -const OpFn *x86_opcodes_REPNE; - -CPU *cpu_s; -int cpu_effective; -int cpu_multi; -int cpu_16bitbus; -int cpu_busspeed; -int cpu_cyrix_alignment; -int cpuspeed; -int CPUID; -uint64_t cpu_CR4_mask; -int isa_cycles; -int cpu_cycles_read, cpu_cycles_read_l, - cpu_cycles_write, cpu_cycles_write_l; -int cpu_prefetch_cycles, cpu_prefetch_width, - cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; -int cpu_waitstates; -int cpu_cache_int_enabled, cpu_cache_ext_enabled; -int cpu_pci_speed; - -int is286, - is386, - is486, - cpu_iscyrix, - israpidcad, - is_pentium; - -int hasfpu, - cpu_hasrdtsc, - cpu_hasMMX, - cpu_hasMSR, - cpu_hasCR4, - cpu_hasVME; - - -uint64_t tsc = 0; -msr_t msr; -cr0_t CR0; -uint64_t pmc[2] = {0, 0}; - -uint16_t temp_seg_data[4] = {0, 0, 0, 0}; - -#if defined(DEV_BRANCH) && defined(USE_I686) -uint16_t cs_msr = 0; -uint32_t esp_msr = 0; -uint32_t eip_msr = 0; -uint64_t apic_base_msr = 0; -uint64_t mtrr_cap_msr = 0; -uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_fix64k_8000_msr = 0; -uint64_t mtrr_fix16k_8000_msr = 0; -uint64_t mtrr_fix16k_a000_msr = 0; -uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t pat_msr = 0; -uint64_t mtrr_deftype_msr = 0; -uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t ecx17_msr = 0; -uint64_t ecx79_msr = 0; -uint64_t ecx8x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx116_msr = 0; -uint64_t ecx11x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx11e_msr = 0; -uint64_t ecx186_msr = 0; -uint64_t ecx187_msr = 0; -uint64_t ecx1e0_msr = 0; -uint64_t ecx570_msr = 0; -#endif - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) -uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ -uint64_t star = 0; /* These are K6-only. */ -uint64_t sfmask = 0; -#endif - -int timing_rr; -int timing_mr, timing_mrl; -int timing_rm, timing_rml; -int timing_mm, timing_mml; -int timing_bt, timing_bnt; -int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, - timing_int_pm_outer; -int timing_iret_rm, timing_iret_v86, timing_iret_pm, - timing_iret_pm_outer; -int timing_call_rm, timing_call_pm, timing_call_pm_gate, - timing_call_pm_gate_inner; -int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; -int timing_misaligned; - - -static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; - - -void -cpu_dynamic_switch(int new_cpu) -{ - if (cpu_effective == new_cpu) - return; - - int c = cpu; - cpu = new_cpu; - cpu_set(); - pc_speed_changed(); - cpu = c; -} - - -void -cpu_set_edx(void) -{ - EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset; -} - - -void -cpu_set(void) -{ - if (!machines[machine].cpu[cpu_manufacturer].cpus) - { - /*CPU is invalid, set to default*/ - cpu_manufacturer = 0; - cpu = 0; - } - - cpu_effective = cpu; - cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; - - CPUID = cpu_s->cpuid_model; - cpuspeed = cpu_s->speed; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - 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); - is_pentium= (cpu_s->cpu_type >= CPU_WINCHIP); - hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); - 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); - cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC); - if (cpu_s->multi) - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - cpu_multi = cpu_s->multi; - cpu_hasrdtsc = 0; - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; - ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; - - if ((cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || (cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) - { - if (enable_external_fpu) - { - hasfpu = 1; - } - } - - cpu_update_waitstates(); - - isa_cycles = cpu_s->atclk_div; - - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; - 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_iscyrix) - io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); - else - io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); - -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); -#else - x86_setopcodes(ops_386, ops_386_0f); -#endif - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; -#ifdef USE_DYNAREC - x86_dynarec_opcodes_REPE = dynarec_ops_REPE; - x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; -#endif - -#ifdef USE_DYNAREC - if (hasfpu) - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; - } - else - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; - } - codegen_timing_set(&codegen_timing_486); -#endif - - if (hasfpu) - { - x86_opcodes_d8_a16 = ops_fpu_d8_a16; - x86_opcodes_d8_a32 = ops_fpu_d8_a32; - x86_opcodes_d9_a16 = ops_fpu_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_d9_a32; - x86_opcodes_da_a16 = ops_fpu_da_a16; - x86_opcodes_da_a32 = ops_fpu_da_a32; - x86_opcodes_db_a16 = ops_fpu_db_a16; - x86_opcodes_db_a32 = ops_fpu_db_a32; - x86_opcodes_dc_a16 = ops_fpu_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_dd_a32; - x86_opcodes_de_a16 = ops_fpu_de_a16; - x86_opcodes_de_a32 = ops_fpu_de_a32; - x86_opcodes_df_a16 = ops_fpu_df_a16; - x86_opcodes_df_a32 = ops_fpu_df_a32; - } - else - { - x86_opcodes_d8_a16 = ops_nofpu_a16; - x86_opcodes_d8_a32 = ops_nofpu_a32; - x86_opcodes_d9_a16 = ops_nofpu_a16; - x86_opcodes_d9_a32 = ops_nofpu_a32; - x86_opcodes_da_a16 = ops_nofpu_a16; - x86_opcodes_da_a32 = ops_nofpu_a32; - x86_opcodes_db_a16 = ops_nofpu_a16; - x86_opcodes_db_a32 = ops_nofpu_a32; - x86_opcodes_dc_a16 = ops_nofpu_a16; - x86_opcodes_dc_a32 = ops_nofpu_a32; - x86_opcodes_dd_a16 = ops_nofpu_a16; - x86_opcodes_dd_a32 = ops_nofpu_a32; - x86_opcodes_de_a16 = ops_nofpu_a16; - x86_opcodes_de_a32 = ops_nofpu_a32; - x86_opcodes_df_a16 = ops_nofpu_a16; - x86_opcodes_df_a32 = ops_nofpu_a32; - } - - memset(&msr, 0, sizeof(msr)); - - timing_misaligned = 0; - cpu_cyrix_alignment = 0; - - switch (cpu_s->cpu_type) - { - case CPU_8088: - case CPU_8086: - break; - - case CPU_286: -#ifdef USE_DYNAREC - x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); -#else - x86_setopcodes(ops_286, ops_286_0f); -#endif - if (enable_external_fpu) - { -#ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; -#endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; - } - timing_rr = 2; /*register dest - register src*/ - timing_rm = 7; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 7; /*memory dest - memory src*/ - timing_rml = 9; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 11; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 23; - timing_int_v86 = 0; - timing_int_pm = 40; - timing_int_pm_outer = 78; - timing_iret_rm = 17; - timing_iret_v86 = 0; - timing_iret_pm = 31; - timing_iret_pm_outer = 55; - timing_call_rm = 13; - timing_call_pm = 26; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 82; - timing_retf_rm = 15; - timing_retf_pm = 25; - timing_retf_pm_outer = 55; - timing_jmp_rm = 11; - timing_jmp_pm = 23; - timing_jmp_pm_gate = 38; - break; - - case CPU_386SX: - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 8; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 10; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - case CPU_386DX: - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 6; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 6; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - case CPU_RAPIDCAD: - 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 = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - break; - - case CPU_486SLC: -#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 = 3; /*register dest - memory src*/ - timing_mr = 5; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 5; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 7; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_486DLC: -#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 = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_iDX4: - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - case CPU_i486SX: - case CPU_i486DX: -#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*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_Am486SX: - case CPU_Am486DX: - /*AMD timing identical to Intel*/ -#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*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_Cx486S: - case CPU_Cx486DX: -#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 = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 4-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; /*unknown*/ - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_Cx5x86: -#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 = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 9; - timing_int_v86 = 82; /*unknown*/ - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; /*unknown*/ - 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; - break; - - case CPU_WINCHIP: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); -#else - x86_setopcodes(ops_386, ops_winchip_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_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = cpu_hasMSR = 1; - cpu_hasCR4 = 1; - 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; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); -#endif - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; - - case CPU_PENTIUM: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_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 = 2; /*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_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; - - case CPU_PENTIUMMMX: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - x86_setopcodes(ops_386, ops_pentiummmx_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_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; - - case CPU_Cx6x86: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - CPUID = 0; /*Disabled on powerup by default*/ - break; - - case CPU_Cx6x86L: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; - - - case CPU_CxGX1: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; - - - case CPU_Cx6x86MX: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_c6x86mx_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - 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 = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; - -#if 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); -#else - x86_setopcodes(ops_386, ops_k6_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_misaligned = 3; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - break; - - case CPU_K6: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); -#else - x86_setopcodes(ops_386, ops_k6_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_misaligned = 3; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; -#endif - -#if defined(DEV_BRANCH) && defined(USE_I686) - case CPU_PENTIUMPRO: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentiumpro_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - 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_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 3; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; - -#if 0 - case CPU_PENTIUM2: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - 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_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 3; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; -#endif - - case CPU_PENTIUM2D: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2d_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - 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_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 3; - cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; -#endif - - default: - fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); - } -} - - -char * -cpu_current_pc(char *bufp) -{ - static char buff[10]; - - if (bufp == NULL) - bufp = buff; - - sprintf(bufp, "%04X:%04X", CS, cpu_state.pc); - - return(bufp); -} - - -void -cpu_CPUID(void) -{ - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) - { - case CPU_i486DX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_iDX4: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_Am486SX: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = EDX = 0; /*No FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_Am486DX: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_WINCHIP: - if (!EAX) - { - 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; - } - } - else if (EAX == 1) - { - EAX = 0x540; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (msr.fcr & (1 << 1)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_PENTIUM: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) - case CPU_K5: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_5K86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000002) - { - EAX = 0x2D444D41; - EBX = 0x7428354B; - ECX = 0x5020296D; - EDX = 0x65636F72; - } - else if (EAX == 0x80000003) - { - EAX = 0x726F7373; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000004) - { - EAX = EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { - EAX = 0; - EBX = 0x04800000; - ECX = 0x08040120; - EDX = 0x10040120; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_K6: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP; - } - else if (EAX == 0x80000002) - { - EAX = 0x2D444D41; - EBX = 0x6D74364B; - ECX = 0x202F7720; - EDX = 0x746C756D; - } - else if (EAX == 0x80000003) - { - EAX = 0x64656D69; - EBX = 0x65206169; - ECX = 0x6E657478; - EDX = 0x6E6F6973; - } - else if (EAX == 0x80000004) - { - EAX = 0x73; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { - EAX = 0; - EBX = 0x02800140; - ECX = 0x20020220; - EDX = 0x20020220; - } - else if (EAX == 0x8FFFFFFF) - { - EAX = 0x4778654E; - EBX = 0x72656E65; - ECX = 0x6F697461; - EDX = 0x444D416E; - } - else - EAX = EBX = ECX = EDX = 0; - break; -#endif - - case CPU_PENTIUMMMX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - case CPU_Cx6x86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - case CPU_Cx6x86L: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - case CPU_CxGX1: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - - case CPU_Cx6x86MX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; - -#ifdef DEV_BRANCH -#ifdef USE_I686 - case CPU_PENTIUMPRO: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { - } - else - EAX = EBX = ECX = EDX = 0; - break; - - /* case CPU_PENTIUM2: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { - EAX = 0x03020101; - EBX = ECX = 0; - EDX = 0x0C040843; - } - else - EAX = EBX = ECX = EDX = 0; - break; */ - - case CPU_PENTIUM2D: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; - } - else if (EAX == 2) - { - EAX = 0x03020101; - EBX = ECX = 0; - EDX = 0x0C040844; - } - else - EAX = EBX = ECX = EDX = 0; - break; -#endif -#endif - - } -} - -void cpu_RDMSR() -{ - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) - { - case CPU_WINCHIP: - EAX = EDX = 0; - switch (ECX) - { - case 0x02: - EAX = msr.tr1; - break; - case 0x0e: - EAX = msr.tr12; - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x11: - EAX = msr.cesr; - break; - case 0x107: - EAX = msr.fcr; - break; - case 0x108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x10a: - EAX = cpu_multi & 3; - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) - case CPU_K5: - case CPU_5K86: - case CPU_K6: - EAX = EDX = 0; - switch (ECX) - { - case 0x0e: - EAX = msr.tr12; - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x83: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000084: - EAX = sfmask & 0xffffffff; - EDX = sfmask >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; -#endif - - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - break; - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - break; - -#ifdef DEV_BRANCH -#ifdef USE_I686 - case CPU_PENTIUMPRO: - case CPU_PENTIUM2D: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x17: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; - EAX = ecx17_msr & 0xffffffff; - EDX = ecx17_msr >> 32; - break; - case 0x1B: - EAX = apic_base_msr & 0xffffffff; - EDX = apic_base_msr >> 32; - break; - case 0x2A: - EAX = 0xC5800000; - EDX = 0; - break; - case 0x79: - EAX = ecx79_msr & 0xffffffff; - EDX = ecx79_msr >> 32; - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - EAX = ecx8x_msr[ECX - 0x88] & 0xffffffff; - EDX = ecx8x_msr[ECX - 0x88] >> 32; - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - EAX = msr_ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr_ia32_pmc[ECX - 0xC1] >> 32; - break; - case 0xFE: - EAX = mtrr_cap_msr & 0xffffffff; - EDX = mtrr_cap_msr >> 32; - break; - case 0x116: - EAX = ecx116_msr & 0xffffffff; - EDX = ecx116_msr >> 32; - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - EAX = ecx11x_msr[ECX - 0x118] & 0xffffffff; - EDX = ecx11x_msr[ECX - 0x118] >> 32; - break; - case 0x11E: - EAX = ecx11e_msr & 0xffffffff; - EDX = ecx11e_msr >> 32; - break; - case 0x174: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX &= 0xFFFF0000; - EAX |= cs_msr; - break; - case 0x175: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = esp_msr; - break; - case 0x176: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = eip_msr; - break; - case 0x186: - EAX = ecx186_msr & 0xffffffff; - EDX = ecx186_msr >> 32; - break; - case 0x187: - EAX = ecx187_msr & 0xffffffff; - EDX = ecx187_msr >> 32; - break; - case 0x1E0: - EAX = ecx1e0_msr & 0xffffffff; - EDX = ecx1e0_msr >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; - } - else - { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; - } - break; - case 0x250: - EAX = mtrr_fix64k_8000_msr & 0xffffffff; - EDX = mtrr_fix64k_8000_msr >> 32; - break; - case 0x258: - EAX = mtrr_fix16k_8000_msr & 0xffffffff; - EDX = mtrr_fix16k_8000_msr >> 32; - break; - case 0x259: - EAX = mtrr_fix16k_a000_msr & 0xffffffff; - EDX = mtrr_fix16k_a000_msr >> 32; - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; - EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; - break; - case 0x277: - EAX = pat_msr & 0xffffffff; - EDX = pat_msr >> 32; - break; - case 0x2FF: - EAX = mtrr_deftype_msr & 0xffffffff; - EDX = mtrr_deftype_msr >> 32; - break; - case 0x570: - EAX = ecx570_msr & 0xffffffff; - EDX = ecx570_msr >> 32; - break; - default: -i686_invalid_rdmsr: - x86gpf(NULL, 0); - break; - } - break; -#endif -#endif - } -} - -void cpu_WRMSR() -{ - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) - { - case CPU_WINCHIP: - switch (ECX) - { - case 0x02: - msr.tr1 = EAX & 2; - break; - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x11: - msr.cesr = EAX & 0xff00ff; - break; - case 0x107: - msr.fcr = EAX; - cpu_hasMMX = EAX & (1 << 9); - if (EAX & (1 << 29)) - CPUID = 0; - else - CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model; - break; - case 0x108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) - case CPU_K5: - case CPU_5K86: - case CPU_K6: - 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 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000084: - sfmask = EAX | ((uint64_t)EDX << 32); - break; - } - break; -#endif - - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - } - break; - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - } - break; - -#ifdef DEV_BRANCH -#ifdef USE_I686 - case CPU_PENTIUMPRO: - case CPU_PENTIUM2D: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x17: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr; - ecx17_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1B: - apic_base_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x79: - ecx79_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - ecx8x_msr[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - msr_ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); - break; - case 0xFE: - mtrr_cap_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x116: - ecx116_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - ecx11x_msr[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); - break; - case 0x11E: - ecx11e_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x174: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - cs_msr = EAX & 0xFFFF; - break; - case 0x175: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - esp_msr = EAX; - break; - case 0x176: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - eip_msr = EAX; - break; - case 0x186: - ecx186_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x187: - ecx187_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1E0: - ecx1e0_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; - case 0x250: - mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x258: - mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x259: - mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; - case 0x277: - pat_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x2FF: - mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x570: - ecx570_msr = EAX | ((uint64_t)EDX << 32); - break; - default: -i686_invalid_wrmsr: - x86gpf(NULL, 0); - break; - } - break; -#endif -#endif - } -} - -static int cyrix_addr; - -void cyrix_write(uint16_t addr, uint8_t val, void *priv) -{ - if (!(addr & 1)) - cyrix_addr = val; - else switch (cyrix_addr) - { - case 0xc0: /*CCR0*/ - ccr0 = val; - break; - case 0xc1: /*CCR1*/ - ccr1 = val; - break; - case 0xc2: /*CCR2*/ - ccr2 = val; - break; - case 0xc3: /*CCR3*/ - ccr3 = val; - break; - case 0xe8: /*CCR4*/ - if ((ccr3 & 0xf0) == 0x10) - { - ccr4 = val; - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) - { - if (val & 0x80) - CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model; - else - CPUID = 0; - } - } - break; - case 0xe9: /*CCR5*/ - if ((ccr3 & 0xf0) == 0x10) - ccr5 = val; - break; - case 0xea: /*CCR6*/ - if ((ccr3 & 0xf0) == 0x10) - ccr6 = val; - break; - } -} - -uint8_t cyrix_read(uint16_t addr, void *priv) -{ - if (addr & 1) - { - switch (cyrix_addr) - { - case 0xc0: return ccr0; - case 0xc1: return ccr1; - case 0xc2: return ccr2; - case 0xc3: return ccr3; - case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; - case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; - case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; - case 0xfe: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id & 0xff; - case 0xff: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id >> 8; - } - if ((cyrix_addr & 0xf0) == 0xc0) return 0xff; - if (cyrix_addr == 0x20 && machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_Cx5x86) return 0xff; - } - return 0xff; -} - - -void -#ifdef USE_DYNAREC -x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, const OpFn *dynarec_opcodes_0f) -{ - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; - x86_dynarec_opcodes = dynarec_opcodes; - x86_dynarec_opcodes_0f = dynarec_opcodes_0f; -} -#else -x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) -{ - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; -} -#endif - - -void -cpu_update_waitstates(void) -{ - cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; - - if (is486) - cpu_prefetch_width = 16; - else - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; - - if (cpu_cache_int_enabled) - { - /* Disable prefetch emulation */ - cpu_prefetch_cycles = 0; - } - else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) - { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates+1; - cpu_cycles_read = cpu_waitstates+1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - cpu_cycles_write = cpu_waitstates+1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - } - else if (cpu_cache_ext_enabled) - { - /* Use cache timings */ - cpu_prefetch_cycles = cpu_s->cache_read_cycles; - cpu_cycles_read = cpu_s->cache_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; - cpu_cycles_write = cpu_s->cache_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; - } - else - { - /* Use memory timings */ - cpu_prefetch_cycles = cpu_s->mem_read_cycles; - cpu_cycles_read = cpu_s->mem_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; - cpu_cycles_write = cpu_s->mem_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; - } - if (is486) - cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; - cpu_mem_prefetch_cycles = cpu_prefetch_cycles; - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; -} diff --git a/src - Cópia/cpu/cpu.h b/src - Cópia/cpu/cpu.h deleted file mode 100644 index b4efb8a3c..000000000 --- a/src - Cópia/cpu/cpu.h +++ /dev/null @@ -1,473 +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. - * - * CPU type handler. - * - * Version: @(#)cpu.h 1.0.11 2018/03/28 - * - * Authors: Sarah Walker, - * leilei, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016,2018 Miran Grca. - */ -#ifndef EMU_CPU_H -# define EMU_CPU_H - - -#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_RAPIDCAD 5 -#define CPU_486SLC 6 -#define CPU_486DLC 7 -#define CPU_i486SX 8 /* 486 class CPUs */ -#define CPU_Am486SX 9 -#define CPU_Cx486S 10 -#define CPU_i486DX 11 -#define CPU_Am486DX 12 -#define CPU_Cx486DX 13 -#define CPU_iDX4 14 -#define CPU_Cx5x86 15 -#define CPU_WINCHIP 16 /* 586 class CPUs */ -#define CPU_PENTIUM 17 -#define CPU_PENTIUMMMX 18 -#define CPU_Cx6x86 19 -#define CPU_Cx6x86MX 20 -#define CPU_Cx6x86L 21 -#define CPU_CxGX1 22 -#ifdef DEV_BRANCH -#ifdef USE_AMD_K -#define CPU_K5 23 -#define CPU_5K86 24 -#define CPU_K6 25 -#endif -#endif -#ifdef DEV_BRANCH -#ifdef USE_I686 -#define CPU_PENTIUMPRO 26 /* 686 class CPUs */ -#if 0 -# define CPU_PENTIUM2 27 -# define CPU_PENTIUM2D 28 -#else -# define CPU_PENTIUM2D 27 -#endif -#endif -#endif - -#define MANU_INTEL 0 -#define MANU_AMD 1 -#define MANU_CYRIX 2 -#define MANU_IDT 3 - -#define CPU_SUPPORTS_DYNAREC 1 -#define CPU_REQUIRES_DYNAREC 2 - - -typedef struct { - const char *name; - int cpu_type; - int speed; - int rspeed; - int multi; - int pci_speed; - uint32_t edx_reset; - uint32_t cpuid_model; - uint16_t cyrix_id; - int cpu_flags; - int mem_read_cycles, mem_write_cycles; - int cache_read_cycles, cache_write_cycles; - int atclk_div; -} CPU; - -extern CPU cpus_8088[]; -extern CPU cpus_8086[]; -extern CPU cpus_286[]; -extern CPU cpus_i386SX[]; -extern CPU cpus_i386DX[]; -extern CPU cpus_Am386SX[]; -extern CPU cpus_Am386DX[]; -extern CPU cpus_486SLC[]; -extern CPU cpus_486DLC[]; -extern CPU cpus_i486[]; -extern CPU cpus_Am486[]; -extern CPU cpus_Cx486[]; -extern CPU cpus_WinChip[]; -extern CPU cpus_Pentium5V[]; -extern CPU cpus_Pentium5V50[]; -extern CPU cpus_PentiumS5[]; -#ifdef DEV_BRANCH -#ifdef USE_AMD_K -extern CPU cpus_K5[]; -extern CPU cpus_K56[]; -#endif -#endif -extern CPU cpus_Pentium[]; -extern CPU cpus_6x86[]; -#ifdef DEV_BRANCH -#ifdef USE_I686 -extern CPU cpus_PentiumPro[]; -extern CPU cpus_Pentium2[]; -extern CPU cpus_Pentium2D[]; -#endif -#endif - - -#define C_FLAG 0x0001 -#define P_FLAG 0x0004 -#define A_FLAG 0x0010 -#define Z_FLAG 0x0040 -#define N_FLAG 0x0080 -#define T_FLAG 0x0100 -#define I_FLAG 0x0200 -#define D_FLAG 0x0400 -#define V_FLAG 0x0800 -#define NT_FLAG 0x4000 - -#define VM_FLAG 0x0002 /* in EFLAGS */ -#define VIF_FLAG 0x0008 /* in EFLAGS */ -#define VIP_FLAG 0x0010 /* in EFLAGS */ - -#define WP_FLAG 0x10000 /* in CR0 */ -#define CR4_VME (1 << 0) -#define CR4_PVI (1 << 1) -#define CR4_PSE (1 << 4) - -#define CPL ((_cs.access>>5)&3) - -#define IOPL ((flags>>12)&3) - -#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) - - -typedef union { - uint32_t l; - uint16_t w; - struct { - uint8_t l, - h; - } b; -} x86reg; - -typedef struct { - uint32_t base; - uint32_t limit; - uint8_t access; - uint16_t seg; - uint32_t limit_low, - limit_high; - int checked; /*Non-zero if selector is known to be valid*/ -} x86seg; - -typedef union { - uint64_t q; - int64_t sq; - uint32_t l[2]; - int32_t sl[2]; - uint16_t w[4]; - int16_t sw[4]; - uint8_t b[8]; - int8_t sb[8]; -} MMX_REG; - -typedef struct { - uint32_t tr1, tr12; - uint32_t cesr; - uint32_t fcr; - uint64_t fcr2, fcr3; -} msr_t; - -typedef union { - uint32_t l; - uint16_t w; -} cr0_t; - - -struct _cpustate_ { - x86reg regs[8]; - - uint8_t tag[8]; - - x86seg *ea_seg; - uint32_t eaaddr; - - int flags_op; - uint32_t flags_res; - uint32_t flags_op1, - flags_op2; - - uint32_t pc; - uint32_t oldpc; - uint32_t op32; - - int TOP; - - union { - struct { - int8_t rm, - mod, - reg; - } rm_mod_reg; - int32_t rm_mod_reg_data; - } rm_data; - - int8_t ssegs; - int8_t ismmx; - int8_t abrt; - - int _cycles; - int cpu_recomp_ins; - - uint16_t npxs, - npxc; - - double ST[8]; - - uint16_t MM_w4[8]; - - MMX_REG MM[8]; - - uint16_t old_npxc, - new_npxc; - uint32_t last_ea; -} cpu_state; - -/*The flags below must match in both cpu_cur_status and block->status for a block - to be valid*/ -#define CPU_STATUS_USE32 (1 << 0) -#define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_PMODE (1 << 2) -#define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_FLAGS 0xffff - -/*If the flags below are set in cpu_cur_status, they must be set in block->status. - Otherwise they are ignored*/ -#define CPU_STATUS_NOTFLATDS (1 << 16) -#define CPU_STATUS_NOTFLATSS (1 << 17) -#define CPU_STATUS_MASK 0xffff0000 - -#ifdef __MSC__ -# define COMPILE_TIME_ASSERT(expr) /*nada*/ -#else -# ifdef EXTREME_DEBUG -# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; -# else -# define COMPILE_TIME_ASSERT(expr) /*nada*/ -# endif -#endif - -COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) - -#define cpu_state_offset(MEMBER) ((uint8_t)((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)) - -#define EAX cpu_state.regs[0].l -#define AX cpu_state.regs[0].w -#define AL cpu_state.regs[0].b.l -#define AH cpu_state.regs[0].b.h -#define ECX cpu_state.regs[1].l -#define CX cpu_state.regs[1].w -#define CL cpu_state.regs[1].b.l -#define CH cpu_state.regs[1].b.h -#define EDX cpu_state.regs[2].l -#define DX cpu_state.regs[2].w -#define DL cpu_state.regs[2].b.l -#define DH cpu_state.regs[2].b.h -#define EBX cpu_state.regs[3].l -#define BX cpu_state.regs[3].w -#define BL cpu_state.regs[3].b.l -#define BH cpu_state.regs[3].b.h -#define ESP cpu_state.regs[4].l -#define EBP cpu_state.regs[5].l -#define ESI cpu_state.regs[6].l -#define EDI cpu_state.regs[7].l -#define SP cpu_state.regs[4].w -#define BP cpu_state.regs[5].w -#define SI cpu_state.regs[6].w -#define DI cpu_state.regs[7].w - -#define cycles cpu_state._cycles - -#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm -#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod -#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg - -#define CR4_TSD (1 << 2) -#define CR4_DE (1 << 3) -#define CR4_MCE (1 << 6) -#define CR4_PCE (1 << 8) -#define CR4_OSFXSR (1 << 9) - - -/* Global variables. */ -extern int cpu_iscyrix; -extern int cpu_16bitbus; -extern int cpu_busspeed; -extern int cpu_multi; -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 is_rapidcad, is_pentium; -extern int hasfpu; -extern int cpu_hasrdtsc; -extern int cpu_hasMSR; -extern int cpu_hasMMX; -extern int cpu_hasCR4; -extern int cpu_hasVME; - -extern uint32_t cpu_cur_status; -extern uint64_t cpu_CR4_mask; -extern uint64_t tsc; -extern msr_t msr; -extern int cpuspeed; -extern int cycles_lost; -extern uint8_t opcode; -extern int insc; -extern int fpucount; -extern float mips,flops; -extern int clockrate; -extern int cgate16; -extern int cpl_override; -extern int CPUID; -extern int xt_cpu_multi; -extern int isa_cycles; -extern uint16_t flags,eflags; -extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; -extern int ins,output; -extern int cycdiff; -extern uint32_t pccache; -extern uint8_t *pccache2; - -extern float isa_timing, bus_timing; -extern uint64_t pmc[2]; -extern uint16_t temp_seg_data[4]; -extern uint16_t cs_msr; -extern uint32_t esp_msr; -extern uint32_t eip_msr; - -/* For the AMD K6. */ -extern uint64_t star; - -#define FPU_CW_Reserved_Bits (0xe0c0) - -extern cr0_t CR0; -#define cr0 CR0.l -#define msw CR0.w -extern uint32_t cr2, cr3, cr4; -extern uint32_t dr[8]; - - -/*Segments - - _cs,_ds,_es,_ss are the segment structures - CS,DS,ES,SS is the 16-bit data - cs,ds,es,ss are defines to the bases*/ -extern x86seg gdt,ldt,idt,tr; -extern x86seg _cs,_ds,_es,_ss,_fs,_gs; -extern x86seg _oldds; -#define CS _cs.seg -#define DS _ds.seg -#define ES _es.seg -#define SS _ss.seg -#define FS _fs.seg -#define GS _gs.seg -#define cs _cs.base -#define ds _ds.base -#define es _es.base -#define ss _ss.base -#define seg_fs _fs.base -#define gs _gs.base - - -#define ISA_CYCLES_SHIFT 6 -#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT) - -extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; -extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; -extern int cpu_waitstates; -extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; -extern int cpu_pci_speed; - -extern int timing_rr; -extern int timing_mr, timing_mrl; -extern int timing_rm, timing_rml; -extern int timing_mm, timing_mml; -extern int timing_bt, timing_bnt; -extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm; -extern int timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm; -extern int timing_iret_pm_outer, timing_call_rm, timing_call_pm; -extern int timing_call_pm_gate, timing_call_pm_gate_inner; -extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; -extern int timing_misaligned; - - -extern CPU cpus_pcjr[]; // FIXME: should be in machine file! -extern CPU cpus_europc[]; // FIXME: should be in machine file! -extern CPU cpus_pc1512[]; // FIXME: should be in machine file! -extern CPU cpus_ibmat[]; // FIXME: should be in machine file! -extern CPU cpus_ibmxt286[]; // FIXME: should be in machine file! -extern CPU cpus_ps1_m2011[]; // FIXME: should be in machine file! -extern CPU cpus_ps2_m30_286[]; // FIXME: should be in machine file! -#if 0 -extern CPU cpus_acer[]; // FIXME: should be in machine file! -#endif - - -/* Functions. */ -extern void cyrix_write(uint16_t addr, uint8_t val, void *priv); -extern uint8_t cyrix_read(uint16_t addr, void *priv); -extern void loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); - -extern char *cpu_current_pc(char *bufp); - -extern void cpu_update_waitstates(void); -extern void cpu_set(void); - -extern void cpu_CPUID(void); -extern void cpu_RDMSR(void); -extern void cpu_WRMSR(void); - -extern int checkio(int port); -extern void codegen_block_end(void); -extern void codegen_reset(void); -extern void cpu_set_edx(void); -extern int divl(uint32_t val); -extern void dumpregs(int __force); -extern void execx86(int cycs); -extern void exec386(int cycs); -extern void exec386_dynarec(int cycs); -extern int idivl(int32_t val); -extern void loadcscall(uint16_t seg); -extern void loadcsjmp(uint16_t seg, uint32_t oxpc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); -extern void resetmcr(void); -extern void resetx86(void); -extern void refreshread(void); -extern void resetreadlookup(void); -extern void softresetx86(void); -extern void x86_int_sw(int num); -extern int x86_int_sw_rm(int num); -extern void x86gpf(char *s, uint16_t error); -extern void x86np(char *s, uint16_t error); -extern void x86ss(char *s, uint16_t error); -extern void x86ts(char *s, uint16_t error); -extern void x87_dumpregs(void); -extern void x87_reset(void); - -extern int cpu_effective; -extern void cpu_dynamic_switch(int new_cpu); - - -#endif /*EMU_CPU_H*/ diff --git a/src - Cópia/cpu/cpu_table.c b/src - Cópia/cpu/cpu_table.c deleted file mode 100644 index 92fdd93f4..000000000 --- a/src - Cópia/cpu/cpu_table.c +++ /dev/null @@ -1,455 +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. - * - * 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.4 2018/02/18 - * - * Authors: Sarah Walker, - * leilei, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "cpu.h" -#include "../machine/machine.h" - - -CPU cpus_8088[] = { - /*8088 standard*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, -#if 0 - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, -#endif - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_pcjr[] = { - /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 0, 4772728, 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_europc[] = { - /*8088 EuroPC*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_8086[] = { - /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 4, 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} -}; - -CPU cpus_pc1512[] = { - /*8086 Amstrad*/ - {"8086/8", CPU_8086, 1, 8000000, 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_286[] = { - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_ibmat[] = { - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, - {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_ibmxt286[] = { - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_ps1_m2011[] = { - /*286*/ - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_ps2_m30_286[] = { - /*286*/ - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_i386SX[] = { - /*i386SX*/ - {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_i386DX[] = { - /*i386DX*/ - {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3, 3}, - {"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3, 4}, - {"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -#if 0 -CPU cpus_acer[] = { - /*i386SX*/ - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; -#endif - -CPU cpus_Am386SX[] = { - /*Am386*/ - {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_Am386DX[] = { - /*Am386*/ - {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386DX/40", CPU_386DX, 4, 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, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, - {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"Cx486SRx2/50", CPU_486SLC, 5, 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*/ - {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, - {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, - {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, - {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 4}, - {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6}, - {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6}, - {"Cx486DRx2/66", CPU_486DLC, 6, 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_i486[] = { - /*i486*/ - {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, - {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 8}, - {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, - {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, - {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, 10, 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*/ - {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, - {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 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, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486SX2/50", CPU_Am486SX, 5, 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, 6, 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, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, - {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 10}, - {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, - {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12}, - {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12}, - {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15}, - {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} -}; - -CPU cpus_Cx486[] = { - /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, - {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 10}, - {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, - {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12}, - {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12}, - {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15}, - {"Cx5x86/133", CPU_Cx5x86, 12, 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} -}; - -CPU cpus_6x86[] = { - /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 10}, - {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, - {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14}, - {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18}, - - /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14}, - {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18}, - - /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 45/2}, - {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25}, - {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, 28}, - {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 30}, - {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 30}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 33}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} - }; - -CPU cpus_WinChip[] = { - /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 9}, - {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 21/2}, - {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 12}, - {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 14}, - {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 16}, - {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 35/2}, - {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 40}, - {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 21}, - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 27}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 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} -}; - -CPU cpus_Pentium5V[] = { - /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 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,0} -}; - -CPU cpus_Pentium5V50[] = { - /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/ - {"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6}, - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium OverDrive 100",CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 12}, - {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 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,0} -}; - -CPU cpus_PentiumS5[] = { - /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,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} -}; - -CPU cpus_Pentium[] = { - /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,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} -}; - -#ifdef DEV_BRANCH -#ifdef USE_AMD_K -CPU cpus_K5[] = { - /*AMD K5 (Socket 5)*/ - {"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 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,0} -}; - -CPU cpus_K56[] = { - /*AMD K5 and K6 (Socket 7)*/ - {"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2}, - {"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12}, - {"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6 (Model 6) 166", CPU_K6, 19, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K6 (Model 6) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6 (Model 6) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6 (Model 7) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6 (Model 7) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6 (Model 7) 266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6 (Model 7) 300", CPU_K6, 28, 300000000, 5, 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} -}; -#endif -#endif - -#ifdef DEV_BRANCH -#ifdef USE_I686 -CPU cpus_PentiumPro[] = { - /*Intel Pentium Pro and II Overdrive*/ - {"Pentium Pro 50", CPU_PENTIUMPRO, 5, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6}, - {"Pentium Pro 60" , CPU_PENTIUMPRO, 6, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium Pro 66" , CPU_PENTIUMPRO, 6, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium Pro 75", CPU_PENTIUMPRO, 9, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium Pro 150", CPU_PENTIUMPRO, 17, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium Pro 166", CPU_PENTIUMPRO, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium Pro 180", CPU_PENTIUMPRO, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, - {"Pentium Pro 200", CPU_PENTIUMPRO, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"Pentium II Overdrive 50", CPU_PENTIUM2D, 5, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6}, - {"Pentium II Overdrive 60", CPU_PENTIUM2D, 6, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium II Overdrive 66", CPU_PENTIUM2D, 6, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium II Overdrive 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9}, - {"Pentium II Overdrive 210", CPU_PENTIUM2D, 22, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25}, - {"Pentium II Overdrive 233", CPU_PENTIUM2D, 24, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,1, 28}, - {"Pentium II Overdrive 240", CPU_PENTIUM2D, 25, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, - {"Pentium II Overdrive 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Overdrive 270", CPU_PENTIUM2D, 27, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33}, - {"Pentium II Overdrive 300/66",CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - {"Pentium II Overdrive 300/60",CPU_PENTIUM2D, 28, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"Pentium II Overdrive 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 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,0} -}; -#endif -#endif diff --git a/src - Cópia/cpu/x86.h b/src - Cópia/cpu/x86.h deleted file mode 100644 index a49ea9769..000000000 --- a/src - Cópia/cpu/x86.h +++ /dev/null @@ -1,107 +0,0 @@ -uint16_t oldcs; -extern uint32_t rmdat32; -int oldcpl; - -extern int nmi_enable; - -int tempc; -int output; -int firstrepcycle; - -uint32_t easeg,ealimit,ealimitw; - -int skipnextprint; -int inhlt; - -uint8_t opcode; -int noint; - -uint16_t lastcs,lastpc; -extern int timetolive,keyboardtimer; - -#define setznp168 setznp16 - -#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l) -#define getr16(r) cpu_state.regs[r].w -#define getr32(r) cpu_state.regs[r].l - -#define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \ - else cpu_state.regs[r&3].b.l=v; -#define setr16(r,v) cpu_state.regs[r].w=v -#define setr32(r,v) cpu_state.regs[r].l=v - -uint8_t znptable8[256]; -uint16_t znptable16[65536]; - -int use32; -int stack32; - -#define fetchea() { rmdat=readmemb(cs+pc); pc++; \ - reg=(rmdat>>3)&7; \ - mod=(rmdat>>6)&3; \ - rm=rmdat&7; \ - if (mod!=3) fetcheal(); } - - -int optype; -#define JMP 1 -#define CALL 2 -#define IRET 3 -#define OPTYPE_INT 4 - -uint32_t oxpc; - -extern uint16_t *mod1add[2][8]; -extern uint32_t *mod1seg[8]; - - -#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !noint) - -extern int cgate32; - - -extern uint32_t *eal_r, *eal_w; - - -extern uint32_t flags_zn; -extern uint8_t flags_p; -#define FLAG_N (flags_zn>>31) -#define FLAG_Z (flags_zn) -#define FLAG_P (znptable8[flags_p]&P_FLAG) - -extern int gpf; - - -enum -{ - ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE -}; - -extern uint32_t abrt_error; - -void x86_doabrt(int x86_abrt); - -extern uint8_t opcode2; - -extern uint16_t rds; -extern uint32_t rmdat32; - -extern int inscounts[256]; - -void x86illegal(); - -void x86seg_reset(); -void x86gpf(char *s, uint16_t error); - -extern uint16_t zero; - -extern int x86_was_reset; - -extern int codegen_flat_ds; -extern int codegen_flat_ss; diff --git a/src - Cópia/cpu/x86_flags.h b/src - Cópia/cpu/x86_flags.h deleted file mode 100644 index dab54dbf6..000000000 --- a/src - Cópia/cpu/x86_flags.h +++ /dev/null @@ -1,521 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -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() -{ - 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 flags & Z_FLAG; - - default: - return 0; - } -} - -static __inline int NF_SET() -{ - 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 flags & N_FLAG; - - default: - return 0; - } -} - -static __inline int PF_SET() -{ - 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 flags & P_FLAG; - - default: - return 0; - } -} - -static __inline int VF_SET() -{ - 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 flags & V_FLAG; - - default: - return 0; - } -} - -static __inline int AF_SET() -{ - 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 flags & A_FLAG; - - default: - return 0; - } -} - -static __inline int CF_SET() -{ - 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 flags & C_FLAG; - - default: - return 0; - } -} - -static __inline void flags_rebuild() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET()) tempf |= C_FLAG; - if (PF_SET()) tempf |= P_FLAG; - if (AF_SET()) tempf |= A_FLAG; - if (ZF_SET()) tempf |= Z_FLAG; - if (NF_SET()) tempf |= N_FLAG; - if (VF_SET()) tempf |= V_FLAG; - flags = (flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract() -{ - cpu_state.flags_op = FLAGS_UNKNOWN; -} - -static __inline void flags_rebuild_c() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET()) - flags |= C_FLAG; - else - flags &= ~C_FLAG; - } -} - -static __inline void setznp8(uint8_t val) -{ - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; -} -static __inline void setznp16(uint16_t val) -{ - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; -} -static __inline void setznp32(uint32_t val) -{ - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; -} - -#define set_flags_shift(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(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(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(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(uint8_t a, uint8_t b) -{ - flags_rebuild_c(); - 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(uint16_t a, uint16_t b) -{ - flags_rebuild_c(); - 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(uint32_t a, uint32_t b) -{ - flags_rebuild_c(); - 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(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(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(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(uint8_t a, uint8_t b) -{ - flags_rebuild_c(); - 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(uint16_t a, uint16_t b) -{ - flags_rebuild_c(); - 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(uint32_t a, uint32_t b) -{ - flags_rebuild_c(); - 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(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} -static __inline void setadc16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; -} - -static __inline void setsbc8(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); - cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} -static __inline void setsbc16(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); - cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if (c&0x10000) flags|=C_FLAG; - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; -} - -static __inline void setadc32(uint32_t a, uint32_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG; -} - diff --git a/src - Cópia/cpu/x86_ops.h b/src - Cópia/cpu/x86_ops.h deleted file mode 100644 index 5b30c0747..000000000 --- a/src - Cópia/cpu/x86_ops.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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. - * - * Miscellaneous x86 CPU Instructions. - * - * Version: @(#)x86_ops.h 1.0.2 2018/05/05 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef _X86_OPS_H -#define _X86_OPS_H - - -#define UN_USED(x) (void)(x) - - -typedef int (*OpFn)(uint32_t fetchdat); - -#ifdef USE_DYNAREC -void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, - const OpFn *dynarec_opcodes_0f); - -extern const OpFn *x86_dynarec_opcodes; -extern const OpFn *x86_dynarec_opcodes_0f; -extern const OpFn *x86_dynarec_opcodes_d8_a16; -extern const OpFn *x86_dynarec_opcodes_d8_a32; -extern const OpFn *x86_dynarec_opcodes_d9_a16; -extern const OpFn *x86_dynarec_opcodes_d9_a32; -extern const OpFn *x86_dynarec_opcodes_da_a16; -extern const OpFn *x86_dynarec_opcodes_da_a32; -extern const OpFn *x86_dynarec_opcodes_db_a16; -extern const OpFn *x86_dynarec_opcodes_db_a32; -extern const OpFn *x86_dynarec_opcodes_dc_a16; -extern const OpFn *x86_dynarec_opcodes_dc_a32; -extern const OpFn *x86_dynarec_opcodes_dd_a16; -extern const OpFn *x86_dynarec_opcodes_dd_a32; -extern const OpFn *x86_dynarec_opcodes_de_a16; -extern const OpFn *x86_dynarec_opcodes_de_a32; -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; - -extern const OpFn dynarec_ops_286[1024]; -extern const OpFn dynarec_ops_286_0f[1024]; - -extern const OpFn dynarec_ops_386[1024]; -extern const OpFn dynarec_ops_386_0f[1024]; - -extern const OpFn dynarec_ops_486_0f[1024]; - -extern const OpFn dynarec_ops_winchip_0f[1024]; - -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(DEV_BRANCH) && defined(USE_AMD_K) -extern const OpFn dynarec_ops_k6_0f[1024]; -#endif - -#if defined(DEV_BRANCH) && defined(USE_I686) -extern const OpFn dynarec_ops_pentiumpro_0f[1024]; -extern const OpFn dynarec_ops_pentium2d_0f[1024]; -#endif - -extern const OpFn dynarec_ops_fpu_287_d9_a16[256]; -extern const OpFn dynarec_ops_fpu_287_d9_a32[256]; -extern const OpFn dynarec_ops_fpu_287_da_a16[256]; -extern const OpFn dynarec_ops_fpu_287_da_a32[256]; -extern const OpFn dynarec_ops_fpu_287_db_a16[256]; -extern const OpFn dynarec_ops_fpu_287_db_a32[256]; -extern const OpFn dynarec_ops_fpu_287_dc_a16[32]; -extern const OpFn dynarec_ops_fpu_287_dc_a32[32]; -extern const OpFn dynarec_ops_fpu_287_dd_a16[256]; -extern const OpFn dynarec_ops_fpu_287_dd_a32[256]; -extern const OpFn dynarec_ops_fpu_287_de_a16[256]; -extern const OpFn dynarec_ops_fpu_287_de_a32[256]; -extern const OpFn dynarec_ops_fpu_287_df_a16[256]; -extern const OpFn dynarec_ops_fpu_287_df_a32[256]; - -extern const OpFn dynarec_ops_fpu_d8_a16[32]; -extern const OpFn dynarec_ops_fpu_d8_a32[32]; -extern const OpFn dynarec_ops_fpu_d9_a16[256]; -extern const OpFn dynarec_ops_fpu_d9_a32[256]; -extern const OpFn dynarec_ops_fpu_da_a16[256]; -extern const OpFn dynarec_ops_fpu_da_a32[256]; -extern const OpFn dynarec_ops_fpu_db_a16[256]; -extern const OpFn dynarec_ops_fpu_db_a32[256]; -extern const OpFn dynarec_ops_fpu_dc_a16[32]; -extern const OpFn dynarec_ops_fpu_dc_a32[32]; -extern const OpFn dynarec_ops_fpu_dd_a16[256]; -extern const OpFn dynarec_ops_fpu_dd_a32[256]; -extern const OpFn dynarec_ops_fpu_de_a16[256]; -extern const OpFn dynarec_ops_fpu_de_a32[256]; -extern const OpFn dynarec_ops_fpu_df_a16[256]; -extern const OpFn dynarec_ops_fpu_df_a32[256]; -extern const OpFn dynarec_ops_nofpu_a16[256]; -extern const OpFn dynarec_ops_nofpu_a32[256]; - -extern const OpFn dynarec_ops_fpu_686_da_a16[256]; -extern const OpFn dynarec_ops_fpu_686_da_a32[256]; -extern const OpFn dynarec_ops_fpu_686_db_a16[256]; -extern const OpFn dynarec_ops_fpu_686_db_a32[256]; -extern const OpFn dynarec_ops_fpu_686_df_a16[256]; -extern const OpFn dynarec_ops_fpu_686_df_a32[256]; - -extern const OpFn dynarec_ops_REPE[1024]; -extern const OpFn dynarec_ops_REPNE[1024]; -#else -void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); -#endif - -extern const OpFn *x86_opcodes; -extern const OpFn *x86_opcodes_0f; -extern const OpFn *x86_opcodes_d8_a16; -extern const OpFn *x86_opcodes_d8_a32; -extern const OpFn *x86_opcodes_d9_a16; -extern const OpFn *x86_opcodes_d9_a32; -extern const OpFn *x86_opcodes_da_a16; -extern const OpFn *x86_opcodes_da_a32; -extern const OpFn *x86_opcodes_db_a16; -extern const OpFn *x86_opcodes_db_a32; -extern const OpFn *x86_opcodes_dc_a16; -extern const OpFn *x86_opcodes_dc_a32; -extern const OpFn *x86_opcodes_dd_a16; -extern const OpFn *x86_opcodes_dd_a32; -extern const OpFn *x86_opcodes_de_a16; -extern const OpFn *x86_opcodes_de_a32; -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; - -extern const OpFn ops_286[1024]; -extern const OpFn ops_286_0f[1024]; - -extern const OpFn ops_386[1024]; -extern const OpFn ops_386_0f[1024]; - -extern const OpFn ops_486_0f[1024]; - -extern const OpFn ops_winchip_0f[1024]; - -extern const OpFn ops_pentium_0f[1024]; -extern const OpFn ops_pentiummmx_0f[1024]; - -extern const OpFn ops_c6x86mx_0f[1024]; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) -extern const OpFn ops_k6_0f[1024]; -#endif - -#if defined(DEV_BRANCH) && defined(USE_I686) -extern const OpFn ops_pentiumpro_0f[1024]; -extern const OpFn ops_pentium2d_0f[1024]; -#endif - -extern const OpFn ops_fpu_287_d9_a16[256]; -extern const OpFn ops_fpu_287_d9_a32[256]; -extern const OpFn ops_fpu_287_da_a16[256]; -extern const OpFn ops_fpu_287_da_a32[256]; -extern const OpFn ops_fpu_287_db_a16[256]; -extern const OpFn ops_fpu_287_db_a32[256]; -extern const OpFn ops_fpu_287_dc_a16[32]; -extern const OpFn ops_fpu_287_dc_a32[32]; -extern const OpFn ops_fpu_287_dd_a16[256]; -extern const OpFn ops_fpu_287_dd_a32[256]; -extern const OpFn ops_fpu_287_de_a16[256]; -extern const OpFn ops_fpu_287_de_a32[256]; -extern const OpFn ops_fpu_287_df_a16[256]; -extern const OpFn ops_fpu_287_df_a32[256]; - -extern const OpFn ops_fpu_d8_a16[32]; -extern const OpFn ops_fpu_d8_a32[32]; -extern const OpFn ops_fpu_d9_a16[256]; -extern const OpFn ops_fpu_d9_a32[256]; -extern const OpFn ops_fpu_da_a16[256]; -extern const OpFn ops_fpu_da_a32[256]; -extern const OpFn ops_fpu_db_a16[256]; -extern const OpFn ops_fpu_db_a32[256]; -extern const OpFn ops_fpu_dc_a16[32]; -extern const OpFn ops_fpu_dc_a32[32]; -extern const OpFn ops_fpu_dd_a16[256]; -extern const OpFn ops_fpu_dd_a32[256]; -extern const OpFn ops_fpu_de_a16[256]; -extern const OpFn ops_fpu_de_a32[256]; -extern const OpFn ops_fpu_df_a16[256]; -extern const OpFn ops_fpu_df_a32[256]; -extern const OpFn ops_nofpu_a16[256]; -extern const OpFn ops_nofpu_a32[256]; - -extern const OpFn ops_fpu_686_da_a16[256]; -extern const OpFn ops_fpu_686_da_a32[256]; -extern const OpFn ops_fpu_686_db_a16[256]; -extern const OpFn ops_fpu_686_db_a32[256]; -extern const OpFn ops_fpu_686_df_a16[256]; -extern const OpFn ops_fpu_686_df_a32[256]; - -extern const OpFn ops_REPE[1024]; -extern const OpFn ops_REPNE[1024]; - -#endif /*_X86_OPS_H*/ diff --git a/src - Cópia/cpu/x86_ops_amd.h b/src - Cópia/cpu/x86_ops_amd.h deleted file mode 100644 index acd7790ff..000000000 --- a/src - Cópia/cpu/x86_ops_amd.h +++ /dev/null @@ -1,192 +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. - * - * AMD SYSCALL and SYSRET CPU Instructions. - * - * Version: @(#)x86_ops_amd.h 1.0.3 2018/04/25 - * - * 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. */ - /* eflags &= ~0x00030200; - flags &= ~0x0200; */ - - /* Let's do this by the AMD spec. */ - ECX = cpu_state.pc; - - eflags &= ~0x0002; - flags &= ~0x0200; - - /* CS */ - _cs.seg = AMD_SYSCALL_SB & ~7; - if (AMD_SYSCALL_SB & 4) - { - if (_cs.seg >= ldt.limit) - { - pclog("Bigger than LDT limit %04X %04X CS\n",AMD_SYSCALL_SB,ldt.limit); - x86gpf(NULL, AMD_SYSCALL_SB & ~3); - return 1; - } - _cs.seg +=ldt.base; - } - else - { - if (_cs.seg >= gdt.limit) - { - pclog("Bigger than GDT limit %04X %04X CS\n",AMD_SYSCALL_SB,gdt.limit); - x86gpf(NULL, AMD_SYSCALL_SB & ~3); - return 1; - } - _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(&_cs, syscall_cs_seg_data); - use32 = 0x300; - - CS = (CS & 0xFFFC) | 0; - - _cs.limit = 0xFFFFFFFF; - _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(&_ss, syscall_ss_seg_data); - _ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC; - stack32 = 1; - - _ss.limit = 0xFFFFFFFF; - _ss.limit_high = 0xFFFFFFFF; - - _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; - - eflags |= (1 << 1); - - /* CS */ - _cs.seg = AMD_SYSRET_SB & ~7; - if (AMD_SYSRET_SB & 4) - { - if (_cs.seg >= ldt.limit) - { - pclog("Bigger than LDT limit %04X %04X CS\n",AMD_SYSRET_SB,ldt.limit); - x86gpf(NULL, AMD_SYSRET_SB & ~3); - return 1; - } - _cs.seg +=ldt.base; - } - else - { - if (_cs.seg >= gdt.limit) - { - pclog("Bigger than GDT limit %04X %04X CS\n",AMD_SYSRET_SB,gdt.limit); - x86gpf(NULL, AMD_SYSRET_SB & ~3); - return 1; - } - _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(&_cs, sysret_cs_seg_data); - flushmmucache_cr3(); - use32 = 0x300; - - CS = (CS & 0xFFFC) | 3; - - _cs.limit = 0xFFFFFFFF; - _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(&_ss, sysret_ss_seg_data); - _ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3; - stack32 = 1; - - _ss.limit = 0xFFFFFFFF; - _ss.limit_high = 0xFFFFFFFF; - - _ss.checked = 0; - - CLOCK_CYCLES(20); - - CPU_BLOCK_END(); - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_arith.h b/src - Cópia/cpu/x86_ops_arith.h deleted file mode 100644 index 3c6b67fa6..000000000 --- a/src - Cópia/cpu/x86_ops_arith.h +++ /dev/null @@ -1,744 +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) \ - dst = getea ## ea_width(); if (cpu_state.abrt) return 1; \ - switch (rmdat&0x38) \ - { \ - case 0x00: /*ADD ea, #*/ \ - setea ## ea_width(dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x08: /*OR ea, #*/ \ - dst |= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x10: /*ADC ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(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 0x18: /*SBB ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(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 0x20: /*AND ea, #*/ \ - dst &= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x28: /*SUB ea, #*/ \ - setea ## ea_width(dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x30: /*XOR ea, #*/ \ - dst ^= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x38: /*CMP ea, #*/ \ - 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(b, 8); - 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(b, 8); - 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(w, 16); - 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(w, 16); - 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(l, 32); - 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(l, 32); - 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(w, 16); - 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(w, 16); - 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(l, 32); - 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(l, 32); - 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 - Cópia/cpu/x86_ops_atomic.h b/src - Cópia/cpu/x86_ops_atomic.h deleted file mode 100644 index 7d90e22d1..000000000 --- a/src - Cópia/cpu/x86_ops_atomic.h +++ /dev/null @@ -1,278 +0,0 @@ -static int opCMPXCHG_b_a16(uint32_t fetchdat) -{ - uint8_t temp, temp2 = AL; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} -static int opCMPXCHG_b_a32(uint32_t fetchdat) -{ - uint8_t temp, temp2 = AL; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} - -static int opCMPXCHG_w_a16(uint32_t fetchdat) -{ - uint16_t temp, temp2 = AX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} -static int opCMPXCHG_w_a32(uint32_t fetchdat) -{ - uint16_t temp, temp2 = AX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} - -static int opCMPXCHG_l_a16(uint32_t fetchdat) -{ - uint32_t temp, temp2 = EAX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} -static int opCMPXCHG_l_a32(uint32_t fetchdat) -{ - uint32_t temp, temp2 = EAX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; -} - -static int opCMPXCHG8B_a16(uint32_t fetchdat) -{ - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - fetch_ea_16(fetchdat); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - flags |= Z_FLAG; - else - flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; - return 0; -} -static int opCMPXCHG8B_a32(uint32_t fetchdat) -{ - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - fetch_ea_32(fetchdat); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - flags |= Z_FLAG; - else - flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; - return 0; -} - -static int opXADD_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setadd8(temp, getr8(cpu_reg)); - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} -static int opXADD_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setadd8(temp, getr8(cpu_reg)); - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} - -static int opXADD_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - 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); - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} -static int opXADD_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - 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); - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} - -static int opXADD_l_a16(uint32_t fetchdat) -{ - uint32_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_16(fetchdat); - 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); - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} -static int opXADD_l_a32(uint32_t fetchdat) -{ - uint32_t temp; - if (!is486) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - fetch_ea_32(fetchdat); - 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); - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_bcd.h b/src - Cópia/cpu/x86_ops_bcd.h deleted file mode 100644 index 241216b14..000000000 --- a/src - Cópia/cpu/x86_ops_bcd.h +++ /dev/null @@ -1,113 +0,0 @@ -static int opAAA(uint32_t fetchdat) -{ - flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) - { - AL += 6; - AH++; - flags |= (A_FLAG | C_FLAG); - } - else - flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opAAD(uint32_t fetchdat) -{ - int base = getbytef(); - if (cpu_manufacturer != MANU_INTEL) base = 10; - AL = (AH * base) + AL; - AH = 0; - setznp16(AX); - CLOCK_CYCLES((is486) ? 14 : 19); - PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0,0,0,0, 0); - return 0; -} - -static int opAAM(uint32_t fetchdat) -{ - int base = getbytef(); - if (!base || cpu_manufacturer != MANU_INTEL) base = 10; - AH = AL / base; - AL %= base; - setznp16(AX); - CLOCK_CYCLES((is486) ? 15 : 17); - PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0,0,0,0, 0); - return 0; -} - -static int opAAS(uint32_t fetchdat) -{ - flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) - { - AL -= 6; - AH--; - flags |= (A_FLAG | C_FLAG); - } - else - flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opDAA(uint32_t fetchdat) -{ - uint16_t tempw; - - flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) - { - int tempi = ((uint16_t)AL) + 6; - AL += 6; - flags |= A_FLAG; - if (tempi & 0x100) flags |= C_FLAG; - } - if ((flags & C_FLAG) || (AL > 0x9f)) - { - AL += 0x60; - flags |= C_FLAG; - } - - tempw = flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - flags |= tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); - - return 0; -} - -static int opDAS(uint32_t fetchdat) -{ - uint16_t tempw; - - flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) - { - int tempi = ((uint16_t)AL) - 6; - AL -= 6; - flags |= A_FLAG; - if (tempi & 0x100) flags |= C_FLAG; - } - if ((flags & C_FLAG) || (AL > 0x9f)) - { - AL -= 0x60; - flags |= C_FLAG; - } - - tempw = flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - flags |= tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_bit.h b/src - Cópia/cpu/x86_ops_bit.h deleted file mode 100644 index dc10b4f6c..000000000 --- a/src - Cópia/cpu/x86_ops_bit.h +++ /dev/null @@ -1,312 +0,0 @@ -static int opBT_w_r_a16(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_16(fetchdat); - 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))) flags |= C_FLAG; - else flags &= ~C_FLAG; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); - return 0; -} -static int opBT_w_r_a32(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_32(fetchdat); - 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))) flags |= C_FLAG; - else flags &= ~C_FLAG; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); - return 0; -} -static int opBT_l_r_a16(uint32_t fetchdat) -{ - uint32_t temp; - - fetch_ea_16(fetchdat); - 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))) flags |= C_FLAG; - else flags &= ~C_FLAG; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); - return 0; -} -static int opBT_l_r_a32(uint32_t fetchdat) -{ - uint32_t temp; - - fetch_ea_32(fetchdat); - 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))) flags |= C_FLAG; - else flags &= ~C_FLAG; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); - return 0; -} - -#define opBT(name, operation) \ - static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_16(fetchdat); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \ - return 0; \ - } \ - static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_32(fetchdat); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_16(fetchdat); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_32(fetchdat); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \ - return 0; \ - } - -opBT(C, ^=) -opBT(R, &=~) -opBT(S, |=) - -static int opBA_w_a16(uint32_t fetchdat) -{ - int tempc, count; - uint16_t temp; - - fetch_ea_16(fetchdat); - - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; - - default: - pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; -} -static int opBA_w_a32(uint32_t fetchdat) -{ - int tempc, count; - uint16_t temp; - - fetch_ea_32(fetchdat); - - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; - - default: - pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; -} - -static int opBA_l_a16(uint32_t fetchdat) -{ - int tempc, count; - uint32_t temp; - - fetch_ea_16(fetchdat); - - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; - - default: - pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; -} -static int opBA_l_a32(uint32_t fetchdat) -{ - int tempc, count; - uint32_t temp; - - fetch_ea_32(fetchdat); - - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; - - default: - pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_bitscan.h b/src - Cópia/cpu/x86_ops_bitscan.h deleted file mode 100644 index 9252b4b87..000000000 --- a/src - Cópia/cpu/x86_ops_bitscan.h +++ /dev/null @@ -1,143 +0,0 @@ -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - instr_cycles = 0; \ - if (temp) \ - { \ - int c; \ - flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - instr_cycles += time; \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - flags |= Z_FLAG; - -static int opBSF_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - int instr_cycles = 0; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opBSF_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - int instr_cycles = 0; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opBSF_l_a16(uint32_t fetchdat) -{ - uint32_t temp; - int instr_cycles = 0; - - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; -} -static int opBSF_l_a32(uint32_t fetchdat) -{ - uint32_t temp; - int instr_cycles = 0; - - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; -} - -static int opBSR_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - int instr_cycles = 0; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opBSR_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - int instr_cycles = 0; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opBSR_l_a16(uint32_t fetchdat) -{ - uint32_t temp; - int instr_cycles = 0; - - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; -} -static int opBSR_l_a32(uint32_t fetchdat) -{ - uint32_t temp; - int instr_cycles = 0; - - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - - CLOCK_CYCLES((is486) ? 6 : 10); - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; -} - diff --git a/src - Cópia/cpu/x86_ops_call.h b/src - Cópia/cpu/x86_ops_call.h deleted file mode 100644 index 30e60410c..000000000 --- a/src - Cópia/cpu/x86_ops_call.h +++ /dev/null @@ -1,401 +0,0 @@ -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } - -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } - - -static int opCALL_far_w(uint32_t fetchdat) -{ - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - new_pc = getwordf(); - new_cs = getword(); if (cpu_state.abrt) return 1; - - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 5, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - - return 0; -} -static int opCALL_far_l(uint32_t fetchdat) -{ - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - new_pc = getlong(); - new_cs = getword(); if (cpu_state.abrt) return 1; - - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 7, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - - return 0; -} - - -static int opFF_w_a16(uint32_t fetchdat) -{ - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - uint16_t temp; - - fetch_ea_16(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x08: /*DEC w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x10: /*CALL*/ - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; - - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - oxpc = cpu_state.pc; - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - break; - - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; -} -static int opFF_w_a32(uint32_t fetchdat) -{ - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - uint16_t temp; - - fetch_ea_32(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x08: /*DEC w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x10: /*CALL*/ - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; - - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - oxpc = cpu_state.pc; - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - break; - - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; -} - -static int opFF_l_a16(uint32_t fetchdat) -{ - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - uint32_t temp; - - fetch_ea_16(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x08: /*DEC l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x10: /*CALL*/ - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; - - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - oxpc = cpu_state.pc; - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - break; - - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; -} -static int opFF_l_a32(uint32_t fetchdat) -{ - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); - - uint32_t temp; - - fetch_ea_32(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x08: /*DEC l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x10: /*CALL*/ - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; - - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - oxpc = cpu_state.pc; - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - break; - - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; -} diff --git a/src - Cópia/cpu/x86_ops_flag.h b/src - Cópia/cpu/x86_ops_flag.h deleted file mode 100644 index 59c692c65..000000000 --- a/src - Cópia/cpu/x86_ops_flag.h +++ /dev/null @@ -1,284 +0,0 @@ -static int opCMC(uint32_t fetchdat) -{ - flags_rebuild(); - flags ^= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - - -static int opCLC(uint32_t fetchdat) -{ - flags_rebuild(); - flags &= ~C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opCLD(uint32_t fetchdat) -{ - flags &= ~D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opCLI(uint32_t fetchdat) -{ - if (!IOPLp) - { - if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - eflags &= ~VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - flags &= ~I_FLAG; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSTC(uint32_t fetchdat) -{ - flags_rebuild(); - flags |= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTD(uint32_t fetchdat) -{ - flags |= D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTI(uint32_t fetchdat) -{ - if (!IOPLp) - { - if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - if (eflags & VIP_FLAG) - { - x86gpf(NULL,0); - return 1; - } - else - eflags |= VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - flags |= I_FLAG; - - CPU_BLOCK_END(); - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSAHF(uint32_t fetchdat) -{ - flags_rebuild(); - flags = (flags & 0xff00) | (AH & 0xd5) | 2; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - -#if 0 - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opLAHF(uint32_t fetchdat) -{ - flags_rebuild(); - AH = flags & 0xff; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opPUSHF(uint32_t fetchdat) -{ - if ((eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint16_t temp; - - flags_rebuild(); - temp = (flags & ~I_FLAG) | 0x3000; - if (eflags & VIF_FLAG) - temp |= I_FLAG; - PUSH_W(temp); - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - { - flags_rebuild(); - PUSH_W(flags); - } - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSHFD(uint32_t fetchdat) -{ - uint16_t tempw; - if ((eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c; - else if (CPUID) tempw = eflags & 0x24; - else tempw = eflags & 4; - flags_rebuild(); - PUSH_L(flags | (tempw << 16)); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} - -static int opPOPF_286(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - tempw = POP_W(); if (cpu_state.abrt) return 1; - - if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; - else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if 0 - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPF(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint32_t old_esp = ESP; - - tempw = POP_W(); - if (cpu_state.abrt) - { - - ESP = old_esp; - return 1; - } - - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG))) - { - ESP = old_esp; - x86gpf(NULL, 0); - return 1; - } - if (tempw & I_FLAG) - eflags |= VIF_FLAG; - else - eflags &= ~VIF_FLAG; - flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - else - { - x86gpf(NULL, 0); - return 1; - } - } - else - { - tempw = POP_W(); - if (cpu_state.abrt) - return 1; - - if (!(CPL) || !(msw & 1)) - flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if 0 - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPFD(uint32_t fetchdat) -{ - uint32_t templ; - - if ((eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - templ = POP_L(); if (cpu_state.abrt) return 1; - - if (!(CPL) || !(msw & 1)) flags = (templ & 0x7fd5) | 2; - else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2; - else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2; - - templ &= is486 ? 0x3c0000 : 0; - templ |= ((eflags&3) << 16); - if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f; - else if (CPUID) eflags = (templ >> 16) & 0x27; - else if (is486) eflags = (templ >> 16) & 7; - else eflags = (templ >> 16) & 3; - - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - -#if 0 - codegen_flags_changed = 0; -#endif - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_fpu.h b/src - Cópia/cpu/x86_ops_fpu.h deleted file mode 100644 index a1976f268..000000000 --- a/src - Cópia/cpu/x86_ops_fpu.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -static int opESCAPE_d8_a16(uint32_t fetchdat) -{ - return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); -} -static int opESCAPE_d8_a32(uint32_t fetchdat) -{ - return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); -} - -static int opESCAPE_d9_a16(uint32_t fetchdat) -{ - return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_d9_a32(uint32_t fetchdat) -{ - return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); -} - -static int opESCAPE_da_a16(uint32_t fetchdat) -{ - return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_da_a32(uint32_t fetchdat) -{ - return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); -} - -static int opESCAPE_db_a16(uint32_t fetchdat) -{ - return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_db_a32(uint32_t fetchdat) -{ - return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); -} - -static int opESCAPE_dc_a16(uint32_t fetchdat) -{ - return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); -} -static int opESCAPE_dc_a32(uint32_t fetchdat) -{ - return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); -} - -static int opESCAPE_dd_a16(uint32_t fetchdat) -{ - return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_dd_a32(uint32_t fetchdat) -{ - return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); -} - -static int opESCAPE_de_a16(uint32_t fetchdat) -{ - return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_de_a32(uint32_t fetchdat) -{ - return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); -} - -static int opESCAPE_df_a16(uint32_t fetchdat) -{ - return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); -} -static int opESCAPE_df_a32(uint32_t fetchdat) -{ - return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); -} - -static int opWAIT(uint32_t fetchdat) -{ - if ((cr0 & 0xa) == 0xa) - { - x86_int(7); - return 1; - } - CLOCK_CYCLES(4); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_i686.h b/src - Cópia/cpu/x86_ops_i686.h deleted file mode 100644 index d4418bfb4..000000000 --- a/src - Cópia/cpu/x86_ops_i686.h +++ /dev/null @@ -1,508 +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. - * - * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. - * - * Version: @(#)x86_ops_i686.h 1.0.4 2018/04/25 - * - * 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 */ - -static void make_seg_data(uint16_t *seg_data, uint32_t base, uint32_t limit, uint8_t type, uint8_t s, uint8_t dpl, uint8_t p, uint8_t g, uint8_t db, uint8_t a) -{ - seg_data[0] = limit & 0xFFFF; - seg_data[1] = base & 0xFFFF; - seg_data[2] = ((base >> 16) & 0xFF) | (type << 8) | (p << 15) | (dpl << 13) | (s << 12); - seg_data[3] = ((limit >> 16) & 0xF) | (a << 4) | (db << 6) | (g << 7) | ((base >> 16) & 0xFF00); -} - -static int opSYSENTER(uint32_t fetchdat) -{ - uint16_t sysenter_cs_seg_data[4]; - uint16_t sysenter_ss_seg_data[4]; - -#ifdef SYSENTER_LOG - pclog("SYSENTER called\n"); -#endif - - if (!(cr0 & 1)) return internal_illegal("SYSENTER: CPU not in protected mode"); - if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSENTER: CS MSR is zero"); - -#ifdef SYSENTER_LOG - pclog("SYSENTER started:\n"); - pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); - pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); - pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); - pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); -#endif - - if (cpu_state.abrt) return 1; - - ESP = esp_msr; - cpu_state.pc = eip_msr; - - optype = CALL; \ - cgate16 = cgate32 = 0; \ - - /* Set VM, RF, and IF to 0. */ - eflags &= ~0x0003; - flags &= ~0x0200; - - CS = (cs_msr & 0xFFFC); - make_seg_data(sysenter_cs_seg_data, 0, 0xFFFFF, 11, 1, 0, 1, 1, 1, 0); - do_seg_load(&_cs, sysenter_cs_seg_data); - use32 = 0x300; - - SS = ((cs_msr + 8) & 0xFFFC); - make_seg_data(sysenter_ss_seg_data, 0, 0xFFFFF, 3, 1, 0, 1, 1, 1, 0); - do_seg_load(&_ss, sysenter_ss_seg_data); - stack32 = 1; - - cycles -= timing_call_pm; - - optype = 0; - - CPU_BLOCK_END(); - -#ifdef SYSENTER_LOG - pclog("SYSENTER completed:\n"); - pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); - pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); - pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); - pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); -#endif - - return 0; -} - -static int opSYSEXIT(uint32_t fetchdat) -{ - uint16_t sysexit_cs_seg_data[4]; - uint16_t sysexit_ss_seg_data[4]; - -#ifdef SYSEXIT_LOG - pclog("SYSEXIT called\n"); -#endif - - if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSEXIT: CS MSR is zero"); - if (!(cr0 & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode"); - if (CS & 3) return internal_illegal("SYSEXIT: CPL not 0"); - -#ifdef SYSEXIT_LOG - pclog("SYSEXIT start:\n"); - pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); - pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); - pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); - pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); -#endif - - if (cpu_state.abrt) return 1; - - ESP = ECX; - cpu_state.pc = EDX; - - optype = CALL; \ - cgate16 = cgate32 = 0; \ - - CS = ((cs_msr + 16) & 0xFFFC) | 3; - make_seg_data(sysexit_cs_seg_data, 0, 0xFFFFF, 11, 1, 3, 1, 1, 1, 0); - do_seg_load(&_cs, sysexit_cs_seg_data); - use32 = 0x300; - - SS = CS + 8; - make_seg_data(sysexit_ss_seg_data, 0, 0xFFFFF, 3, 1, 3, 1, 1, 1, 0); - do_seg_load(&_ss, sysexit_ss_seg_data); - stack32 = 1; - - flushmmucache_cr3(); - - cycles -= timing_call_pm; - - optype = 0; - - CPU_BLOCK_END(); - -#ifdef SYSEXIT_LOG - pclog("SYSEXIT completed:\n"); - pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); - pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); - pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); - pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); -#endif - - return 0; -} - -static int opFXSAVESTOR_a16(uint32_t fetchdat) -{ - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint16_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; - uint64_t *p; - - if (CPUID < 0x650) return ILLEGAL(fetchdat); - - FP_ENTER(); - - fetch_ea_16(fetchdat); - - if (cpu_state.eaaddr & 0xf) - { - pclog("Effective address %04X not on 16-byte boundary\n", cpu_state.eaaddr); - x86gpf(NULL, 0); - return cpu_state.abrt; - } - - fxinst = (rmdat >> 3) & 7; - - if ((fxinst > 1) || (cpu_mod == 3)) - { - x86illegal(); - return cpu_state.abrt; - } - - FP_ENTER(); - - old_eaaddr = cpu_state.eaaddr; - - if (fxinst == 1) - { - /* FXRSTOR */ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - fpus = readmemw(easeg, cpu_state.eaaddr + 2); - cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; - cpu_state.TOP = (fpus >> 11) & 7; - cpu_state.npxs &= fpus & ~0x3800; - - /* foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; */ - - x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8); - x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12); - /* if (cr0 & 1) - { - x87_pc_seg &= 0xFFFC; - x87_pc_seg |= ((_cs.access >> 5) & 3); - } */ - - ftwb = readmemb(easeg, cpu_state.eaaddr + 4); - - if (ftwb & 0x01) rec_ftw |= 0x0003; - if (ftwb & 0x02) rec_ftw |= 0x000C; - if (ftwb & 0x04) rec_ftw |= 0x0030; - if (ftwb & 0x08) rec_ftw |= 0x00C0; - if (ftwb & 0x10) rec_ftw |= 0x0300; - if (ftwb & 0x20) rec_ftw |= 0x0C00; - if (ftwb & 0x40) rec_ftw |= 0x3000; - if (ftwb & 0x80) rec_ftw |= 0xC000; - - x87_op_off = readmeml(easeg, cpu_state.eaaddr+16); - x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; - x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20); - /* if (cr0 & 1) - { - x87_op_seg &= 0xFFFC; - x87_op_seg |= ((_ds.access >> 5) & 3); - } */ - - cpu_state.eaaddr = old_eaaddr + 32; - x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0); - - cpu_state.eaaddr = old_eaaddr + 48; - x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1); - - cpu_state.eaaddr = old_eaaddr + 64; - x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2); - - cpu_state.eaaddr = old_eaaddr + 80; - x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3); - - cpu_state.eaaddr = old_eaaddr + 96; - x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4); - - cpu_state.eaaddr = old_eaaddr + 112; - x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5); - - cpu_state.eaaddr = old_eaaddr + 128; - x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6); - - cpu_state.eaaddr = old_eaaddr + 144; - x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7); - - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *)cpu_state.tag; - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - cpu_state.ismmx = 1; - - x87_settag(rec_ftw); - - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - - if(cpu_state.abrt) pclog("FXRSTOR: abrt != 0\n"); - } - else - { - /* FXSAVE */ - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; - if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; - if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; - if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08; - if ((twd & 0x0300) == 0x0300) ftwb |= 0x10; - if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20; - if ((twd & 0x3000) == 0x3000) ftwb |= 0x40; - if ((twd & 0xC000) == 0xC000) ftwb |= 0x80; - - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememb(easeg,cpu_state.eaaddr+4,ftwb); - - writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12); - writememl(easeg,cpu_state.eaaddr+8,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg); - - writememl(easeg,cpu_state.eaaddr+16,x87_op_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_seg); - - cpu_state.eaaddr = old_eaaddr + 32; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); - - cpu_state.eaaddr = old_eaaddr + 48; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); - - cpu_state.eaaddr = old_eaaddr + 64; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); - - cpu_state.eaaddr = old_eaaddr + 80; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); - - cpu_state.eaaddr = old_eaaddr + 96; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); - - cpu_state.eaaddr = old_eaaddr + 112; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); - - cpu_state.eaaddr = old_eaaddr + 128; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); - - cpu_state.eaaddr = old_eaaddr + 144; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); - - cpu_state.eaaddr = old_eaaddr; - - cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - - if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n"); - } - - return cpu_state.abrt; -} - -static int opFXSAVESTOR_a32(uint32_t fetchdat) -{ - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; - uint64_t *p; - - if (CPUID < 0x650) return ILLEGAL(fetchdat); - - FP_ENTER(); - - fetch_ea_32(fetchdat); - - if (cpu_state.eaaddr & 0xf) - { - pclog("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); - x86gpf(NULL, 0); - return cpu_state.abrt; - } - - fxinst = (rmdat >> 3) & 7; - - if ((fxinst > 1) || (cpu_mod == 3)) - { - x86illegal(); - return cpu_state.abrt; - } - - FP_ENTER(); - - old_eaaddr = cpu_state.eaaddr; - - if (fxinst == 1) - { - /* FXRSTOR */ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - fpus = readmemw(easeg, cpu_state.eaaddr + 2); - cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; - cpu_state.TOP = (fpus >> 11) & 7; - cpu_state.npxs &= fpus & ~0x3800; - - /* foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; */ - - x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8); - x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12); - /* if (cr0 & 1) - { - x87_pc_seg &= 0xFFFC; - x87_pc_seg |= ((_cs.access >> 5) & 3); - } */ - - ftwb = readmemb(easeg, cpu_state.eaaddr + 4); - - if (ftwb & 0x01) rec_ftw |= 0x0003; - if (ftwb & 0x02) rec_ftw |= 0x000C; - if (ftwb & 0x04) rec_ftw |= 0x0030; - if (ftwb & 0x08) rec_ftw |= 0x00C0; - if (ftwb & 0x10) rec_ftw |= 0x0300; - if (ftwb & 0x20) rec_ftw |= 0x0C00; - if (ftwb & 0x40) rec_ftw |= 0x3000; - if (ftwb & 0x80) rec_ftw |= 0xC000; - - x87_op_off = readmeml(easeg, cpu_state.eaaddr+16); - x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; - x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20); - /* if (cr0 & 1) - { - x87_op_seg &= 0xFFFC; - x87_op_seg |= ((_ds.access >> 5) & 3); - } */ - - cpu_state.eaaddr = old_eaaddr + 32; - x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0); - - cpu_state.eaaddr = old_eaaddr + 48; - x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1); - - cpu_state.eaaddr = old_eaaddr + 64; - x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2); - - cpu_state.eaaddr = old_eaaddr + 80; - x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3); - - cpu_state.eaaddr = old_eaaddr + 96; - x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4); - - cpu_state.eaaddr = old_eaaddr + 112; - x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5); - - cpu_state.eaaddr = old_eaaddr + 128; - x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6); - - cpu_state.eaaddr = old_eaaddr + 144; - x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7); - - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *)cpu_state.tag; - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - cpu_state.ismmx = 1; - - x87_settag(rec_ftw); - - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - - if(cpu_state.abrt) pclog("FXRSTOR: abrt != 0\n"); - } - else - { - /* FXSAVE */ - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; - if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; - if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; - if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08; - if ((twd & 0x0300) == 0x0300) ftwb |= 0x10; - if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20; - if ((twd & 0x3000) == 0x3000) ftwb |= 0x40; - if ((twd & 0xC000) == 0xC000) ftwb |= 0x80; - - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememb(easeg,cpu_state.eaaddr+4,ftwb); - - writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12); - writememl(easeg,cpu_state.eaaddr+8,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg); - - writememl(easeg,cpu_state.eaaddr+16,x87_op_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_seg); - - cpu_state.eaaddr = old_eaaddr + 32; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); - - cpu_state.eaaddr = old_eaaddr + 48; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); - - cpu_state.eaaddr = old_eaaddr + 64; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); - - cpu_state.eaaddr = old_eaaddr + 80; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); - - cpu_state.eaaddr = old_eaaddr + 96; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); - - cpu_state.eaaddr = old_eaaddr + 112; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); - - cpu_state.eaaddr = old_eaaddr + 128; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); - - cpu_state.eaaddr = old_eaaddr + 144; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); - - cpu_state.eaaddr = old_eaaddr; - - cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - - if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n"); - } - - return cpu_state.abrt; -} diff --git a/src - Cópia/cpu/x86_ops_inc_dec.h b/src - Cópia/cpu/x86_ops_inc_dec.h deleted file mode 100644 index 56293c7bf..000000000 --- a/src - Cópia/cpu/x86_ops_inc_dec.h +++ /dev/null @@ -1,89 +0,0 @@ -#define INC_DEC_OP(name, reg, inc, setflags) \ - static int op ## name (uint32_t fetchdat) \ - { \ - setflags(reg, 1); \ - reg += inc; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } - -INC_DEC_OP(INC_AX, AX, 1, setadd16nc) -INC_DEC_OP(INC_BX, BX, 1, setadd16nc) -INC_DEC_OP(INC_CX, CX, 1, setadd16nc) -INC_DEC_OP(INC_DX, DX, 1, setadd16nc) -INC_DEC_OP(INC_SI, SI, 1, setadd16nc) -INC_DEC_OP(INC_DI, DI, 1, setadd16nc) -INC_DEC_OP(INC_BP, BP, 1, setadd16nc) -INC_DEC_OP(INC_SP, SP, 1, setadd16nc) - -INC_DEC_OP(INC_EAX, EAX, 1, setadd32nc) -INC_DEC_OP(INC_EBX, EBX, 1, setadd32nc) -INC_DEC_OP(INC_ECX, ECX, 1, setadd32nc) -INC_DEC_OP(INC_EDX, EDX, 1, setadd32nc) -INC_DEC_OP(INC_ESI, ESI, 1, setadd32nc) -INC_DEC_OP(INC_EDI, EDI, 1, setadd32nc) -INC_DEC_OP(INC_EBP, EBP, 1, setadd32nc) -INC_DEC_OP(INC_ESP, ESP, 1, setadd32nc) - -INC_DEC_OP(DEC_AX, AX, -1, setsub16nc) -INC_DEC_OP(DEC_BX, BX, -1, setsub16nc) -INC_DEC_OP(DEC_CX, CX, -1, setsub16nc) -INC_DEC_OP(DEC_DX, DX, -1, setsub16nc) -INC_DEC_OP(DEC_SI, SI, -1, setsub16nc) -INC_DEC_OP(DEC_DI, DI, -1, setsub16nc) -INC_DEC_OP(DEC_BP, BP, -1, setsub16nc) -INC_DEC_OP(DEC_SP, SP, -1, setsub16nc) - -INC_DEC_OP(DEC_EAX, EAX, -1, setsub32nc) -INC_DEC_OP(DEC_EBX, EBX, -1, setsub32nc) -INC_DEC_OP(DEC_ECX, ECX, -1, setsub32nc) -INC_DEC_OP(DEC_EDX, EDX, -1, setsub32nc) -INC_DEC_OP(DEC_ESI, ESI, -1, setsub32nc) -INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc) -INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc) -INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc) - - -static int opINCDEC_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_16(fetchdat); - temp=geteab(); if (cpu_state.abrt) return 1; - - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; -} -static int opINCDEC_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_32(fetchdat); - temp=geteab(); if (cpu_state.abrt) return 1; - - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_int.h b/src - Cópia/cpu/x86_ops_int.h deleted file mode 100644 index 5aa05fc11..000000000 --- a/src - Cópia/cpu/x86_ops_int.h +++ /dev/null @@ -1,91 +0,0 @@ -static int opINT3(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(3); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; -} - -static int opINT1(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(1); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; -} - -static int opINT(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - uint8_t temp = getbytef(); - - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t t; - uint8_t d; - - cpl_override = 1; - t = readmemw(tr.base, 0x66) - 32; - cpl_override = 0; - if (cpu_state.abrt) return 1; - - t += (temp >> 3); - if (t <= tr.limit) - { - cpl_override = 1; - d = readmemb(tr.base, t);// + (temp >> 3)); - cpl_override = 0; - if (cpu_state.abrt) return 1; - - if (!(d & (1 << (temp & 7)))) - { - x86_int_sw_rm(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); - return 1; - } - } - } - x86gpf(NULL,0); - return 1; - } - - x86_int_sw(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); - return 1; -} - -static int opINTO(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (VF_SET()) - { - cpu_state.oldpc = cpu_state.pc; - x86_int_sw(4); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; - } - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - diff --git a/src - Cópia/cpu/x86_ops_io.h b/src - Cópia/cpu/x86_ops_io.h deleted file mode 100644 index 9fa91a215..000000000 --- a/src - Cópia/cpu/x86_ops_io.h +++ /dev/null @@ -1,146 +0,0 @@ -static int opIN_AL_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - AL = inb(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - AX = inw(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - EAX = inl(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opOUT_AL_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - outb(port, AL); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (port == 0x64) - return x86_was_reset; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - outw(port, AX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - outl(port, EAX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opIN_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - AL = inb(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - AX = inw(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - EAX = inl(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opOUT_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - outb(DX, AL); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return x86_was_reset; -} -static int opOUT_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - outw(DX, AX); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - outl(DX, EAX); - PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_jump.h b/src - Cópia/cpu/x86_ops_jump.h deleted file mode 100644 index 63ca65ea0..000000000 --- a/src - Cópia/cpu/x86_ops_jump.h +++ /dev/null @@ -1,358 +0,0 @@ -#define cond_O ( VF_SET()) -#define cond_NO (!VF_SET()) -#define cond_B ( CF_SET()) -#define cond_NB (!CF_SET()) -#define cond_E ( ZF_SET()) -#define cond_NE (!ZF_SET()) -#define cond_BE ( CF_SET() || ZF_SET()) -#define cond_NBE (!CF_SET() && !ZF_SET()) -#define cond_S ( NF_SET()) -#define cond_NS (!NF_SET()) -#define cond_P ( PF_SET()) -#define cond_NP (!PF_SET()) -#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) -#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) -#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) -#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) - -#define opJ(condition) \ - static int opJ ## condition(uint32_t fetchdat) \ - { \ - int8_t offset = (int8_t)getbytef(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _w(uint32_t fetchdat) \ - { \ - int16_t offset = (int16_t)getwordf(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _l(uint32_t fetchdat) \ - { \ - uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - -opJ(O) -opJ(NO) -opJ(B) -opJ(NB) -opJ(E) -opJ(NE) -opJ(BE) -opJ(NBE) -opJ(S) -opJ(NS) -opJ(P) -opJ(NP) -opJ(L) -opJ(NL) -opJ(LE) -opJ(NLE) - - - -static int opLOOPNE_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && !ZF_SET()) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPNE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && !ZF_SET()) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOPE_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && ZF_SET()) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && ZF_SET()) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOP_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOP_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX) - { - cpu_state.pc += offset; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opJCXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!CX) - { - cpu_state.pc += offset; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opJECXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!ECX) - { - cpu_state.pc += offset; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} - - -static int opJMP_r8(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - cpu_state.pc += offset; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opJMP_r16(uint32_t fetchdat) -{ - int16_t offset = (int16_t)getwordf(); - cpu_state.pc += offset; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opJMP_r32(uint32_t fetchdat) -{ - int32_t offset = (int32_t)getlong(); if (cpu_state.abrt) return 1; - cpu_state.pc += offset; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} - -static int opJMP_far_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - uint32_t oxpc; - addr = getwordf(); - seg = getword(); if (cpu_state.abrt) return 1; - oxpc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, oxpc); - CPU_BLOCK_END(); - PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opJMP_far_a32(uint32_t fetchdat) -{ - uint16_t seg; - uint32_t addr, oxpc; - addr = getlong(); - seg = getword(); if (cpu_state.abrt) return 1; - oxpc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, oxpc); - CPU_BLOCK_END(); - PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} - -static int opCALL_r16(uint32_t fetchdat) -{ - int16_t addr = (int16_t)getwordf(); - PUSH_W(cpu_state.pc); - cpu_state.pc += addr; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opCALL_r32(uint32_t fetchdat) -{ - int32_t addr = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc += addr; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,1, 0); - PREFETCH_FLUSH(); - return 0; -} - -static int opRET_w(uint32_t fetchdat) -{ - uint16_t ret; - - ret = POP_W(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opRET_l(uint32_t fetchdat) -{ - uint32_t ret; - - ret = POP_L(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} - -static int opRET_w_imm(uint32_t fetchdat) -{ - uint16_t ret; - uint16_t offset = getwordf(); - - ret = POP_W(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opRET_l_imm(uint32_t fetchdat) -{ - uint32_t ret; - uint16_t offset = getwordf(); - - ret = POP_L(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} - diff --git a/src - Cópia/cpu/x86_ops_misc.h b/src - Cópia/cpu/x86_ops_misc.h deleted file mode 100644 index 9fa219919..000000000 --- a/src - Cópia/cpu/x86_ops_misc.h +++ /dev/null @@ -1,941 +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. - * - * Miscellaneous x86 CPU Instructions. - * - * Version: @(#)x86_ops_misc.h 1.0.1 2018/04/12 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -static int opCBW(uint32_t fetchdat) -{ - AH = (AL & 0x80) ? 0xff : 0; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opCWDE(uint32_t fetchdat) -{ - EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opCWD(uint32_t fetchdat) -{ - DX = (AX & 0x8000) ? 0xFFFF : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opCDQ(uint32_t fetchdat) -{ - EDX = (EAX & 0x80000000) ? 0xffffffff : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opNOP(uint32_t fetchdat) -{ - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSETALC(uint32_t fetchdat) -{ - AL = (CF_SET()) ? 0xff : 0; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); - return 0; -} - - - -static int opF6_a16(uint32_t fetchdat) -{ - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - { - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - } - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT b*/ - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG b*/ - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - flags |= 0x8D5; /*Not a Cyrix*/ - flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - flags|=0x8D5; /*Not a Cyrix*/ - flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - pclog("Bad F6 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} -static int opF6_a32(uint32_t fetchdat) -{ - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; - - fetch_ea_32(fetchdat); - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT b*/ - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG b*/ - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - flags |= 0x8D5; /*Not a Cyrix*/ - flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - flags|=0x8D5; /*Not a Cyrix*/ - flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - pclog("Bad F6 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} - - - -static int opF7_w_a16(uint32_t fetchdat) -{ - uint32_t templ, templ2; - int tempws, tempws2 = 0; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_16(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT w*/ - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG w*/ - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - pclog("Bad F7 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} -static int opF7_w_a32(uint32_t fetchdat) -{ - uint32_t templ, templ2; - int tempws, tempws2 = 0; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_32(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT w*/ - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG w*/ - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - pclog("Bad F7 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} - -static int opF7_l_a16(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_16(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x10: /*NOT l*/ - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x18: /*NEG l*/ - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) flags |= (C_FLAG|V_FLAG); - else flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40:38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - - default: - pclog("Bad F7 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} -static int opF7_l_a32(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_32(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x10: /*NOT l*/ - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x18: /*NEG l*/ - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) flags |= (C_FLAG|V_FLAG); - else flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - - default: - pclog("Bad F7 opcode %02X\n", rmdat & 0x38); - x86illegal(); - } - return 0; -} - - -static int opHLT(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (!((flags&I_FLAG) && pic_intpending)) - { - CLOCK_CYCLES_ALWAYS(100); - cpu_state.pc--; - } - else - CLOCK_CYCLES(5); - - CPU_BLOCK_END(); - PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); - - return 0; -} - - -static int opLOCK(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 0; - cpu_state.pc++; - - ILLEGAL_ON((fetchdat & 0xff) == 0x90); - - CLOCK_CYCLES(4); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} - - - -static int opBOUND_w_a16(uint32_t fetchdat) -{ - int16_t low, high; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); - return 1; - } - - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 0); - return 0; -} -static int opBOUND_w_a32(uint32_t fetchdat) -{ - int16_t low, high; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); - return 1; - } - - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 1); - return 0; -} - -static int opBOUND_l_a16(uint32_t fetchdat) -{ - int32_t low, high; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); - return 1; - } - - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 0); - return 0; -} -static int opBOUND_l_a32(uint32_t fetchdat) -{ - int32_t low, high; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); - return 1; - } - - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 1); - return 0; -} - - -static int opCLTS(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't CLTS\n"); - x86gpf(NULL,0); - return 1; - } - cr0 &= ~8; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opINVD(uint32_t fetchdat) -{ - if (!is486) - { - x86illegal(); - return 1; - } - CLOCK_CYCLES(1000); - CPU_BLOCK_END(); - return 0; -} -static int opWBINVD(uint32_t fetchdat) -{ - if (!is486) - { - x86illegal(); - return 1; - } - CLOCK_CYCLES(10000); - CPU_BLOCK_END(); - return 0; -} - -static int opLOADALL(uint32_t fetchdat) -{ - if (CPL && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - msw = (msw & 1) | readmemw(0, 0x806); - flags = (readmemw(0, 0x818) & 0xffd5) | 2; - flags_extract(); - tr.seg = readmemw(0, 0x816); - cpu_state.pc = readmemw(0, 0x81A); - ldt.seg = readmemw(0, 0x81C); - DS = readmemw(0, 0x81E); - SS = readmemw(0, 0x820); - CS = readmemw(0, 0x822); - ES = readmemw(0, 0x824); - DI = readmemw(0, 0x826); - SI = readmemw(0, 0x828); - BP = readmemw(0, 0x82A); - SP = readmemw(0, 0x82C); - BX = readmemw(0, 0x82E); - DX = readmemw(0, 0x830); - CX = readmemw(0, 0x832); - AX = readmemw(0, 0x834); - es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); - _es.access = readmemb(0, 0x839); - _es.limit = readmemw(0, 0x83A); - cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - _cs.access = readmemb(0, 0x83F); - _cs.limit = readmemw(0, 0x840); - ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); - _ss.access = readmemb(0, 0x845); - _ss.limit = readmemw(0, 0x846); - if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); - _ds.access = readmemb(0, 0x84B); - _ds.limit = readmemw(0, 0x84C); - if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); - gdt.limit = readmemw(0, 0x852); - ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); - ldt.access = readmemb(0, 0x857); - ldt.limit = readmemw(0, 0x858); - idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); - idt.limit = readmemw(0, 0x85E); - tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); - tr.access = readmemb(0, 0x863); - tr.limit = readmemw(0, 0x864); - CLOCK_CYCLES(195); - PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0); - return 0; -} - -static void set_segment_limit(x86seg *s, uint8_t segdat3) -{ - if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } -} - -static void loadall_load_segment(uint32_t addr, x86seg *s) -{ - uint32_t attrib = readmeml(0, addr); - uint32_t segdat3 = (attrib >> 16) & 0xff; - s->access = (attrib >> 8) & 0xff; - s->base = readmeml(0, addr + 4); - s->limit = readmeml(0, addr + 8); - - if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; - cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); - if (use32) - cpu_cur_status |= CPU_STATUS_USE32; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - - set_segment_limit(s, segdat3); - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static int opLOADALL386(uint32_t fetchdat) -{ - uint32_t la_addr = es + EDI; - - cr0 = readmeml(0, la_addr); - flags = readmemw(0, la_addr + 4); - eflags = readmemw(0, la_addr + 6); - flags_extract(); - cpu_state.pc = readmeml(0, la_addr + 8); - EDI = readmeml(0, la_addr + 0xC); - ESI = readmeml(0, la_addr + 0x10); - EBP = readmeml(0, la_addr + 0x14); - ESP = readmeml(0, la_addr + 0x18); - EBX = readmeml(0, la_addr + 0x1C); - EDX = readmeml(0, la_addr + 0x20); - ECX = readmeml(0, la_addr + 0x24); - EAX = readmeml(0, la_addr + 0x28); - dr[6] = readmeml(0, la_addr + 0x2C); - dr[7] = readmeml(0, la_addr + 0x30); - tr.seg = readmemw(0, la_addr + 0x34); - ldt.seg = readmemw(0, la_addr + 0x38); - GS = readmemw(0, la_addr + 0x3C); - FS = readmemw(0, la_addr + 0x40); - DS = readmemw(0, la_addr + 0x44); - SS = readmemw(0, la_addr + 0x48); - CS = readmemw(0, la_addr + 0x4C); - ES = readmemw(0, la_addr + 0x50); - - loadall_load_segment(la_addr + 0x54, &tr); - loadall_load_segment(la_addr + 0x60, &idt); - loadall_load_segment(la_addr + 0x6c, &gdt); - loadall_load_segment(la_addr + 0x78, &ldt); - loadall_load_segment(la_addr + 0x84, &_gs); - loadall_load_segment(la_addr + 0x90, &_fs); - loadall_load_segment(la_addr + 0x9c, &_ds); - loadall_load_segment(la_addr + 0xa8, &_ss); - loadall_load_segment(la_addr + 0xb4, &_cs); - loadall_load_segment(la_addr + 0xc0, &_es); - - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - - CLOCK_CYCLES(350); - return 0; -} - -static int opCPUID(uint32_t fetchdat) -{ - if (CPUID) - { - cpu_CPUID(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRDMSR(uint32_t fetchdat) -{ - if (cpu_hasMSR) - { - cpu_RDMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opWRMSR(uint32_t fetchdat) -{ - if (cpu_hasMSR) - { - cpu_WRMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - diff --git a/src - Cópia/cpu/x86_ops_mmx.h b/src - Cópia/cpu/x86_ops_mmx.h deleted file mode 100644 index 1af186d0b..000000000 --- a/src - Cópia/cpu/x86_ops_mmx.h +++ /dev/null @@ -1,48 +0,0 @@ -#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) -#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) -#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) -#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) - -#define MMX_GETSRC() \ - if (cpu_mod == 3) \ - { \ - src = cpu_state.MM[cpu_rm]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(2); \ - } - -#define MMX_ENTER() \ - if (!cpu_hasMMX) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 1; \ - } \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - x87_set_mmx() - -static int opEMMS(uint32_t fetchdat) -{ - if (!cpu_hasMMX) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if (cr0 & 4) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(100); /*Guess*/ - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_arith.h b/src - Cópia/cpu/x86_ops_mmx_arith.h deleted file mode 100644 index 302a44eaa..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_arith.h +++ /dev/null @@ -1,625 +0,0 @@ -static int opPADDB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; -} -static int opPADDB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; -} - -static int opPADDW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; -} -static int opPADDW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; -} - -static int opPADDD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; - - return 0; -} -static int opPADDD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; - - return 0; -} - -static int opPADDSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); - - return 0; -} -static int opPADDSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); - - return 0; -} - -static int opPADDUSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); - - return 0; -} -static int opPADDUSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); - - return 0; -} - -static int opPADDSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); - - return 0; -} -static int opPADDSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); - - return 0; -} - -static int opPADDUSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); - - return 0; -} -static int opPADDUSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); - - return 0; -} - -static int opPMADDWD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); - - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; -} -static int opPMADDWD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); - - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; -} - - -static int opPMULLW_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - 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] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; -} -static int opPMULLW_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - 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] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPMULHW_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(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]) >> 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]) >> 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]) >> 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]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - 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; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} -static int opPMULHW_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(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]) >> 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]) >> 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]) >> 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]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - 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; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPSUBB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} -static int opPSUBB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} - -static int opPSUBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} -static int opPSUBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} - -static int opPSUBD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} -static int opPSUBD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} - -static int opPSUBSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} -static int opPSUBSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} - -static int opPSUBUSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} -static int opPSUBUSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} - -static int opPSUBSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} -static int opPSUBSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} - -static int opPSUBUSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; -} -static int opPSUBUSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_cmp.h b/src - Cópia/cpu/x86_ops_mmx_cmp.h deleted file mode 100644 index eb401b83f..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_cmp.h +++ /dev/null @@ -1,205 +0,0 @@ -static int opPCMPEQB_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - - return 0; -} -static int opPCMPEQB_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - - return 0; -} - -static int opPCMPGTB_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - - return 0; -} -static int opPCMPGTB_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - - return 0; -} - -static int opPCMPEQW_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - - return 0; -} -static int opPCMPEQW_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - - return 0; -} - -static int opPCMPGTW_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - - return 0; -} -static int opPCMPGTW_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - - return 0; -} - -static int opPCMPEQD_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPCMPEQD_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - - return 0; -} - -static int opPCMPGTD_a16(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPCMPGTD_a32(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_logic.h b/src - Cópia/cpu/x86_ops_mmx_logic.h deleted file mode 100644 index be5132e85..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_logic.h +++ /dev/null @@ -1,91 +0,0 @@ -static int opPAND_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q &= src.q; - return 0; -} -static int opPAND_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q &= src.q; - return 0; -} - -static int opPANDN_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; -} -static int opPANDN_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; -} - -static int opPOR_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q |= src.q; - return 0; -} -static int opPOR_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q |= src.q; - return 0; -} - -static int opPXOR_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; -} -static int opPXOR_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_mov.h b/src - Cópia/cpu/x86_ops_mmx_mov.h deleted file mode 100644 index d96df747b..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_mov.h +++ /dev/null @@ -1,161 +0,0 @@ -static int opMOVD_l_mm_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; - - 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; - - CLOCK_CYCLES(2); - } - return 0; -} -static int opMOVD_l_mm_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; - - 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; - - CLOCK_CYCLES(2); - } - return 0; -} - -static int opMOVD_mm_l_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - CHECK_WRITE(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); - } - return 0; -} -static int opMOVD_mm_l_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - CHECK_WRITE(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); - } - return 0; -} - -static int opMOVQ_q_mm_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; - - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; -} -static int opMOVQ_q_mm_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; - - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opMOVQ_mm_q_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - CHECK_WRITE(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); - } - return 0; -} -static int opMOVQ_mm_q_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - CHECK_WRITE(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); - } - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_pack.h b/src - Cópia/cpu/x86_ops_mmx_pack.h deleted file mode 100644 index 50b813cb3..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_pack.h +++ /dev/null @@ -1,324 +0,0 @@ -static int opPUNPCKLDQ_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; - - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; - - CLOCK_CYCLES(2); - } - return 0; -} -static int opPUNPCKLDQ_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; - - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; - - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPUNPCKHDQ_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; - - return 0; -} -static int opPUNPCKHDQ_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; - - return 0; -} - -static int opPUNPCKLBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - - return 0; -} -static int opPUNPCKLBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - - return 0; -} - -static int opPUNPCKHBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; - - return 0; -} -static int opPUNPCKHBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; - - return 0; -} - -static int opPUNPCKLWD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - - return 0; -} -static int opPUNPCKLWD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - - return 0; -} - -static int opPUNPCKHWD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; - - return 0; -} -static int opPUNPCKHWD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; - - return 0; -} - -static int opPACKSSWB_a16(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - - return 0; -} -static int opPACKSSWB_a32(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - - return 0; -} - -static int opPACKUSWB_a16(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - - return 0; -} -static int opPACKUSWB_a32(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - - return 0; -} - -static int opPACKSSDW_a16(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - - return 0; -} -static int opPACKSSDW_a32(uint32_t fetchdat) -{ - MMX_REG src, dst; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mmx_shift.h b/src - Cópia/cpu/x86_ops_mmx_shift.h deleted file mode 100644 index 429347598..000000000 --- a/src - Cópia/cpu/x86_ops_mmx_shift.h +++ /dev/null @@ -1,452 +0,0 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) \ - { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ - CLOCK_CYCLES(2); \ - } - -static int opPSxxW_imm(uint32_t fetchdat) -{ - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; - - cpu_state.pc += 2; - MMX_ENTER(); - - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; - } - break; - case 0x20: /*PSRAW*/ - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; - } - break; - default: - pclog("Bad PSxxW (0F 71) instruction %02X\n", op); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} -static int opPSLLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} - -static int opPSRLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} -static int opPSRLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} - -static int opPSRAW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; -} -static int opPSRAW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; -} - -static int opPSxxD_imm(uint32_t fetchdat) -{ - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; - - cpu_state.pc += 2; - MMX_ENTER(); - - switch (op) - { - case 0x10: /*PSRLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; - } - break; - case 0x20: /*PSRAD*/ - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; - break; - case 0x30: /*PSLLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; - } - break; - default: - pclog("Bad PSxxD (0F 72) instruction %02X\n", op); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLD_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } - - return 0; -} -static int opPSLLD_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } - - return 0; -} - -static int opPSRLD_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } - - return 0; -} -static int opPSRLD_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } - - return 0; -} - -static int opPSRAD_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - shift = 31; - - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; -} -static int opPSRAD_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) - shift = 31; - - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; -} - -static int opPSxxQ_imm(uint32_t fetchdat) -{ - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; - - cpu_state.pc += 2; - MMX_ENTER(); - - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; - break; - case 0x20: /*PSRAW*/ - if (shift > 63) - shift = 63; - cpu_state.MM[reg].sq >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; - break; - default: - pclog("Bad PSxxQ (0F 73) instruction %02X\n", op); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLQ_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; - - return 0; -} -static int opPSLLQ_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; - - return 0; -} - -static int opPSRLQ_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; - - return 0; -} -static int opPSRLQ_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; - - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mov.h b/src - Cópia/cpu/x86_ops_mov.h deleted file mode 100644 index a8ed5d819..000000000 --- a/src - Cópia/cpu/x86_ops_mov.h +++ /dev/null @@ -1,757 +0,0 @@ -static int opMOV_AL_imm(uint32_t fetchdat) -{ - AL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_AH_imm(uint32_t fetchdat) -{ - AH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_BL_imm(uint32_t fetchdat) -{ - BL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_BH_imm(uint32_t fetchdat) -{ - BH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_CL_imm(uint32_t fetchdat) -{ - CL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_CH_imm(uint32_t fetchdat) -{ - CH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_DL_imm(uint32_t fetchdat) -{ - DL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_DH_imm(uint32_t fetchdat) -{ - DH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} - -static int opMOV_AX_imm(uint32_t fetchdat) -{ - AX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_BX_imm(uint32_t fetchdat) -{ - BX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_CX_imm(uint32_t fetchdat) -{ - CX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_DX_imm(uint32_t fetchdat) -{ - DX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_SI_imm(uint32_t fetchdat) -{ - SI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_DI_imm(uint32_t fetchdat) -{ - DI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_BP_imm(uint32_t fetchdat) -{ - BP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_SP_imm(uint32_t fetchdat) -{ - SP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} - -static int opMOV_EAX_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EAX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_EBX_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_ECX_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ECX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_EDX_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_ESI_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_EDI_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_EBP_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} -static int opMOV_ESP_imm(uint32_t fetchdat) -{ - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} - -static int opMOV_b_imm_a16(uint32_t fetchdat) -{ - uint8_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - seteab(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; -} -static int opMOV_b_imm_a32(uint32_t fetchdat) -{ - uint8_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = getbyte(); if (cpu_state.abrt) return 1; - seteab(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_w_imm_a16(uint32_t fetchdat) -{ - uint16_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; -} -static int opMOV_w_imm_a32(uint32_t fetchdat) -{ - uint16_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; -} -static int opMOV_l_imm_a16(uint32_t fetchdat) -{ - uint32_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); - return cpu_state.abrt; -} -static int opMOV_l_imm_a32(uint32_t fetchdat) -{ - uint32_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); - return cpu_state.abrt; -} - - -static int opMOV_AL_a16(uint32_t fetchdat) -{ - uint8_t temp; - uint16_t addr = getwordf(); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AL_a32(uint32_t fetchdat) -{ - uint8_t temp; - uint32_t addr = getlong(); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_AX_a16(uint32_t fetchdat) -{ - uint16_t temp; - uint16_t addr = getwordf(); - CHECK_READ(cpu_state.ea_seg, addr, addr + 1); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AX_a32(uint32_t fetchdat) -{ - uint16_t temp; - uint32_t addr = getlong(); - CHECK_READ(cpu_state.ea_seg, addr, addr + 1); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_EAX_a16(uint32_t fetchdat) -{ - uint32_t temp; - uint16_t addr = getwordf(); - CHECK_READ(cpu_state.ea_seg, addr, addr + 3); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0); - return 0; -} -static int opMOV_EAX_a32(uint32_t fetchdat) -{ - uint32_t temp; - uint32_t addr = getlong(); - CHECK_READ(cpu_state.ea_seg, addr, addr + 3); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1); - return 0; -} - -static int opMOV_a16_AL(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AL(uint32_t fetchdat) -{ - uint32_t addr = getlong(); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_AX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_EAX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} -static int opMOV_a32_EAX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); - return cpu_state.abrt; -} - - -static int opLEA_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - /* ILLEGAL_ON(cpu_mod == 3); */ - cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - /* ILLEGAL_ON(cpu_mod == 3); */ - cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opLEA_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - /* ILLEGAL_ON(cpu_mod == 3); */ - cpu_state.regs[cpu_reg].l = ((cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr) & 0xffff; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - /* ILLEGAL_ON(cpu_mod == 3); */ - cpu_state.regs[cpu_reg].l = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - - - -static int opXLAT_a16(uint32_t fetchdat) -{ - uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp; - cpu_state.last_ea = addr; - temp = readmemb(cpu_state.ea_seg->base, addr); - if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opXLAT_a32(uint32_t fetchdat) -{ - uint32_t addr = EBX + AL; - uint8_t temp; - cpu_state.last_ea = addr; - temp = readmemb(cpu_state.ea_seg->base, addr); - if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opMOV_b_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_b_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); - } - return cpu_state.abrt; -} - -static int opMOV_r_b_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint8_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_b_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint8_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint16_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint16_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint32_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 0); - } - return 0; -} -static int opMOV_r_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint32_t temp; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 1); - } - return 0; -} - -#define opCMOV(condition) \ - static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } - -opCMOV(O) -opCMOV(NO) -opCMOV(B) -opCMOV(NB) -opCMOV(E) -opCMOV(NE) -opCMOV(BE) -opCMOV(NBE) -opCMOV(S) -opCMOV(NS) -opCMOV(P) -opCMOV(NP) -opCMOV(L) -opCMOV(NL) -opCMOV(LE) -opCMOV(NLE) diff --git a/src - Cópia/cpu/x86_ops_mov_ctrl.h b/src - Cópia/cpu/x86_ops_mov_ctrl.h deleted file mode 100644 index 3a522a652..000000000 --- a/src - Cópia/cpu/x86_ops_mov_ctrl.h +++ /dev/null @@ -1,304 +0,0 @@ -static int opMOV_r_CRx_a16(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from CRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_hasCR4) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - pclog("Bad read of CR%i %i\n",rmdat&7,cpu_reg); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_CRx_a32(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from CRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_hasCR4) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - pclog("Bad read of CR%i %i\n",rmdat&7,cpu_reg); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_r_DRx_a16(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from DRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_DRx_a32(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from DRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_CRx_r_a16(uint32_t fetchdat) -{ - uint32_t old_cr0 = cr0; - - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load CRx\n"); - x86gpf(NULL,0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (is486 && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; - break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; - flushmmucache(); - break; - case 4: - if (cpu_hasCR4) - { - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } - - default: - pclog("Bad load CR%i\n", cpu_reg); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_CRx_r_a32(uint32_t fetchdat) -{ - uint32_t old_cr0 = cr0; - - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load CRx\n"); - x86gpf(NULL,0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (is486 && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; - break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; - flushmmucache(); - break; - case 4: - if (cpu_hasCR4) - { - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } - - default: - pclog("Bad load CR%i\n", cpu_reg); - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_DRx_r_a16(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load DRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_DRx_r_a32(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load DRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_r_TRx_a16(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from TRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = 0; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_TRx_a32(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load from TRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = 0; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_TRx_r_a16(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load TRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_TRx_r_a32(uint32_t fetchdat) -{ - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) - { - pclog("Can't load TRx\n"); - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - diff --git a/src - Cópia/cpu/x86_ops_mov_seg.h b/src - Cópia/cpu/x86_ops_mov_seg.h deleted file mode 100644 index 1e2f654b1..000000000 --- a/src - Cópia/cpu/x86_ops_mov_seg.h +++ /dev/null @@ -1,412 +0,0 @@ -static int opMOV_w_seg_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - seteaw(ES); - break; - case 0x08: /*CS*/ - seteaw(CS); - break; - case 0x18: /*DS*/ - seteaw(DS); - break; - case 0x10: /*SS*/ - seteaw(SS); - break; - case 0x20: /*FS*/ - seteaw(FS); - break; - case 0x28: /*GS*/ - seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_w_seg_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - seteaw(ES); - break; - case 0x08: /*CS*/ - seteaw(CS); - break; - case 0x18: /*DS*/ - seteaw(DS); - break; - case 0x10: /*SS*/ - seteaw(SS); - break; - case 0x20: /*FS*/ - seteaw(FS); - break; - case 0x28: /*GS*/ - seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_l_seg_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_l_seg_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_seg_w_a16(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_16(fetchdat); - - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &_gs); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_seg_w_a32(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_32(fetchdat); - - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &_gs); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - - -static int opLDS_w_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 0; -} -static int opLDS_w_a32(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 0; -} -static int opLDS_l_a16(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); - return 0; -} -static int opLDS_l_a32(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); - return 0; -} - -static int opLSS_w_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 1; -} -static int opLSS_w_a32(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 1; -} -static int opLSS_l_a16(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 1; -} -static int opLSS_l_a32(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 1; -} - -#define opLsel(name, sel) \ - static int opL ## name ## _w_a16(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_16(fetchdat); \ - ILLEGAL_ON(cpu_mod == 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _w_a32(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_32(fetchdat); \ - ILLEGAL_ON(cpu_mod == 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a16(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_16(fetchdat); \ - ILLEGAL_ON(cpu_mod == 3); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a32(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_32(fetchdat); \ - ILLEGAL_ON(cpu_mod == 3); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \ - return 0; \ - } - -opLsel(ES, _es) -opLsel(FS, _fs) -opLsel(GS, _gs) diff --git a/src - Cópia/cpu/x86_ops_movx.h b/src - Cópia/cpu/x86_ops_movx.h deleted file mode 100644 index 2175a63c3..000000000 --- a/src - Cópia/cpu/x86_ops_movx.h +++ /dev/null @@ -1,181 +0,0 @@ -static int opMOVZX_w_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVZX_w_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opMOVZX_l_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVZX_l_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opMOVZX_w_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVZX_w_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opMOVZX_l_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVZX_l_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} - -static int opMOVSX_w_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVSX_w_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opMOVSX_l_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVSX_l_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} -static int opMOVSX_l_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; -} -static int opMOVSX_l_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; - - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_msr.h b/src - Cópia/cpu/x86_ops_msr.h deleted file mode 100644 index a73316745..000000000 --- a/src - Cópia/cpu/x86_ops_msr.h +++ /dev/null @@ -1,30 +0,0 @@ -static int opRDTSC(uint32_t fetchdat) -{ - if (!cpu_hasrdtsc) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if ((cr4 & CR4_TSD) && CPL) - { - x86gpf("RDTSC when TSD set and CPL != 0", 0); - return 1; - } - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - CLOCK_CYCLES(1); - return 0; -} - -static int opRDPMC(uint32_t fetchdat) -{ - if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) - { - x86gpf("RDPMC not allowed", 0); - return 1; - } - EAX = EDX = 0; - CLOCK_CYCLES(1); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_mul.h b/src - Cópia/cpu/x86_ops_mul.h deleted file mode 100644 index 98cf254cc..000000000 --- a/src - Cópia/cpu/x86_ops_mul.h +++ /dev/null @@ -1,234 +0,0 @@ -static int opIMUL_w_iw_a16(uint32_t fetchdat) -{ - int32_t templ; - int16_t tempw, tempw2; - - fetch_ea_16(fetchdat); - - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; - - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; - - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 0); - return 0; -} -static int opIMUL_w_iw_a32(uint32_t fetchdat) -{ - int32_t templ; - int16_t tempw, tempw2; - - fetch_ea_32(fetchdat); - - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; - - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; - - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 1); - return 0; -} - -static int opIMUL_l_il_a16(uint32_t fetchdat) -{ - int64_t temp64; - int32_t templ, templ2; - - fetch_ea_16(fetchdat); - - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; - - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 0); - return 0; -} -static int opIMUL_l_il_a32(uint32_t fetchdat) -{ - int64_t temp64; - int32_t templ, templ2; - - fetch_ea_32(fetchdat); - - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; - - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 1); - return 0; -} - -static int opIMUL_w_ib_a16(uint32_t fetchdat) -{ - int32_t templ; - int16_t tempw, tempw2; - - fetch_ea_16(fetchdat); - - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; - - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; - - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 0); - return 0; -} -static int opIMUL_w_ib_a32(uint32_t fetchdat) -{ - int32_t templ; - int16_t tempw, tempw2; - - fetch_ea_32(fetchdat); - - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; - - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; - - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 1); - return 0; -} - -static int opIMUL_l_ib_a16(uint32_t fetchdat) -{ - int64_t temp64; - int32_t templ, templ2; - - fetch_ea_16(fetchdat); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; - - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 0); - return 0; -} -static int opIMUL_l_ib_a32(uint32_t fetchdat) -{ - int64_t temp64; - int32_t templ, templ2; - - fetch_ea_32(fetchdat); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; - - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 1); - return 0; -} - - - -static int opIMUL_w_w_a16(uint32_t fetchdat) -{ - int32_t templ; - - fetch_ea_16(fetchdat); - 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; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0); - return 0; -} -static int opIMUL_w_w_a32(uint32_t fetchdat) -{ - int32_t templ; - - fetch_ea_32(fetchdat); - 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; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1); - return 0; -} - -static int opIMUL_l_l_a16(uint32_t fetchdat) -{ - int64_t temp64; - - fetch_ea_16(fetchdat); - 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; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0); - return 0; -} -static int opIMUL_l_l_a32(uint32_t fetchdat) -{ - int64_t temp64; - - fetch_ea_32(fetchdat); - 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; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); - - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1); - return 0; -} - diff --git a/src - Cópia/cpu/x86_ops_pmode.h b/src - Cópia/cpu/x86_ops_pmode.h deleted file mode 100644 index 46e324322..000000000 --- a/src - Cópia/cpu/x86_ops_pmode.h +++ /dev/null @@ -1,439 +0,0 @@ -static int opARPL_a16(uint32_t fetchdat) -{ - uint16_t temp_seg; - - NOTRM - fetch_ea_16(fetchdat); - /* pclog("ARPL_a16\n"); */ - temp_seg = geteaw(); if (cpu_state.abrt) return 1; - - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - flags |= Z_FLAG; - } - else - flags &= ~Z_FLAG; - - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0); - return 0; -} -static int opARPL_a32(uint32_t fetchdat) -{ - uint16_t temp_seg; - - NOTRM - fetch_ea_32(fetchdat); - /* pclog("ARPL_a32\n"); */ - temp_seg = geteaw(); if (cpu_state.abrt) return 1; - - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - flags |= Z_FLAG; - } - else - flags &= ~Z_FLAG; - - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1); - return 0; -} - -#define opLAR(name, fetch_ea, is32, ea32) \ - static int opLAR_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - \ - flags_rebuild(); \ - if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - flags &= ~Z_FLAG; \ - if ((desc & 0x1f00) == 0x000) valid = 0; \ - if ((desc & 0x1f00) == 0x800) valid = 0; \ - if ((desc & 0x1f00) == 0xa00) valid = 0; \ - if ((desc & 0x1f00) == 0xd00) valid = 0; \ - if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int dpl = (desc >> 13) & 3; \ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(11); \ - PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \ - return cpu_state.abrt; \ - } - -opLAR(w_a16, fetch_ea_16, 0, 0) -opLAR(w_a32, fetch_ea_32, 0, 1) -opLAR(l_a16, fetch_ea_16, 1, 0) -opLAR(l_a32, fetch_ea_32, 1, 1) - -#define opLSL(name, fetch_ea, is32, ea32) \ - static int opLSL_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - flags &= ~Z_FLAG; \ - if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ - if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ - if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \ - if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int rpl = (desc >> 13) & 3; \ - if (rpl < CPL || rpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - { \ - cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ - if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \ - { \ - cpu_state.regs[cpu_reg].l <<= 12; \ - cpu_state.regs[cpu_reg].l |= 0xFFF; \ - } \ - } \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(10); \ - PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \ - return cpu_state.abrt; \ - } - -opLSL(w_a16, fetch_ea_16, 0, 0) -opLSL(w_a32, fetch_ea_32, 0, 1) -opLSL(l_a16, fetch_ea_16, 1, 0) -opLSL(l_a32, fetch_ea_32, 1, 1) - - -static int op0F00_common(uint32_t fetchdat, int ea32) -{ - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access; - - /* pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ - switch (rmdat & 0x38) - { - case 0x00: /*SLDT*/ - seteaw(ldt.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x08: /*STR*/ - seteaw(tr.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x10: /*LLDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) - { - pclog("Invalid LLDT!\n"); - x86gpf(NULL,0); - return 1; - } - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - ldt.limit = limit; - ldt.access = access; - if (granularity) - { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = base; - ldt.seg = sel; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x18: /*LTR*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) - { - pclog("Invalid LTR!\n"); - x86gpf(NULL,0); - break; - } - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - access |= 2; - writememb(0, addr + 5, access); - if (cpu_state.abrt) return 1; - tr.seg = sel; - tr.limit = limit; - tr.access = access; - if (granularity) - { - tr.limit <<= 12; - tr.limit |= 0xFFF; - } - tr.base = base; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x20: /*VERR*/ - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; - if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ - { - dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - } - if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ - if (valid) flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; - case 0x28: /*VERW*/ - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; - dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - if (desc & 0x0800) valid = 0; /*Code*/ - if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ - if (valid) flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; - - default: - pclog("Bad 0F 00 opcode %02X\n", rmdat & 0x38); - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; -} - -static int op0F00_a16(uint32_t fetchdat) -{ - NOTRM - - fetch_ea_16(fetchdat); - - return op0F00_common(fetchdat, 0); -} -static int op0F00_a32(uint32_t fetchdat) -{ - NOTRM - - fetch_ea_32(fetchdat); - - return op0F00_common(fetchdat, 1); -} - -static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) -{ - uint32_t base; - uint16_t limit, tempw; - /* pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ - switch (rmdat & 0x38) - { - case 0x00: /*SGDT*/ - seteaw(gdt.limit); - base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); - break; - case 0x08: /*SIDT*/ - seteaw(idt.limit); - base = idt.base; - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); - break; - case 0x10: /*LGDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) - { - pclog("Invalid LGDT!\n"); - x86gpf(NULL,0); - break; - } - /* pclog("LGDT %08X:%08X\n", easeg, eaaddr); */ - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* pclog(" %08X %04X\n", base, limit); */ - gdt.limit = limit; - gdt.base = base; - if (!is32) gdt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); - break; - case 0x18: /*LIDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) - { - pclog("Invalid LIDT!\n"); - x86gpf(NULL,0); - break; - } - /* pclog("LIDT %08X:%08X\n", easeg, eaaddr); */ - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* pclog(" %08X %04X\n", base, limit); */ - idt.limit = limit; - idt.base = base; - if (!is32) idt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); - break; - - case 0x20: /*SMSW*/ - if (is486) seteaw(msw); - else if (is386) seteaw(msw | 0xFF00); - else seteaw(msw | 0xFFF0); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x30: /*LMSW*/ - if ((CPL || eflags&VM_FLAG) && (msw&1)) - { - pclog("LMSW - ring not zero!\n"); - x86gpf(NULL, 0); - break; - } - tempw = geteaw(); if (cpu_state.abrt) return 1; - if (msw & 1) tempw |= 1; - if (is386) - { - tempw &= ~0x10; - tempw |= (msw & 0x10); - } - else tempw &= 0xF; - msw = tempw; - if (msw & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - - case 0x38: /*INVLPG*/ - if (is486) - { - if ((CPL || eflags&VM_FLAG) && (cr0&1)) - { - pclog("Invalid INVLPG!\n"); - x86gpf(NULL, 0); - break; - } - mmu_invalidate(ds + cpu_state.eaaddr); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); - break; - } - - default: - pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38); - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; -} - -static int op0F01_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - - return op0F01_common(fetchdat, 0, 0, 0); -} -static int op0F01_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - - return op0F01_common(fetchdat, 0, 0, 1); -} -static int op0F01_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - - return op0F01_common(fetchdat, 1, 0, 0); -} -static int op0F01_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - - return op0F01_common(fetchdat, 1, 0, 1); -} - -static int op0F01_286(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - - return op0F01_common(fetchdat, 0, 1, 0); -} diff --git a/src - Cópia/cpu/x86_ops_prefix.h b/src - Cópia/cpu/x86_ops_prefix.h deleted file mode 100644 index 8265c19f1..000000000 --- a/src - Cópia/cpu/x86_ops_prefix.h +++ /dev/null @@ -1,161 +0,0 @@ -#define op_seg(name, seg, opcode_table, normal_opcode_table) \ -static int op ## name ## _w_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[fetchdat & 0xff]) \ - return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ - return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x100]) \ - return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ - return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _w_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x200]) \ - return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ - return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x300]) \ - return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ - return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ -} - -op_seg(CS, _cs, x86_opcodes, x86_opcodes) -op_seg(DS, _ds, x86_opcodes, x86_opcodes) -op_seg(ES, _es, x86_opcodes, x86_opcodes) -op_seg(FS, _fs, x86_opcodes, x86_opcodes) -op_seg(GS, _gs, x86_opcodes, x86_opcodes) -op_seg(SS, _ss, x86_opcodes, x86_opcodes) - -op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes) -op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes) -op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes) -op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes) -op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes) -op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes) - -op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes) -op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes) -op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes) -op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes) -op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes) -op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes) - -static int op_66(uint32_t fetchdat) /*Data size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} -static int op_67(uint32_t fetchdat) /*Address size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} - -static int op_66_REPE(uint32_t fetchdat) /*Data size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} -static int op_67_REPE(uint32_t fetchdat) /*Address size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} -static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} -static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/ -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} diff --git a/src - Cópia/cpu/x86_ops_rep.h b/src - Cópia/cpu/x86_ops_rep.h deleted file mode 100644 index 065695706..000000000 --- a/src - Cópia/cpu/x86_ops_rep.h +++ /dev/null @@ -1,643 +0,0 @@ -extern int trap; - -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - check_io_perm(DX); \ - temp = inb(DX); \ - writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - temp = inw(DX); \ - writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - temp = inl(DX); \ - writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - ins++; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - ins++; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - ins++; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - while (CNT_REG > 0) \ - { \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ - uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ - uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ - uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - ins++; \ - if (cycles < cycles_end) \ - break; \ - } \ - ins--; \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} - -REP_OPS(a16, CX, SI, DI) -REP_OPS(a32, ECX, ESI, EDI) -REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) -REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) - -static int opREPNE(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} -static int opREPE(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; - - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} diff --git a/src - Cópia/cpu/x86_ops_ret.h b/src - Cópia/cpu/x86_ops_ret.h deleted file mode 100644 index 95872588c..000000000 --- a/src - Cópia/cpu/x86_ops_ret.h +++ /dev/null @@ -1,261 +0,0 @@ -#define RETF_a16(stack_offset) \ - if ((msw&1) && !(eflags&VM_FLAG)) \ - { \ - pmoderetf(0, stack_offset); \ - return 1; \ - } \ - oxpc = cpu_state.pc; \ - if (stack32) \ - { \ - cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ - } \ - else \ - { \ - cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ - } \ - 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) && !(eflags&VM_FLAG)) \ - { \ - pmoderetf(1, stack_offset); \ - return 1; \ - } \ - oxpc = cpu_state.pc; \ - if (stack32) \ - { \ - cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ - } \ - else \ - { \ - cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 8 + stack_offset; \ - else SP += 8 + stack_offset; \ - cycles -= timing_retf_rm; - -static int opRETF_a16(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - CPU_BLOCK_END(); - RETF_a16(0); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opRETF_a32(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - CPU_BLOCK_END(); - RETF_a32(0); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; -} - -static int opRETF_a16_imm(uint32_t fetchdat) -{ - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); - - CPU_BLOCK_END(); - RETF_a16(offset); - - PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; -} -static int opRETF_a32_imm(uint32_t fetchdat) -{ - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); - - CPU_BLOCK_END(); - RETF_a32(offset); - - PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; -} - -static int opIRET_286(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - oxpc = cpu_state.pc; - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - flags = (flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - flags = (flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRET(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t new_pc, new_cs, new_flags; - - new_pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - new_flags = readmemw(ss, ((SP + 4) & 0xffff)); - if (cpu_state.abrt) - return 1; - - if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG))) - { - x86gpf(NULL, 0); - return 1; - } - SP += 6; - if (new_flags & I_FLAG) - eflags |= VIF_FLAG; - else - eflags &= ~VIF_FLAG; - flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); - cpu_state.pc = new_pc; - - cycles -= timing_iret_rm; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - { - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - oxpc = cpu_state.pc; - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRETD(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (msw & 1) - { - optype = IRET; - pmodeiret(1); - optype = 0; - } - else - { - uint16_t new_cs; - oxpc = cpu_state.pc; - if (stack32) - { - cpu_state.pc = readmeml(ss, ESP); - new_cs = readmemw(ss, ESP + 4); - flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - eflags = readmemw(ss, ESP + 10); - ESP += 12; - } - else - { - cpu_state.pc = readmeml(ss, SP); - new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; - eflags = readmemw(ss, (SP + 10) & 0xffff); - SP += 12; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - diff --git a/src - Cópia/cpu/x86_ops_set.h b/src - Cópia/cpu/x86_ops_set.h deleted file mode 100644 index 0094b85d4..000000000 --- a/src - Cópia/cpu/x86_ops_set.h +++ /dev/null @@ -1,33 +0,0 @@ -#define opSET(condition) \ - static int opSET ## condition ## _a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } \ - \ - static int opSET ## condition ## _a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } - -opSET(O) -opSET(NO) -opSET(B) -opSET(NB) -opSET(E) -opSET(NE) -opSET(BE) -opSET(NBE) -opSET(S) -opSET(NS) -opSET(P) -opSET(NP) -opSET(L) -opSET(NL) -opSET(LE) -opSET(NLE) diff --git a/src - Cópia/cpu/x86_ops_shift.h b/src - Cópia/cpu/x86_ops_shift.h deleted file mode 100644 index 5f0f57631..000000000 --- a/src - Cópia/cpu/x86_ops_shift.h +++ /dev/null @@ -1,608 +0,0 @@ -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ - } - -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x8000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x8000; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ - } - -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80000000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x08: /*ROR l, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80000000; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ - } - -static int opC0_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opC0_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opC1_w_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opC1_w_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opC1_l_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opC1_l_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - -static int opD0_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opD0_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opD1_w_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opD1_w_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opD1_l_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opD1_l_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - -static int opD2_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opD2_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opD3_w_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opD3_w_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opD3_l_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opD3_l_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - - -#define SHLD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ - if (count <= 16) tempw = templ >> (16 - count); \ - else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - } - -#define SHLD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ - templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - } - - -#define SHRD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (tempw >> (count - 1)) & 1; \ - templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ - tempw = templ >> count; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - } - -#define SHRD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (templ >> (count - 1)) & 1; \ - templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - } - -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - count = getbyte() & 31; \ - operation() \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _CL_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - count = CL & 31; \ - operation() \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _i_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - count = getbyte() & 31; \ - operation() \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } \ - static int op ## operation ## _CL_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - count = CL & 31; \ - operation() \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } - -opSHxD(SHLD_w) -opSHxD(SHLD_l) -opSHxD(SHRD_w) -opSHxD(SHRD_l) diff --git a/src - Cópia/cpu/x86_ops_stack.h b/src - Cópia/cpu/x86_ops_stack.h deleted file mode 100644 index 621f602b3..000000000 --- a/src - Cópia/cpu/x86_ops_stack.h +++ /dev/null @@ -1,517 +0,0 @@ -#define PUSH_W_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_W(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } - -#define PUSH_L_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_L(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } - -#define POP_W_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_W(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \ - return cpu_state.abrt; \ - } - -#define POP_L_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_L(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \ - return cpu_state.abrt; \ - } - -PUSH_W_OP(AX) -PUSH_W_OP(BX) -PUSH_W_OP(CX) -PUSH_W_OP(DX) -PUSH_W_OP(SI) -PUSH_W_OP(DI) -PUSH_W_OP(BP) -PUSH_W_OP(SP) - -PUSH_L_OP(EAX) -PUSH_L_OP(EBX) -PUSH_L_OP(ECX) -PUSH_L_OP(EDX) -PUSH_L_OP(ESI) -PUSH_L_OP(EDI) -PUSH_L_OP(EBP) -PUSH_L_OP(ESP) - -POP_W_OP(AX) -POP_W_OP(BX) -POP_W_OP(CX) -POP_W_OP(DX) -POP_W_OP(SI) -POP_W_OP(DI) -POP_W_OP(BP) -POP_W_OP(SP) - -POP_L_OP(EAX) -POP_L_OP(EBX) -POP_L_OP(ECX) -POP_L_OP(EDX) -POP_L_OP(ESI) -POP_L_OP(EDI) -POP_L_OP(EBP) -POP_L_OP(ESP) - - -static int opPUSHA_w(uint32_t fetchdat) -{ - if (stack32) - { - writememw(ss, ESP - 2, AX); - writememw(ss, ESP - 4, CX); - writememw(ss, ESP - 6, DX); - writememw(ss, ESP - 8, BX); - writememw(ss, ESP - 10, SP); - writememw(ss, ESP - 12, BP); - writememw(ss, ESP - 14, SI); - writememw(ss, ESP - 16, DI); - if (!cpu_state.abrt) ESP -= 16; - } - else - { - writememw(ss, ((SP - 2) & 0xFFFF), AX); - writememw(ss, ((SP - 4) & 0xFFFF), CX); - writememw(ss, ((SP - 6) & 0xFFFF), DX); - writememw(ss, ((SP - 8) & 0xFFFF), BX); - writememw(ss, ((SP - 10) & 0xFFFF), SP); - writememw(ss, ((SP - 12) & 0xFFFF), BP); - writememw(ss, ((SP - 14) & 0xFFFF), SI); - writememw(ss, ((SP - 16) & 0xFFFF), DI); - if (!cpu_state.abrt) SP -= 16; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0); - return cpu_state.abrt; -} -static int opPUSHA_l(uint32_t fetchdat) -{ - if (stack32) - { - writememl(ss, ESP - 4, EAX); - writememl(ss, ESP - 8, ECX); - writememl(ss, ESP - 12, EDX); - writememl(ss, ESP - 16, EBX); - writememl(ss, ESP - 20, ESP); - writememl(ss, ESP - 24, EBP); - writememl(ss, ESP - 28, ESI); - writememl(ss, ESP - 32, EDI); - if (!cpu_state.abrt) ESP -= 32; - } - else - { - writememl(ss, ((SP - 4) & 0xFFFF), EAX); - writememl(ss, ((SP - 8) & 0xFFFF), ECX); - writememl(ss, ((SP - 12) & 0xFFFF), EDX); - writememl(ss, ((SP - 16) & 0xFFFF), EBX); - writememl(ss, ((SP - 20) & 0xFFFF), ESP); - writememl(ss, ((SP - 24) & 0xFFFF), EBP); - writememl(ss, ((SP - 28) & 0xFFFF), ESI); - writememl(ss, ((SP - 32) & 0xFFFF), EDI); - if (!cpu_state.abrt) SP -= 32; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0); - return cpu_state.abrt; -} - -static int opPOPA_w(uint32_t fetchdat) -{ - if (stack32) - { - DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1; - ESP += 16; - } - else - { - DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 16; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0); - return 0; -} -static int opPOPA_l(uint32_t fetchdat) -{ - if (stack32) - { - EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; - ESP += 32; - } - else - { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 32; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 0,7,0,0, 0); - return 0; -} - -static int opPUSH_imm_w(uint32_t fetchdat) -{ - uint16_t val = getwordf(); - PUSH_W(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSH_imm_l(uint32_t fetchdat) -{ - uint32_t val = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} - -static int opPUSH_imm_bw(uint32_t fetchdat) -{ - uint16_t tempw = getbytef(); - - if (tempw & 0x80) tempw |= 0xFF00; - PUSH_W(tempw); - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSH_imm_bl(uint32_t fetchdat) -{ - uint32_t templ = getbytef(); - - if (templ & 0x80) templ |= 0xFFFFFF00; - PUSH_L(templ); - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} - -static int opPOPW_a16(uint32_t fetchdat) -{ - uint16_t temp; - - temp = POP_W(); if (cpu_state.abrt) return 1; - - fetch_ea_16(fetchdat); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } - - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); - return cpu_state.abrt; -} -static int opPOPW_a32(uint32_t fetchdat) -{ - uint16_t temp; - - temp = POP_W(); if (cpu_state.abrt) return 1; - - fetch_ea_32(fetchdat); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } - - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); - return cpu_state.abrt; -} - -static int opPOPL_a16(uint32_t fetchdat) -{ - uint32_t temp; - - temp = POP_L(); if (cpu_state.abrt) return 1; - - fetch_ea_16(fetchdat); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } - - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); - return cpu_state.abrt; -} -static int opPOPL_a32(uint32_t fetchdat) -{ - uint32_t temp; - - temp = POP_L(); if (cpu_state.abrt) return 1; - - fetch_ea_32(fetchdat); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } - - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); - return cpu_state.abrt; -} - - -static int opENTER_w(uint32_t fetchdat) -{ - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; - int reads = 0, writes = 1, instr_cycles = 0; - uint16_t tempw; - - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; - tempESP = ESP; - - PUSH_W(BP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; - - if (count > 0) - { - while (--count) - { - BP -= 2; - tempw = readmemw(ss, BP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_W(tempw); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); - reads++; writes++; instr_cycles += (is486) ? 3 : 4; - } - PUSH_W(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); - writes++; instr_cycles += (is486) ? 3 : 5; - } - BP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); - return 0; -} -static int opENTER_l(uint32_t fetchdat) -{ - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; - int reads = 0, writes = 1, instr_cycles = 0; - uint32_t templ; - - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; tempESP = ESP; - - PUSH_L(EBP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; - - if (count > 0) - { - while (--count) - { - EBP -= 4; - templ = readmeml(ss, EBP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_L(templ); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); - reads++; writes++; instr_cycles += (is486) ? 3 : 4; - } - PUSH_L(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); - writes++; instr_cycles += (is486) ? 3 : 5; - } - EBP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); - return 0; -} - - -static int opLEAVE_w(uint32_t fetchdat) -{ - uint32_t tempESP = ESP; - uint16_t temp; - - SP = BP; - temp = POP_W(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - BP = temp; - - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opLEAVE_l(uint32_t fetchdat) -{ - uint32_t tempESP = ESP; - uint32_t temp; - - ESP = EBP; - temp = POP_L(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - EBP = temp; - - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); - return 0; -} - - -#define PUSH_SEG_OPS(seg) \ - static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \ - { \ - PUSH_W(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ - { \ - PUSH_L(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } - -#define POP_SEG_OPS(seg, realseg) \ - static int opPOP_ ## seg ## _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, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPOP_ ## seg ## _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, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } - - -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, &_ds) -POP_SEG_OPS(ES, &_es) -POP_SEG_OPS(FS, &_fs) -POP_SEG_OPS(GS, &_gs) - - -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, &_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); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - - return 1; -} -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, &_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); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - - return 1; -} diff --git a/src - Cópia/cpu/x86_ops_string.h b/src - Cópia/cpu/x86_ops_string.h deleted file mode 100644 index 8c8ba6816..000000000 --- a/src - Cópia/cpu/x86_ops_string.h +++ /dev/null @@ -1,477 +0,0 @@ -static int opMOVSB_a16(uint32_t fetchdat) -{ - uint8_t 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 (flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opMOVSB_a32(uint32_t fetchdat) -{ - uint8_t 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 (flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opMOVSW_a16(uint32_t fetchdat) -{ - uint16_t 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 (flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opMOVSW_a32(uint32_t fetchdat) -{ - uint16_t 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 (flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opMOVSL_a16(uint32_t fetchdat) -{ - uint32_t 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 (flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); - return 0; -} -static int opMOVSL_a32(uint32_t fetchdat) -{ - uint32_t 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 (flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); - return 0; -} - - -static int opCMPSB_a16(uint32_t fetchdat) -{ - uint8_t src = readmemb(cpu_state.ea_seg->base, SI); - uint8_t dst = readmemb(es, DI); if (cpu_state.abrt) return 1; - setsub8(src, dst); - if (flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; -} -static int opCMPSB_a32(uint32_t fetchdat) -{ - uint8_t src = readmemb(cpu_state.ea_seg->base, ESI); - uint8_t dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; - setsub8(src, dst); - if (flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; -} - -static int opCMPSW_a16(uint32_t fetchdat) -{ - uint16_t src = readmemw(cpu_state.ea_seg->base, SI); - uint16_t dst = readmemw(es, DI); if (cpu_state.abrt) return 1; - setsub16(src, dst); - if (flags & D_FLAG) { 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; -} -static int opCMPSW_a32(uint32_t fetchdat) -{ - uint16_t src = readmemw(cpu_state.ea_seg->base, ESI); - uint16_t dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; - setsub16(src, dst); - if (flags & D_FLAG) { 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; -} - -static int opCMPSL_a16(uint32_t fetchdat) -{ - uint32_t src = readmeml(cpu_state.ea_seg->base, SI); - uint32_t dst = readmeml(es, DI); if (cpu_state.abrt) return 1; - setsub32(src, dst); - if (flags & D_FLAG) { 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; -} -static int opCMPSL_a32(uint32_t fetchdat) -{ - uint32_t src = readmeml(cpu_state.ea_seg->base, ESI); - uint32_t dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; - setsub32(src, dst); - if (flags & D_FLAG) { 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; -} - -static int opSTOSB_a16(uint32_t fetchdat) -{ - writememb(es, DI, AL); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) 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) -{ - writememb(es, EDI, AL); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; -} - -static int opSTOSW_a16(uint32_t fetchdat) -{ - writememw(es, DI, AX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) 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) -{ - writememw(es, EDI, AX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; -} - -static int opSTOSL_a16(uint32_t fetchdat) -{ - writememl(es, DI, EAX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) 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) -{ - writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); - return 0; -} - - -static int opLODSB_a16(uint32_t fetchdat) -{ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AL = temp; - if (flags & D_FLAG) SI--; - else SI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opLODSB_a32(uint32_t fetchdat) -{ - uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AL = temp; - if (flags & D_FLAG) ESI--; - else ESI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opLODSW_a16(uint32_t fetchdat) -{ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AX = temp; - if (flags & D_FLAG) SI -= 2; - else SI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opLODSW_a32(uint32_t fetchdat) -{ - uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AX = temp; - if (flags & D_FLAG) ESI -= 2; - else ESI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opLODSL_a16(uint32_t fetchdat) -{ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - EAX = temp; - if (flags & D_FLAG) SI -= 4; - else SI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - return 0; -} -static int opLODSL_a32(uint32_t fetchdat) -{ - uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - EAX = temp; - if (flags & D_FLAG) ESI -= 4; - else ESI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); - return 0; -} - - -static int opSCASB_a16(uint32_t fetchdat) -{ - uint8_t temp = readmemb(es, DI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opSCASB_a32(uint32_t fetchdat) -{ - uint8_t temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opSCASW_a16(uint32_t fetchdat) -{ - uint16_t temp = readmemw(es, DI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opSCASW_a32(uint32_t fetchdat) -{ - uint16_t temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opSCASL_a16(uint32_t fetchdat) -{ - uint32_t temp = readmeml(es, DI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); - return 0; -} -static int opSCASL_a32(uint32_t fetchdat) -{ - uint32_t temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); - return 0; -} - -static int opINSB_a16(uint32_t fetchdat) -{ - uint8_t temp; - check_io_perm(DX); - temp = inb(DX); - writememb(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opINSB_a32(uint32_t fetchdat) -{ - uint8_t temp; - check_io_perm(DX); - temp = inb(DX); - writememb(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opINSW_a16(uint32_t fetchdat) -{ - uint16_t temp; - check_io_perm(DX); - check_io_perm(DX + 1); - temp = inw(DX); - writememw(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opINSW_a32(uint32_t fetchdat) -{ - uint16_t temp; - check_io_perm(DX); - check_io_perm(DX + 1); - temp = inw(DX); - writememw(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opINSL_a16(uint32_t fetchdat) -{ - uint32_t temp; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - temp = inl(DX); - writememl(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); - return 0; -} -static int opINSL_a32(uint32_t fetchdat) -{ - uint32_t temp; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - temp = inl(DX); - writememl(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); - return 0; -} - -static int opOUTSB_a16(uint32_t fetchdat) -{ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (flags & D_FLAG) SI--; - else SI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opOUTSB_a32(uint32_t fetchdat) -{ - uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (flags & D_FLAG) ESI--; - else ESI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opOUTSW_a16(uint32_t fetchdat) -{ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (flags & D_FLAG) SI -= 2; - else SI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; -} -static int opOUTSW_a32(uint32_t fetchdat) -{ - uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (flags & D_FLAG) ESI -= 2; - else ESI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; -} - -static int opOUTSL_a16(uint32_t fetchdat) -{ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (flags & D_FLAG) SI -= 4; - else SI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); - return 0; -} -static int opOUTSL_a32(uint32_t fetchdat) -{ - uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (flags & D_FLAG) ESI -= 4; - else ESI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); - return 0; -} diff --git a/src - Cópia/cpu/x86_ops_xchg.h b/src - Cópia/cpu/x86_ops_xchg.h deleted file mode 100644 index 77191ae43..000000000 --- a/src - Cópia/cpu/x86_ops_xchg.h +++ /dev/null @@ -1,216 +0,0 @@ -static int opXCHG_b_a16(uint32_t fetchdat) -{ - uint8_t temp; - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; -} -static int opXCHG_b_a32(uint32_t fetchdat) -{ - uint8_t temp; - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; -} - -static int opXCHG_w_a16(uint32_t fetchdat) -{ - uint16_t temp; - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; -} -static int opXCHG_w_a32(uint32_t fetchdat) -{ - uint16_t temp; - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; -} - -static int opXCHG_l_a16(uint32_t fetchdat) -{ - uint32_t temp; - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; -} -static int opXCHG_l_a32(uint32_t fetchdat) -{ - uint32_t temp; - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; -} - - -static int opXCHG_AX_BX(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = BX; - BX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_CX(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = CX; - CX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_DX(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = DX; - DX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_SI(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = SI; - SI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_DI(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = DI; - DI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_BP(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = BP; - BP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_AX_SP(uint32_t fetchdat) -{ - uint16_t temp = AX; - AX = SP; - SP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opXCHG_EAX_EBX(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = EBX; - EBX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_ECX(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = ECX; - ECX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_EDX(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = EDX; - EDX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_ESI(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = ESI; - ESI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_EDI(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = EDI; - EDI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_EBP(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = EBP; - EBP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opXCHG_EAX_ESP(uint32_t fetchdat) -{ - uint32_t temp = EAX; - EAX = ESP; - ESP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - - -#define opBSWAP(reg) \ - static int opBSWAP_ ## reg(uint32_t fetchdat) \ - { \ - reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ - CLOCK_CYCLES(1); \ - PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } - -opBSWAP(EAX) -opBSWAP(EBX) -opBSWAP(ECX) -opBSWAP(EDX) -opBSWAP(ESI) -opBSWAP(EDI) -opBSWAP(EBP) -opBSWAP(ESP) diff --git a/src - Cópia/cpu/x86seg.c b/src - Cópia/cpu/x86seg.c deleted file mode 100644 index 3447a2628..000000000 --- a/src - Cópia/cpu/x86seg.c +++ /dev/null @@ -1,2555 +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. - * - * x86 CPU segment emulation. - * - * Version: @(#)x86seg.c 1.0.7 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../nvr.h" -#include "x86.h" -#include "386.h" -#include "386_common.h" - - -/*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ -#define CS_ACCESSED - -/*Controls whether the accessed bit in a descriptor is set when a data or stack - selector is loaded.*/ -#define SEL_ACCESSED -int stimes = 0; -int dtimes = 0; -int btimes = 0; - -uint32_t abrt_error; -int cgate16,cgate32; - -#define breaknullsegs 0 - -int intgatesize; - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); -void taskswitch386(uint16_t seg, uint16_t *segdat); - -int output; -void pmodeint(int num, int soft); -/*NOT PRESENT is INT 0B - GPF is INT 0D*/ - - -#ifdef ENABLE_X86SEG_LOG -int x86seg_do_log = ENABLE_X86SEG_LOG; -#endif - - -static void -x86seg_log(const char *fmt, ...) -{ -#ifdef ENABLE_X86SEG_LOG - va_list ap; - - if (x86seg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void x86abort(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - vfprintf(stdlog, format, ap); - va_end(ap); - fflush(stdlog); - nvr_save(); - dumpregs(1); - fflush(stdlog); - exit(-1); -} - -uint8_t opcode2; - -static void seg_reset(x86seg *s) -{ - s->access = (0 << 5) | 2 | 0x80; - s->limit = 0xFFFF; - s->limit_low = 0; - s->limit_high = 0xffff; - if(s == &_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->seg = AT ? 0xF000 : 0xFFFF; - } - else - { - s->base = 0; - s->seg = 0; - } - -} - -void x86seg_reset() -{ - seg_reset(&_cs); - seg_reset(&_ds); - seg_reset(&_es); - seg_reset(&_fs); - seg_reset(&_gs); - seg_reset(&_ss); -} - -void x86_doabrt(int x86_abrt) -{ - CS = oldcs; - cpu_state.pc = cpu_state.oldpc; - _cs.access = (oldcpl << 5) | 0x80; - - if (msw & 1) - pmodeint(x86_abrt, 0); - else - { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) - { - writememw(ss,ESP-2,flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - flags&=~I_FLAG; - flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - return; - } - - if (cpu_state.abrt || x86_was_reset) return; - - if (intgatesize == 16) - { - if (stack32) - { - writememw(ss, ESP-2, abrt_error); - ESP-=2; - } - else - { - writememw(ss, ((SP-2)&0xFFFF), abrt_error); - SP-=2; - } - } - else - { - if (stack32) - { - writememl(ss, ESP-4, abrt_error); - ESP-=4; - } - else - { - writememl(ss, ((SP-4)&0xFFFF), abrt_error); - SP-=4; - } - } -} -void x86gpf(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_GPF; - abrt_error = error; -} -void x86ss(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_SS; - abrt_error = error; -} -void x86ts(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_TS; - abrt_error = error; -} -void x86np(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_NP; - abrt_error = error; -} - - -static void set_stack32(int s) -{ - stack32 = s; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - else - cpu_cur_status &= ~CPU_STATUS_STACK32; -} - -static void set_use32(int u) -{ - if (u) - { - use32 = 0x300; - cpu_cur_status |= CPU_STATUS_USE32; - } - else - { - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - } -} - -void do_seg_load(x86seg *s, uint16_t *segdat) -{ - s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); - if (segdat[3] & 0x80) - s->limit = (s->limit << 12) | 0xFFF; - s->base = segdat[1] | ((segdat[2] & 0xFF) << 16); - if (is386) - s->base |= ((segdat[3] >> 8) << 24); - s->access = segdat[2] >> 8; - - if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static void do_seg_v86_init(x86seg *s) -{ - s->access = (3 << 5) | 2 | 0x80; - s->limit = 0xffff; - s->limit_low = 0; - s->limit_high = 0xffff; -} - -static void check_seg_valid(x86seg *s) -{ - int dpl = (s->access >> 5) & 3; - int valid = 1; - - if (s->seg & 4) - { - if ((s->seg & ~7) >= ldt.limit) - { - valid = 0; - } - } - else - { - if ((s->seg & ~7) >= gdt.limit) - { - valid = 0; - } - } - - switch (s->access & 0x1f) - { - case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1A: case 0x1B: /*Readable non-conforming code*/ - if ((s->seg & 3) > dpl || (CPL) > dpl) - { - valid = 0; - break; - } - break; - - case 0x1E: case 0x1F: /*Readable conforming code*/ - break; - - default: - valid = 0; - break; - } - - if (!valid) - loadseg(0, s); -} - -void loadseg(uint16_t seg, x86seg *s) -{ - uint16_t segdat[4]; - uint32_t addr; - int dpl; - - if (msw&1 && !(eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - if (s==&_ss) - { - x86ss(NULL,0); - return; - } - s->seg=0; - s->access = 0x80; - s->base=-1; - if (s == &_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf("loadseg(): Bigger than LDT limit",seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf("loadseg(): Bigger than GDT limit",seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - dpl=(segdat[2]>>13)&3; - if (s==&_ss) - { - if (!(seg&~3)) - { - x86gpf(NULL,seg&~3); - return; - } - if ((seg&3)!=CPL || dpl!=CPL) - { - x86gpf(NULL,seg&~3); - return; - } - switch ((segdat[2]>>8)&0x1F) - { - case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/ - break; - default: - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86ss(NULL,seg&~3); - return; - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); - } - else if (s!=&_cs) - { - x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - x86seg_log("Seg type %03X\n",segdat[2]&0x1F00); - switch ((segdat[2]>>8)&0x1F) - { - case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1A: case 0x1B: /*Readable non-conforming code*/ - if ((seg&3)>dpl || (CPL)>dpl) - { - x86gpf(NULL,seg&~3); - return; - } - break; - case 0x1E: case 0x1F: /*Readable conforming code*/ - break; - default: - x86gpf(NULL,seg&~3); - return; - } - } - - if (!(segdat[2] & 0x8000)) - { - x86np("Load data seg not present", seg & 0xfffc); - return; - } - s->seg = seg; - do_seg_load(s, segdat); - -#ifndef CS_ACCESSED - if (s != &_cs) - { -#endif -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif -#ifndef CS_ACCESSED - } -#endif - s->checked = 0; -#ifdef USE_DYNAREC - if (s == &_ds) - codegen_flat_ds = 0; - if (s == &_ss) - codegen_flat_ss = 0; -#endif - } - else - { - s->access = (3 << 5) | 2 | 0x80; - s->base = seg << 4; - s->seg = seg; - if (s == &_ss) - set_stack32(0); - s->checked = 1; -#ifdef USE_DYNAREC - if (s == &_ds) - codegen_flat_ds = 0; - if (s == &_ss) - codegen_flat_ss = 0; -#endif - } - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -#define DPL ((segdat[2]>>13)&3) -#define DPL2 ((segdat2[2]>>13)&3) -#define DPL3 ((segdat3[2]>>13)&3) - -void loadcs(uint16_t seg) -{ - uint16_t segdat[4]; - uint32_t addr; - x86seg_log("Load CS %04X\n",seg); - if (msw&1 && !(eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - if (segdat[2]&0x1000) /*Normal code segment*/ - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf(NULL,seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf("loadcs(): CPL != DPL",seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf("loadcs(): CPL < DPL",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); - CS=(seg&~3)|CPL; - do_seg_load(&_cs, segdat); - use32=(segdat[3]&0x40)?0x300:0; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - } - else /*System segment*/ - { - if (!(segdat[2]&0x8000)) - { - x86np("Load CS system seg not present\n", seg & 0xfffc); - return; - } - switch (segdat[2]&0xF00) - { - default: - x86gpf(NULL,seg&~3); - return; - } - } - } - else - { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; - CS=seg & 0xFFFF; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80; - else _cs.access=(0<<5) | 2 | 0x80; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - } -} - -void loadcsjmp(uint16_t seg, uint32_t oxpc) -{ - uint16_t segdat[4]; - uint32_t addr; - uint16_t type,seg2; - uint32_t newpc; - if (msw&1 && !(eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - x86seg_log("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); - if (segdat[2]&0x1000) /*Normal code segment*/ - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf("loadcsjmp(): segment PL > CPL",seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf("loadcsjmp(): CPL != DPL",seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf("loadcsjmp(): CPL < DPL",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP not present\n", seg & 0xfffc); - return; - } - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - CS = (seg & ~3) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - cycles -= timing_jmp_pm; - } - else /*System segment*/ - { - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP system selector not present\n", seg & 0xfffc); - return; - } - type=segdat[2]&0xF00; - newpc=segdat[0]; - if (type&0x800) newpc|=segdat[3]<<16; - switch (type) - { - case 0x400: /*Call gate*/ - case 0xC00: - cgate32=(type&0x800); - cgate16=!cgate32; - oldcs=CS; - cpu_state.oldpc = cpu_state.pc; - if ((DPL < CPL) || (DPL < (seg&3))) - { - x86gpf(NULL,seg&~3); - return; - } - if (DPL < CPL) - { - x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3); - return; - } - if ((DPL < (seg&3))) - { - x86gpf("loadcsjmp(): ex (DPL < (seg&3))",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP call gate not present\n", seg & 0xfffc); - return; - } - seg2=segdat[1]; - - if (!(seg2&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg2&~7; - if (seg2&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - - if (DPL > CPL) - { - x86gpf("loadcsjmp(): ex DPL > CPL",seg2&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP from call gate not present\n", seg2 & 0xfffc); - return; - } - - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if (DPL > CPL) - { - x86gpf(NULL,seg2&~3); - return; - } - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - CS=seg2; - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - break; - - default: - x86gpf(NULL,seg2&~3); - return; - } - cycles -= timing_jmp_pm_gate; - break; - - - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ - cpu_state.pc=oxpc; - optype=JMP; - cpl_override=1; - taskswitch286(seg,segdat,segdat[2]&0x800); - flags &= ~NT_FLAG; - cpl_override=0; - return; - - default: - x86gpf(NULL,0); - return; - } - } - } - else - { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; - CS=seg; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80; - else _cs.access=(0<<5) | 2 | 0x80; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - cycles -= timing_jmp_rm; - } -} - -void PUSHW(uint16_t v) -{ - if (stack32) - { - writememw(ss,ESP-2,v); - if (cpu_state.abrt) return; - ESP-=2; - } - else - { - writememw(ss,((SP-2)&0xFFFF),v); - if (cpu_state.abrt) return; - SP-=2; - } -} -void PUSHL(uint32_t v) -{ - if (stack32) - { - writememl(ss,ESP-4,v); - if (cpu_state.abrt) return; - ESP-=4; - } - else - { - writememl(ss,((SP-4)&0xFFFF),v); - if (cpu_state.abrt) return; - SP-=4; - } -} -uint16_t POPW() -{ - uint16_t tempw; - if (stack32) - { - tempw=readmemw(ss,ESP); - if (cpu_state.abrt) return 0; - ESP+=2; - } - else - { - tempw=readmemw(ss,SP); - if (cpu_state.abrt) return 0; - SP+=2; - } - return tempw; -} -uint32_t POPL() -{ - uint32_t templ; - if (stack32) - { - templ=readmeml(ss,ESP); - if (cpu_state.abrt) return 0; - ESP+=4; - } - else - { - templ=readmeml(ss,SP); - if (cpu_state.abrt) return 0; - SP+=4; - } - return templ; -} - -void loadcscall(uint16_t seg) -{ - uint16_t seg2; - uint16_t segdat[4],segdat2[4],newss; - uint32_t addr,oldssbase=ss, oaddr; - uint32_t newpc; - int count; - uint32_t oldss,oldsp,newsp, oldsp2; - int type; - uint16_t tempw; - - int csout = output; - - if (msw&1 && !(eflags&VM_FLAG)) - { - if (csout) x86seg_log("Protected mode CS load! %04X\n",seg); - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - type=segdat[2]&0xF00; - newpc=segdat[0]; - if (type&0x800) newpc|=segdat[3]<<16; - - if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]); - if (segdat[2]&0x1000) - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf("loadcscall(): segment > CPL",seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf(NULL,seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - /*Conforming segments don't change CPL, so preserve existing CPL*/ - if (segdat[2]&0x400) - { - seg = (seg & ~3) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - } - else /*On non-conforming segments, set RPL = CPL*/ - seg = (seg & ~3) | CPL; - CS=seg; - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - if (csout) x86seg_log("Complete\n"); - cycles -= timing_call_pm; - } - else - { - type=segdat[2]&0xF00; - if (csout) x86seg_log("Type %03X\n",type); - switch (type) - { - case 0x400: /*Call gate*/ - case 0xC00: /*386 Call gate*/ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32=(type&0x800); - cgate16=!cgate32; - oldcs=CS; - count=segdat[2]&31; - if (DPL < CPL) - { - x86gpf("loadcscall(): ex DPL < CPL",seg&~3); - return; - } - if ((DPL < (seg&3))) - { - x86gpf("loadcscall(): ex (DPL < (seg&3))",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86seg_log("Call gate not present %04X\n",seg); - x86np("Call gate not present\n", seg & 0xfffc); - return; - } - seg2=segdat[1]; - - x86seg_log("New address : %04X:%08X\n", seg2, newpc); - - if (!(seg2&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg2&~7; - if (seg2&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - - x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]); - - if (DPL > CPL) - { - x86gpf("loadcscall(): ex DPL > CPL",seg2&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86seg_log("Call gate CS not present %04X\n",seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } - - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if (DPL < CPL) - { - oaddr = addr; - /*Load new stack*/ - oldss=SS; - oldsp=oldsp2=ESP; - cpl_override=1; - if (tr.access&8) - { - addr = 4 + tr.base + (DPL * 8); - newss=readmemw(0,addr+4); - newsp=readmeml(0,addr); - } - else - { - addr = 2 + tr.base + (DPL * 4); - newss=readmemw(0,addr+2); - newsp=readmemw(0,addr); - } - cpl_override=0; - if (cpu_state.abrt) return; - x86seg_log("New stack %04X:%08X\n",newss,newsp); - if (!(newss&~3)) - { - x86ts(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if (addr>=ldt.limit) - { - x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit); - x86ts(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); - x86ts(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - x86seg_log("Read stack seg\n"); - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 3) != DPL) || (DPL2 != DPL)) - { - x86ts(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - x86ts(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - x86ss("Call gate loading SS not present\n", newss & 0xfffc); - return; - } - if (!stack32) oldsp &= 0xFFFF; - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - - do_seg_load(&_ss, segdat2); - - x86seg_log("Set access 1\n"); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - CS=seg2; - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - - x86seg_log("Set access 2\n"); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - x86seg_log("Type %04X\n",type); - if (type==0xC00) - { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - return; - } - if (count) - { - while (count) - { - count--; - PUSHL(readmeml(oldssbase,oldsp+(count*4))); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - return; - } - } - } - } - else - { - x86seg_log("Stack %04X\n",SP); - PUSHW(oldss); - x86seg_log("Write SS to %04X:%04X\n",SS,SP); - PUSHW(oldsp2); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - return; - } - x86seg_log("Write SP to %04X:%04X\n",SS,SP); - if (count) - { - while (count) - { - count--; - tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2)); - x86seg_log("PUSH %04X\n",tempw); - PUSHW(tempw); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - return; - } - } - } - } - cycles -= timing_call_pm_gate_inner; - break; - } - else if (DPL > CPL) - { - x86gpf(NULL,seg2&~3); - return; - } - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - CS=seg2; - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - cycles -= timing_call_pm_gate; - break; - - default: - x86gpf(NULL,seg2&~3); - return; - } - break; - - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ - cpu_state.pc=oxpc; - cpl_override=1; - taskswitch286(seg,segdat,segdat[2]&0x800); - cpl_override=0; - break; - - default: - x86gpf(NULL,seg&~3); - return; - } - } - } - else - { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; - CS=seg; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80; - else _cs.access=(0<<5) | 2 | 0x80; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - } -} - -void pmoderetf(int is32, uint16_t off) -{ - uint32_t newpc; - uint32_t newsp; - uint32_t addr, oaddr; - uint16_t segdat[4],segdat2[4],seg,newss; - uint32_t oldsp=ESP; - x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags); - if (is32) - { - newpc=POPL(); - seg=POPL(); if (cpu_state.abrt) return; - } - else - { - x86seg_log("PC read from %04X:%04X\n",SS,SP); - newpc=POPW(); - x86seg_log("CS read from %04X:%04X\n",SS,SP); - seg=POPW(); if (cpu_state.abrt) return; - } - x86seg_log("Return to %04X:%08X\n",seg,newpc); - if ((seg&3)=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } - oaddr = addr; - - x86seg_log("CPL %i RPL %i %i\n",CPL,seg&3,is32); - - if (stack32) ESP+=off; - else SP+=off; - - if (CPL==(seg&3)) - { - x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if (CPL != DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if (CPL < DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - default: - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - cpu_state.pc=newpc; - if (segdat[2] & 0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - CS = seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); - - cycles -= timing_retf_pm; - } - else - { - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((seg&3) != DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL); - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((seg&3) < DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - x86seg_log("RETF conforming, %i %i\n",seg&3, DPL); - break; - default: - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } - if (is32) - { - newsp=POPL(); - newss=POPL(); if (cpu_state.abrt) return; - } - else - { - x86seg_log("SP read from %04X:%04X\n",SS,SP); - newsp=POPW(); - x86seg_log("SS read from %04X:%04X\n",SS,SP); - newss=POPW(); if (cpu_state.abrt) return; - } - x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss&~3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if (addr>=ldt.limit) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - if ((newss & 3) != (seg & 3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF loading SS not present\n", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&_ss, segdat2); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - -#ifdef CS_ACCESSED - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ -#endif - cpl_override = 0; -#endif - /*Conforming segments don't change CPL, so CPL = RPL*/ - if (segdat[2]&0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - - cpu_state.pc=newpc; - CS=seg; - do_seg_load(&_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); - - if (stack32) ESP+=off; - else SP+=off; - - check_seg_valid(&_ds); - check_seg_valid(&_es); - check_seg_valid(&_fs); - check_seg_valid(&_gs); - cycles -= timing_retf_pm_outer; - } -} - -void restore_stack() -{ - ss=oldss; _ss.limit=oldsslimit; -} - -void pmodeint(int num, int soft) -{ - uint16_t segdat[4],segdat2[4],segdat3[4]; - uint32_t addr, oaddr; - uint16_t newss; - uint32_t oldss,oldsp; - int type; - uint32_t newsp; - uint16_t seg = 0; - int new_cpl; - - if (eflags&VM_FLAG && IOPL!=3 && soft) - { - x86seg_log("V86 banned int\n"); - x86gpf(NULL,0); - return; - } - addr=(num<<3); - if (addr>=idt.limit) - { - if (num==8) - { - /*Triple fault - reset!*/ - softresetx86(); - cpu_set_edx(); - } - else if (num==0xD) - { - pmodeint(8,0); - } - else - { - x86gpf(NULL,(num*8)+2+((soft)?0:1)); - } - x86seg_log("addr >= IDT.limit\n"); - return; - } - addr+=idt.base; - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(2,addr); - segdat[2]=readmemw(4,addr); - segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; } - oaddr = addr; - - x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]); - if (!(segdat[2]&0x1F00)) - { - x86gpf(NULL,(num*8)+2); - return; - } - if (DPL=0x800)?32:16; - if (!(segdat[2]&0x8000)) - { - x86np("Int gate not present\n", (num << 3) | 2); - return; - } - seg=segdat[1]; - new_cpl = seg & 3; - - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - oaddr = addr; - - if (DPL2 > CPL) - { - x86gpf(NULL,seg&~3); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if (DPL2=ldt.limit) - { - x86ss(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ss(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat3[0]=readmemw(0,addr); - segdat3[1]=readmemw(0,addr+2); - segdat3[2]=readmemw(0,addr+4); - segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - if (((newss & 3) != DPL2) || (DPL3 != DPL2)) - { - x86ss(NULL,newss&~3); - return; - } - if ((segdat3[2]&0x1A00)!=0x1200) - { - x86ss(NULL,newss&~3); - return; - } - if (!(segdat3[2]&0x8000)) - { - x86np("Int gate loading SS not present\n", newss & 0xfffc); - return; - } - SS=newss; - set_stack32((segdat3[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&_ss, segdat3); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat3[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - x86seg_log("New stack %04X:%08X\n",SS,ESP); - cpl_override=1; - if (type>=0x800) - { - if (eflags & VM_FLAG) - { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); if (cpu_state.abrt) return; - loadseg(0,&_ds); - loadseg(0,&_es); - loadseg(0,&_fs); - loadseg(0,&_gs); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(flags|(eflags<<16)); - PUSHL(CS); - PUSHL(cpu_state.pc); if (cpu_state.abrt) return; - } - else - { - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(flags); - PUSHW(CS); - PUSHW(cpu_state.pc); if (cpu_state.abrt) return; - } - cpl_override=0; - _cs.access=0 | 0x80; - cycles -= timing_int_pm_outer - timing_int_pm; - break; - } - else if (DPL2!=CPL) - { - x86gpf(NULL,seg&~3); - return; - } - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if (!(segdat2[2]&0x8000)) - { - x86np("Int gate CS not present\n", segdat[1] & 0xfffc); - return; - } - if ((eflags & VM_FLAG) && DPL20x800) - { - PUSHL(flags|(eflags<<16)); - PUSHL(CS); - PUSHL(cpu_state.pc); if (cpu_state.abrt) return; - } - else - { - PUSHW(flags); - PUSHW(CS); - PUSHW(cpu_state.pc); if (cpu_state.abrt) return; - } - new_cpl = CS & 3; - break; - default: - x86gpf(NULL,seg&~3); - return; - } - do_seg_load(&_cs, segdat2); - CS = (seg & ~3) | new_cpl; - _cs.access = (_cs.access & ~(3 << 5)) | (new_cpl << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); - else cpu_state.pc=segdat[0]; - set_use32(segdat2[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - eflags&=~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type&0x100)) - { - flags&=~I_FLAG; - } - flags&=~(T_FLAG|NT_FLAG); - cycles -= timing_int_pm; - break; - - case 0x500: /*Task gate*/ - seg=segdat[1]; - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - cpl_override=0; if (cpu_state.abrt) return; - if (!(segdat2[2]&0x8000)) - { - x86np("Int task gate not present\n", segdat[1] & 0xfffc); - return; - } - optype=OPTYPE_INT; - cpl_override=1; - taskswitch286(seg,segdat2,segdat2[2]&0x800); - cpl_override=0; - break; - - default: - x86gpf(NULL,seg&~3); - return; - } -} - -void pmodeiret(int is32) -{ - uint32_t newsp; - uint16_t newss; - uint32_t tempflags,flagmask; - uint32_t newpc; - uint16_t segdat[4],segdat2[4]; - uint16_t segs[4]; - uint16_t seg; - uint32_t addr, oaddr; - uint32_t oldsp=ESP; - if (is386 && (eflags&VM_FLAG)) - { - if (IOPL!=3) - { - x86gpf(NULL,0); - return; - } - oxpc=cpu_state.pc; - if (is32) - { - newpc=POPL(); - seg=POPL(); - tempflags=POPL(); if (cpu_state.abrt) return; - } - else - { - newpc=POPW(); - seg=POPW(); - tempflags=POPW(); if (cpu_state.abrt) return; - } - cpu_state.pc=newpc; - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; - _cs.access |= 0x80; - CS=seg; - flags=(flags&0x3000)|(tempflags&0xCFD5)|2; - cycles -= timing_iret_rm; - return; - } - - if (flags&NT_FLAG) - { - seg=readmemw(tr.base,0); - addr=seg&~7; - if (seg&4) - { - x86seg_log("TS LDT %04X %04X IRET\n",seg,gdt.limit); - x86ts(NULL,seg&~3); - return; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); - taskswitch286(seg,segdat,segdat[2] & 0x800); - cpl_override=0; - return; - } - oxpc=cpu_state.pc; - flagmask=0xFFFF; - if (CPL) flagmask&=~0x3000; - if (IOPL>16)&VM_FLAG)) - { - newsp=POPL(); - newss=POPL(); - segs[0]=POPL(); - segs[1]=POPL(); - segs[2]=POPL(); - segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } - eflags=tempflags>>16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0],&_es); - do_seg_v86_init(&_es); - loadseg(segs[1],&_ds); - do_seg_v86_init(&_ds); - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2],&_fs); - do_seg_v86_init(&_fs); - loadseg(segs[3],&_gs); - do_seg_v86_init(&_gs); - - cpu_state.pc=newpc; - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; - CS=seg; - _cs.access=(3<<5) | 2 | 0x80; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - - ESP=newsp; - loadseg(newss,&_ss); - do_seg_v86_init(&_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32=0; - cpu_cur_status &= ~CPU_STATUS_USE32; - flags=(tempflags&0xFFD5)|2; - cycles -= timing_iret_v86; - return; - } - } - else - { - newpc=POPW(); - seg=POPW(); - tempflags=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - if (!(seg&~3)) - { - ESP = oldsp; - x86gpf(NULL,0); - return; - } - - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - if ((seg&3) < CPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if ((seg&3) != DPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/ - if ((seg&3) < DPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - default: - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP = oldsp; - x86np("IRET CS not present\n", seg & 0xfffc); - return; - } - if ((seg&3) == CPL) - { - CS=seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - cycles -= timing_iret_pm; - } - else /*Return to outer level*/ - { - oaddr = addr; - x86seg_log("Outer level\n"); - if (is32) - { - newsp=POPL(); - newss=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - else - { - newsp=POPW(); - newss=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - - x86seg_log("IRET load stack %04X:%04X\n",newss,newsp); - - if (!(newss&~3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if (addr>=ldt.limit) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } - if ((newss & 3) != (seg & 3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (DPL2 != (seg & 3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - ESP = oldsp; - x86np("IRET loading SS not present\n", newss & 0xfffc); - return; - } - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&_ss, segdat2); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - -#ifdef CS_ACCESSED - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ -#endif - cpl_override = 0; -#endif - /*Conforming segments don't change CPL, so CPL = RPL*/ - if (segdat[2]&0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - - CS=seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); - - check_seg_valid(&_ds); - check_seg_valid(&_es); - check_seg_valid(&_fs); - check_seg_valid(&_gs); - cycles -= timing_iret_pm_outer; - } - cpu_state.pc=newpc; - flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2; - if (is32) eflags=tempflags>>16; -} - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) -{ - uint32_t base; - uint32_t limit; - uint32_t templ; - uint16_t tempw; - - uint32_t new_cr3=0; - uint16_t new_es,new_cs,new_ss,new_ds,new_fs,new_gs; - uint16_t new_ldt; - - uint32_t new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi,new_pc,new_flags; - - uint32_t addr; - - uint16_t segdat2[4]; - - base=segdat[1]|((segdat[2]&0xFF)<<16); - limit=segdat[0]; - if(is386) - { - base |= (segdat[3]>>8)<<24; - limit |= (segdat[3]&0xF)<<16; - } - - if (is32) - { - if (limit < 103) - { - x86ts(NULL, seg); - return; - } - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==IRET) flags&=~NT_FLAG; - - cpu_386_flags_rebuild(); - writememl(tr.base,0x1C,cr3); - writememl(tr.base,0x20,cpu_state.pc); - writememl(tr.base,0x24,flags|(eflags<<16)); - - writememl(tr.base,0x28,EAX); - writememl(tr.base,0x2C,ECX); - writememl(tr.base,0x30,EDX); - writememl(tr.base,0x34,EBX); - writememl(tr.base,0x38,ESP); - writememl(tr.base,0x3C,EBP); - writememl(tr.base,0x40,ESI); - writememl(tr.base,0x44,EDI); - - writememl(tr.base,0x48,ES); - writememl(tr.base,0x4C,CS); - writememl(tr.base,0x50,SS); - writememl(tr.base,0x54,DS); - writememl(tr.base,0x58,FS); - writememl(tr.base,0x5C,GS); - - if (optype==JMP || optype==IRET) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememl(base,0,tr.seg); - if (cpu_state.abrt) - return; - } - - - new_cr3=readmeml(base,0x1C); - new_pc=readmeml(base,0x20); - new_flags=readmeml(base,0x24); - if (optype == OPTYPE_INT || optype == CALL) - new_flags |= NT_FLAG; - - new_eax=readmeml(base,0x28); - new_ecx=readmeml(base,0x2C); - new_edx=readmeml(base,0x30); - new_ebx=readmeml(base,0x34); - new_esp=readmeml(base,0x38); - new_ebp=readmeml(base,0x3C); - new_esi=readmeml(base,0x40); - new_edi=readmeml(base,0x44); - - new_es=readmemw(base,0x48); - new_cs=readmemw(base,0x4C); - new_ss=readmemw(base,0x50); - new_ds=readmemw(base,0x54); - new_fs=readmemw(base,0x58); - new_gs=readmemw(base,0x5C); - new_ldt=readmemw(base,0x60); - - cr0 |= 8; - - cr3=new_cr3; - flushmmucache(); - - cpu_state.pc=new_pc; - flags=new_flags; - eflags=new_flags>>16; - cpu_386_flags_extract(); - - ldt.seg=new_ldt; - templ=(ldt.seg&~7)+gdt.base; - ldt.limit=readmemw(0,templ); - if (readmemb(0,templ+6)&0x80) - { - ldt.limit<<=12; - ldt.limit|=0xFFF; - } - ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); - - if (eflags & VM_FLAG) - { - loadcs(new_cs); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } - else - { - if (!(new_cs&~3)) - { - x86ts(NULL,0); - return; - } - addr=new_cs&~7; - if (new_cs&4) - { - if (addr>=ldt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=gdt.base; - } - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - if (!(segdat2[2]&0x8000)) - { - x86np("TS loading CS not present\n", new_cs & 0xfffc); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((new_cs&3) != DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((new_cs&3) < DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - default: - x86ts(NULL,new_cs&~3); - return; - } - - CS=new_cs; - do_seg_load(&_cs, segdat2); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat2[3] & 0x40); - cpu_cur_status &= ~CPU_STATUS_V86; - } - - EAX=new_eax; - ECX=new_ecx; - EDX=new_edx; - EBX=new_ebx; - ESP=new_esp; - EBP=new_ebp; - ESI=new_esi; - EDI=new_edi; - - loadseg(new_es,&_es); - loadseg(new_ss,&_ss); - loadseg(new_ds,&_ds); - loadseg(new_fs,&_fs); - loadseg(new_gs,&_gs); - } - else - { - if (limit < 43) - { - x86ts(NULL, seg); - return; - } - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==IRET) flags&=~NT_FLAG; - - cpu_386_flags_rebuild(); - writememw(tr.base,0x0E,cpu_state.pc); - writememw(tr.base,0x10,flags); - - writememw(tr.base,0x12,AX); - writememw(tr.base,0x14,CX); - writememw(tr.base,0x16,DX); - writememw(tr.base,0x18,BX); - writememw(tr.base,0x1A,SP); - writememw(tr.base,0x1C,BP); - writememw(tr.base,0x1E,SI); - writememw(tr.base,0x20,DI); - - writememw(tr.base,0x22,ES); - writememw(tr.base,0x24,CS); - writememw(tr.base,0x26,SS); - writememw(tr.base,0x28,DS); - - if (optype==JMP || optype==IRET) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememw(base,0,tr.seg); - if (cpu_state.abrt) - return; - } - - new_pc=readmemw(base,0x0E); - new_flags=readmemw(base,0x10); - if (optype == OPTYPE_INT || optype == CALL) - new_flags |= NT_FLAG; - - new_eax=readmemw(base,0x12); - new_ecx=readmemw(base,0x14); - new_edx=readmemw(base,0x16); - new_ebx=readmemw(base,0x18); - new_esp=readmemw(base,0x1A); - new_ebp=readmemw(base,0x1C); - new_esi=readmemw(base,0x1E); - new_edi=readmemw(base,0x20); - - new_es=readmemw(base,0x22); - new_cs=readmemw(base,0x24); - new_ss=readmemw(base,0x26); - new_ds=readmemw(base,0x28); - new_ldt=readmemw(base,0x2A); - - msw |= 8; - - cpu_state.pc=new_pc; - flags=new_flags; - cpu_386_flags_extract(); - - ldt.seg=new_ldt; - templ=(ldt.seg&~7)+gdt.base; - ldt.limit=readmemw(0,templ); - ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); - if (is386) - { - if (readmemb(0,templ+6)&0x80) - { - ldt.limit<<=12; - ldt.limit|=0xFFF; - } - ldt.base|=(readmemb(0,templ+7)<<24); - } - - if (!(new_cs&~3)) - { - x86ts(NULL,0); - return; - } - addr=new_cs&~7; - if (new_cs&4) - { - if (addr>=ldt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=gdt.base; - } - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - if (!(segdat2[2]&0x8000)) - { - x86np("TS loading CS not present\n", new_cs & 0xfffc); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((new_cs&3) != DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((new_cs&3) < DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - default: - x86ts(NULL,new_cs&~3); - return; - } - - CS=new_cs; - do_seg_load(&_cs, segdat2); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(0); - - EAX=new_eax | 0xFFFF0000; - ECX=new_ecx | 0xFFFF0000; - EDX=new_edx | 0xFFFF0000; - EBX=new_ebx | 0xFFFF0000; - ESP=new_esp | 0xFFFF0000; - EBP=new_ebp | 0xFFFF0000; - ESI=new_esi | 0xFFFF0000; - EDI=new_edi | 0xFFFF0000; - - loadseg(new_es,&_es); - loadseg(new_ss,&_ss); - loadseg(new_ds,&_ds); - if (is386) - { - loadseg(0,&_fs); - loadseg(0,&_gs); - } - } - - tr.seg=seg; - tr.base=base; - tr.limit=limit; - tr.access=segdat[2]>>8; -} diff --git a/src - Cópia/cpu/x86seg.h b/src - Cópia/cpu/x86seg.h deleted file mode 100644 index 4f12a8d65..000000000 --- a/src - Cópia/cpu/x86seg.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x86 CPU segment emulation. - * - * Version: @(#)x86seg.h 1.0.1 2017/10/12 - * - * Author: Miran Grca, - * - * Copyright 2016-2017 Miran Grca. - */ - -extern void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src - Cópia/cpu/x87.c b/src - Cópia/cpu/x87.c deleted file mode 100644 index d85cd54ce..000000000 --- a/src - Cópia/cpu/x87.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#define fplog 0 -#include -#include "../86box.h" -#include "cpu.h" -#include "../mem.h" -#include "../pic.h" -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" -#include "386_common.h" - - -uint16_t x87_gettag() -{ - uint16_t ret = 0; - int c; - - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else - ret |= (cpu_state.tag[c] << (c*2)); - } - - return ret; -} - -void x87_settag(uint16_t new_tag) -{ - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; -} - -void x87_dumpregs() -{ - if (cpu_state.ismmx) - { - pclog("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); - pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); - } - else - { - pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); - pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]); - } - pclog("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); -} - -void x87_print() -{ - if (cpu_state.ismmx) - { - pclog("\tMM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\t", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); - pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); - } - else - { - pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",cpu_state.ST[cpu_state.TOP&7],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); - pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\tTOP=%i CR=%04X SR=%04X TAG=%04X\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7], cpu_state.TOP, cpu_state.npxc, cpu_state.npxs, x87_gettag()); - } -} - -void x87_reset() -{ -} diff --git a/src - Cópia/cpu/x87.h b/src - Cópia/cpu/x87.h deleted file mode 100644 index 5e3db1960..000000000 --- a/src - Cópia/cpu/x87.h +++ /dev/null @@ -1,8 +0,0 @@ -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - -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 - Cópia/cpu/x87_ops.h b/src - Cópia/cpu/x87_ops.h deleted file mode 100644 index d1fd0b464..000000000 --- a/src - Cópia/cpu/x87_ops.h +++ /dev/null @@ -1,1775 +0,0 @@ -/* - * 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. - * - * x87 FPU instructions core. - * - * Version: @(#)x87_ops.h 1.0.5 2018/05/05 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * leilei, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#ifdef _MSC_VER -# include -#endif - -#define fplog 0 - -static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; - -#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] - -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - -#define STATUS_ZERODIVIDE 4 - -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - pclog("FPU : divide by zero\n"); \ - picint(1 << 13); \ - } \ - return 1; \ - } \ - else \ - dst = src1 / (double)src2; \ - } while (0) - -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 = 0x0303030303030303ll; - cpu_state.ismmx = 0; -} - -static __inline void x87_checkexceptions() -{ -} - -static __inline void x87_push(double i) -{ - 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; -} - -static inline void x87_push_u64(uint64_t i) -{ - union - { - double d; - uint64_t ll; - } td; - - td.ll = i; - - 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; -} - -static __inline double x87_pop() -{ - 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; -} - -static __inline int64_t x87_fround(double b) -{ - int64_t a, c; - - switch ((cpu_state.npxc>>10)&3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - default: - return (int64_t)0; - } -} -#define BIAS80 16383 -#define BIAS64 1023 - -static __inline double x87_ld80() -{ - int64_t exp64; - int64_t blah; - int64_t exp64final; - int64_t mant64; - int64_t sign; - struct { - int16_t begin; - union - { - double d; - uint64_t ll; - } eind; - } test; - test.eind.ll = readmeml(easeg,cpu_state.eaaddr); - test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; - test.begin = readmemw(easeg,cpu_state.eaaddr+8); - - exp64 = (((test.begin&0x7fff) - BIAS80)); - blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - exp64final = ((exp64 >0)?blah:-blah) +BIAS64; - - mant64 = (test.eind.ll >> 11) & (0xfffffffffffffll); - sign = (test.begin&0x8000)?1:0; - - if ((test.begin & 0x7fff) == 0x7fff) - exp64final = 0x7ff; - if ((test.begin & 0x7fff) == 0) - exp64final = 0; - if (test.eind.ll & 0x400) - mant64++; - - test.eind.ll = (sign <<63)|(exp64final << 52)| mant64; - - return test.eind.d; -} - -static __inline void x87_st80(double d) -{ - int64_t sign80; - int64_t exp80; - int64_t exp80final; - int64_t mant80; - int64_t mant80final; - - struct { - int16_t begin; - union - { - double d; - uint64_t ll; - } eind; - } test; - - test.eind.d=d; - - sign80 = (test.eind.ll&(0x8000000000000000ll))?1:0; - exp80 = test.eind.ll&(0x7ff0000000000000ll); - exp80final = (exp80>>52); - mant80 = test.eind.ll&(0x000fffffffffffffll); - mant80final = (mant80 << 11); - - if (exp80final == 0x7ff) /*Infinity / Nan*/ - { - exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); - } - else if (d != 0){ /* Zero is a special case */ - /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); - /* Ca-cyber doesn't like this when result is zero. */ - exp80final += (BIAS80 - BIAS64); - } - test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; - test.eind.ll = mant80final; - - writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); - writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); - writememw(easeg,cpu_state.eaaddr+8,test.begin); -} - -static __inline void x87_st_fsave(int reg) -{ - reg = (cpu_state.TOP + reg) & 7; - - if (cpu_state.tag[reg] & TAG_UINT64) - { - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); - writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); - writememw(easeg, cpu_state.eaaddr + 8, 0x5555); - } - else - x87_st80(cpu_state.ST[reg]); -} - -static __inline void x87_ld_frstor(int reg) -{ - reg = (cpu_state.TOP + reg) & 7; - - cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); - cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); - - if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) - { - cpu_state.tag[reg] = TAG_UINT64; - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } - else - cpu_state.ST[reg] = x87_ld80(); -} - -static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) -{ - r->l[0] = readmeml(easeg, cpu_state.eaaddr); - r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - *w4 = readmemw(easeg, cpu_state.eaaddr + 8); -} - -static __inline void x87_stmmx(MMX_REG r) -{ - writememl(easeg, cpu_state.eaaddr, r.l[0]); - writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); - writememw(easeg, cpu_state.eaaddr + 8, 0xffff); -} - -static __inline uint16_t x87_compare(double a, double b) -{ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 - uint32_t result; - - if (!is386) - { - if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - { - /* pclog("Comparing infinity\n"); */ -#ifndef _MSC_VER - __asm volatile ("" : : : "memory"); - - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (a) - ); -#else - _ReadWriteBarrier(); - __asm - { - fld a - fld a - fclex - fcompp - fnstsw result - } -#endif - - return result & (C0|C2|C3); - } - } - -#ifndef _MSC_VER - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); - - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (b) - ); -#else - _ReadWriteBarrier(); - _asm - { - fld b - fld a - fclex - fcompp - fnstsw result - } -#endif - - return result & (C0|C2|C3); -#else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t out = 0; - - if (is386) - { - if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - { - result |= C3; - return result; - } - - if (a == b) - result |= C3; - else if (a < b) - result |= C0; - } - else - { - if (a == b) - result |= C3; - else if (a < b) - result |= C0; - } - - return result; -#endif -} - -static __inline uint16_t x87_ucompare(double a, double b) -{ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 - uint32_t result; - -#ifndef _MSC_VER - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); - - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fucompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (b) - ); -#else - _ReadWriteBarrier(); - _asm - { - fld b - fld a - fclex - fcompp - fnstsw result - } -#endif - - return result & (C0|C2|C3); -#else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; - - if (a == b) - result |= C3; - else if (a < b) - result |= C0; - - return result; -#endif -} - -typedef union -{ - float s; - uint32_t i; -} x87_ts; - -typedef union -{ - double d; - uint64_t i; -} x87_td; - -#define FP_ENTER() do \ - { \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - fpucount++; \ - } while (0) - -#include "x87_ops_arith.h" -#include "x87_ops_misc.h" -#include "x87_ops_loadstore.h" - -static int op_nofpu_a16(uint32_t fetchdat) -{ - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_16(fetchdat); - return 0; - } -} -static int op_nofpu_a32(uint32_t fetchdat) -{ - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_32(fetchdat); - return 0; - } -} - -static int FPU_ILLEGAL_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} - -static int FPU_ILLEGAL_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} - -#define ILLEGAL_a16 FPU_ILLEGAL_a16 -#define ILLEGAL_a32 FPU_ILLEGAL_a32 - -const OpFn OP_TABLE(fpu_d8_a16)[32] = -{ - opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, - opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, - opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, - opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR -}; -const OpFn OP_TABLE(fpu_d8_a32)[32] = -{ - opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, - opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, - opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, - opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR -}; - -const OpFn OP_TABLE(fpu_287_d9_a16)[256] = -{ - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ - opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -}; - -const OpFn OP_TABLE(fpu_287_d9_a32)[256] = -{ - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/ - opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -}; - -const OpFn OP_TABLE(fpu_d9_a16)[256] = -{ - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, - opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, - opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, - opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, - opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, - opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -}; - -const OpFn OP_TABLE(fpu_d9_a32)[256] = -{ - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, - opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, - opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, - opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, - opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, - opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -}; - -const OpFn OP_TABLE(fpu_287_da_a16)[256] = -{ - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_287_da_a32)[256] = -{ - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_da_a16)[256] = -{ - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_da_a32)[256] = -{ - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_686_da_a16)[256] = -{ - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, - opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, - opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, - opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, - opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, - opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, - opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, - opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - - opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, - opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, - opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, - opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_686_da_a32)[256] = -{ - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, - opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, - opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, - opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_287_db_a16)[256] = -{ - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_287_db_a32)[256] = -{ - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_db_a16)[256] = -{ - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_db_a32)[256] = -{ - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_686_db_a16)[256] = -{ - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, - opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - - opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, - opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, - opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, - opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, - opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, - opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_686_db_a32)[256] = -{ - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, - opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - - opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, - opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, - opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, - opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, - opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, - opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_287_dc_a16)[32] = -{ - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -}; -const OpFn OP_TABLE(fpu_287_dc_a32)[32] = -{ - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -}; - -const OpFn OP_TABLE(fpu_dc_a16)[32] = -{ - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -}; -const OpFn OP_TABLE(fpu_dc_a32)[32] = -{ - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -}; - -const OpFn OP_TABLE(fpu_287_dd_a16)[256] = -{ - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_287_dd_a32)[256] = -{ - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_dd_a16)[256] = -{ - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, - opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, - opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, - opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, - - opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, - opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_dd_a32)[256] = -{ - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, - opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, - opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, - opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, - - opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, - opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_287_de_a16)[256] = -{ - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, - opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, - opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, - opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, - opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -}; - -const OpFn OP_TABLE(fpu_287_de_a32)[256] = -{ - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, - opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, - opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, - opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, - opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -}; - -const OpFn OP_TABLE(fpu_de_a16)[256] = -{ - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, - opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, - opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, - opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, - opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, - opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, - opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, - opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, - - opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, - opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, - ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, - opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, - opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, - opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -}; - -const OpFn OP_TABLE(fpu_de_a32)[256] = -{ - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, - opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, - opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, - opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, - opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, - opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, - opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, - opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, - - opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, - opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, - ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, - opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, - opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, - opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -}; - -const OpFn OP_TABLE(fpu_287_df_a16)[256] = -{ - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_287_df_a32)[256] = -{ - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_df_a16)[256] = -{ - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_df_a32)[256] = -{ - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(fpu_686_df_a16)[256] = -{ - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, - opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, - FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, - FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, - opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, - opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_686_df_a32)[256] = -{ - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, - opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, - FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, - FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, - - opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, - opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -}; - -const OpFn OP_TABLE(nofpu_a16)[256] = -{ - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, -}; -const OpFn OP_TABLE(nofpu_a32)[256] = -{ - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, -}; diff --git a/src - Cópia/cpu/x87_ops_arith.h b/src - Cópia/cpu/x87_ops_arith.h deleted file mode 100644 index f53ad9213..000000000 --- a/src - Cópia/cpu/x87_ops_arith.h +++ /dev/null @@ -1,431 +0,0 @@ -#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); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ - ST(0) += use_var; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(FE_TONEAREST); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(8); \ - return 0; \ -} \ -static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - 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); \ - 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); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(73); \ - return 0; \ -} \ -static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(73); \ - return 0; \ -} \ -static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(11); \ - return 0; \ -} \ -static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(8); \ - return 0; \ -} \ -static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ - CLOCK_CYCLES(8); \ - return 0; \ -} - - -opFPU(s, x87_ts, 16, t.i, geteal, t.s) -opFPU(s, x87_ts, 32, t.i, geteal, t.s) -opFPU(d, x87_td, 16, t.i, geteaq, t.d) -opFPU(d, x87_td, 32, t.i, geteaq, t.d) - -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t) -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t) -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t) -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t) - - - - -static int opFADD(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FADD\n"); - ST(0) = ST(0) + ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFADDr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FADD\n"); - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFADDP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FADDP\n"); - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(8); - return 0; -} - -static int opFCOM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FCOM\n"); - 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++; - if (fplog) pclog("FCOMP\n"); - 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++; - if (fplog) pclog("FCOMPP\n"); - 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; -} -static int opFUCOMPP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FUCOMPP\n", easeg, cpu_state.eaaddr); - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES(5); - return 0; -} - -static int opFCOMI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FICOM\n"); - flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; - CLOCK_CYCLES(4); - return 0; -} -static int opFCOMIP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FICOMP\n"); - flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES(4); - return 0; -} - -static int opFDIV(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIV\n"); - x87_div(ST(0), ST(0), ST(fetchdat & 7)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(73); - return 0; -} -static int opFDIVr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIV\n"); - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(73); - return 0; -} -static int opFDIVP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIVP\n"); - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(73); - return 0; -} - -static int opFDIVR(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIVR\n"); - x87_div(ST(0), ST(fetchdat&7), ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(73); - return 0; -} -static int opFDIVRr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIVR\n"); - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(73); - return 0; -} -static int opFDIVRP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDIVR\n"); - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(73); - return 0; -} - -static int opFMUL(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FMUL\n"); - ST(0) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(16); - return 0; -} -static int opFMULr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FMUL\n"); - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(16); - return 0; -} -static int opFMULP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FMULP\n"); - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(16); - return 0; -} - -static int opFSUB(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUB\n"); - ST(0) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFSUBr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUB\n"); - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFSUBP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUBP\n"); - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(8); - return 0; -} - -static int opFSUBR(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUBR\n"); - ST(0) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFSUBRr(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUBR\n"); - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - CLOCK_CYCLES(8); - return 0; -} -static int opFSUBRP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSUBRP\n"); - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(8); - return 0; -} - -static int opFUCOM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FUCOM\n"); - 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++; - if (fplog) pclog("FUCOMP\n"); - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES(4); - return 0; -} - -static int opFUCOMI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FUCOMI\n"); - flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; - CLOCK_CYCLES(4); - return 0; -} -static int opFUCOMIP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FUCOMIP\n"); - flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES(4); - return 0; -} diff --git a/src - Cópia/cpu/x87_ops_loadstore.h b/src - Cópia/cpu/x87_ops_loadstore.h deleted file mode 100644 index 39a14c4fb..000000000 --- a/src - Cópia/cpu/x87_ops_loadstore.h +++ /dev/null @@ -1,488 +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. - * - * x87 FPU instructions core. - * - * Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -static int opFILDiw_a16(uint32_t fetchdat) -{ - int16_t temp; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", (double)temp); - x87_push((double)temp); - CLOCK_CYCLES(13); - return 0; -} -static int opFILDiw_a32(uint32_t fetchdat) -{ - int16_t temp; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", (double)temp); - x87_push((double)temp); - CLOCK_CYCLES(13); - return 0; -} - -static int opFISTiw_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ - seteaw((int16_t)temp64); - CLOCK_CYCLES(29); - return cpu_state.abrt; -} -static int opFISTiw_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ - seteaw((int16_t)temp64); - CLOCK_CYCLES(29); - return cpu_state.abrt; -} - -static int opFISTPiw_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ - seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(29); - return 0; -} -static int opFISTPiw_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ - seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(29); - return 0; -} - -static int opFILDiq_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; - - CLOCK_CYCLES(10); - return 0; -} -static int opFILDiq_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; - - CLOCK_CYCLES(10); - return 0; -} - -static int FBSTP_a16(uint32_t fetchdat) -{ - double tempd; - int c; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - return 0; -} -static int FBSTP_a32(uint32_t fetchdat) -{ - double tempd; - int c; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - return 0; -} - -static int FISTPiq_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(29); - return 0; -} -static int FISTPiq_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(29); - return 0; -} - -static int opFILDil_a16(uint32_t fetchdat) -{ - int32_t templ; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr); - templ = geteal(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); - x87_push((double)templ); - CLOCK_CYCLES(9); - return 0; -} -static int opFILDil_a32(uint32_t fetchdat) -{ - int32_t templ; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr); - templ = geteal(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); - x87_push((double)templ); - CLOCK_CYCLES(9); - return 0; -} - -static int opFISTil_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ - seteal((int32_t)temp64); - CLOCK_CYCLES(28); - return cpu_state.abrt; -} -static int opFISTil_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ - seteal((int32_t)temp64); - CLOCK_CYCLES(28); - return cpu_state.abrt; -} - -static int opFISTPil_a16(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ - seteal((int32_t)temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(28); - return 0; -} -static int opFISTPil_a32(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); - temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ - seteal((int32_t)temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(28); - return 0; -} - -static int opFLDe_a16(uint32_t fetchdat) -{ - double t; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr); - t=x87_ld80(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", t); - x87_push(t); - CLOCK_CYCLES(6); - return 0; -} -static int opFLDe_a32(uint32_t fetchdat) -{ - double t; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr); - t=x87_ld80(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", t); - x87_push(t); - CLOCK_CYCLES(6); - return 0; -} - -static int opFSTPe_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(6); - return 0; -} -static int opFSTPe_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(6); - return 0; -} - -static int opFLDd_a16(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.i = geteaq(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", t.d); - x87_push(t.d); - CLOCK_CYCLES(3); - return 0; -} -static int opFLDd_a32(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.i = geteaq(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", t.d); - x87_push(t.d); - CLOCK_CYCLES(3); - return 0; -} - -static int opFSTd_a16(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES(8); - return cpu_state.abrt; -} -static int opFSTd_a32(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES(8); - return cpu_state.abrt; -} - -static int opFSTPd_a16(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(8); - return 0; -} -static int opFSTPd_a32(uint32_t fetchdat) -{ - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDs_a16(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.i = geteal(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", ts.s); - x87_push((double)ts.s); - CLOCK_CYCLES(3); - return 0; -} -static int opFLDs_a32(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.i = geteal(); if (cpu_state.abrt) return 1; - if (fplog) pclog(" %f\n", ts.s); - x87_push((double)ts.s); - CLOCK_CYCLES(3); - return 0; -} - -static int opFSTs_a16(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES(7); - return cpu_state.abrt; -} -static int opFSTs_a32(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES(7); - return cpu_state.abrt; -} - -static int opFSTPs_a16(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(7); - return 0; -} -static int opFSTPs_a32(uint32_t fetchdat) -{ - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(7); - return 0; -} diff --git a/src - Cópia/cpu/x87_ops_misc.h b/src - Cópia/cpu/x87_ops_misc.h deleted file mode 100644 index bf4eb3c7f..000000000 --- a/src - Cópia/cpu/x87_ops_misc.h +++ /dev/null @@ -1,861 +0,0 @@ -static int opFSTSW_AX(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSTSW\n"); - AX = cpu_state.npxs; - CLOCK_CYCLES(3); - return 0; -} - - - -static int opFNOP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - CLOCK_CYCLES(4); - return 0; -} - -static int opFCLEX(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= 0xff00; - CLOCK_CYCLES(4); - return 0; -} - -static int opFINIT(uint32_t fetchdat) -{ - uint64_t *p; - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - CLOCK_CYCLES(17); - return 0; -} - - -static int opFFREE(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FFREE\n"); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; - CLOCK_CYCLES(3); - return 0; -} - -static int opFFREEP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FFREE\n"); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES(3); - return 0; -} - -static int opFST(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FST\n"); - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES(3); - return 0; -} - -static int opFSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSTP\n"); - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - x87_pop(); - CLOCK_CYCLES(3); - return 0; -} - - - - -static int FSTOR() -{ - uint64_t *p; - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 14; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 28; - break; - } - x87_ld_frstor(0); cpu_state.eaaddr += 10; - x87_ld_frstor(1); cpu_state.eaaddr += 10; - x87_ld_frstor(2); cpu_state.eaaddr += 10; - x87_ld_frstor(3); cpu_state.eaaddr += 10; - x87_ld_frstor(4); cpu_state.eaaddr += 10; - x87_ld_frstor(5); cpu_state.eaaddr += 10; - x87_ld_frstor(6); cpu_state.eaaddr += 10; - x87_ld_frstor(7); - - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *)cpu_state.tag; - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - cpu_state.ismmx = 1; - - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, cpu_state.eaaddr, cpu_state.ismmx, cpu_state.TOP, x87_gettag()); - return cpu_state.abrt; -} -static int opFSTOR_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - FSTOR(); - return cpu_state.abrt; -} -static int opFSTOR_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - FSTOR(); - return cpu_state.abrt; -} - -static int FSAVE() -{ - uint64_t *p; - - FP_ENTER(); - if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11); - - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - } - - cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - return cpu_state.abrt; -} -static int opFSAVE_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - FSAVE(); - return cpu_state.abrt; -} -static int opFSAVE_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - FSAVE(); - return cpu_state.abrt; -} - -static int opFSTSW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); - CLOCK_CYCLES(3); - return cpu_state.abrt; -} -static int opFSTSW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); - CLOCK_CYCLES(3); - return cpu_state.abrt; -} - - -static int opFLD(uint32_t fetchdat) -{ - int old_tag; - uint64_t old_i64; - - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLD %f\n", ST(fetchdat & 7)); - 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; - CLOCK_CYCLES(4); - return 0; -} - -static int opFXCH(uint32_t fetchdat) -{ - double td; - uint8_t old_tag; - uint64_t old_i64; - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FXCH\n"); - 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]; - 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; - cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - - CLOCK_CYCLES(4); - return 0; -} - -static int opFCHS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FCHS\n"); - ST(0) = -ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(6); - return 0; -} - -static int opFABS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FABS %f\n", ST(0)); - ST(0) = fabs(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(3); - return 0; -} - -static int opFTST(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FTST\n"); - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == 0.0) cpu_state.npxs |= C3; - else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES(4); - return 0; -} - -static int opFXAM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0)); - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); - else if (ST(0) == 0.0) cpu_state.npxs |= C3; - else cpu_state.npxs |= C2; - if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES(8); - return 0; -} - -static int opFLD1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLD1\n"); - x87_push(1.0); - CLOCK_CYCLES(4); - return 0; -} - -static int opFLDL2T(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDL2T\n"); - x87_push(3.3219280948873623); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDL2E(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDL2E\n"); - x87_push(1.4426950408889634); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDPI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDPI\n"); - x87_push(3.141592653589793); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDEG2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDEG2\n"); - x87_push(0.3010299956639812); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDLN2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDLN2\n"); - x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES(8); - return 0; -} - -static int opFLDZ(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FLDZ\n"); - x87_push(0.0); - cpu_state.tag[cpu_state.TOP&7] = 1; - CLOCK_CYCLES(4); - return 0; -} - -static int opF2XM1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("F2XM1\n"); - ST(0) = pow(2.0, ST(0)) - 1.0; - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(200); - return 0; -} - -static int opFYL2X(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FYL2X\n"); - ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(250); - return 0; -} - -static int opFYL2XP1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FYL2XP1\n"); - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(250); - return 0; -} - -static int opFPTAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FPTAN\n"); - ST(0) = tan(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - x87_push(1.0); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(235); - return 0; -} - -static int opFPATAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FPATAN\n"); - ST(1) = atan2(ST(1), ST(0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; - x87_pop(); - CLOCK_CYCLES(250); - return 0; -} - -static int opFDECSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDECSTP\n"); - cpu_state.TOP = (cpu_state.TOP - 1) & 7; - CLOCK_CYCLES(4); - return 0; -} - -static int opFINCSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FDECSTP\n"); - cpu_state.TOP = (cpu_state.TOP + 1) & 7; - CLOCK_CYCLES(4); - return 0; -} - -static int opFPREM(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FPREM %f %f ", ST(0), ST(1)); - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - if (fplog) pclog("%f\n", ST(0)); - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); - return 0; -} -static int opFPREM1(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FPREM1 %f %f ", ST(0), ST(1)); - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - if (fplog) pclog("%f\n", ST(0)); - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); - return 0; -} - -static int opFSQRT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSQRT\n"); - ST(0) = sqrt(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(83); - return 0; -} - -static int opFSINCOS(uint32_t fetchdat) -{ - double td; - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSINCOS\n"); - td = ST(0); - ST(0) = sin(td); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - x87_push(cos(td)); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(330); - return 0; -} - -static int opFRNDINT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FRNDINT %g ", ST(0)); - ST(0) = (double)x87_fround(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - if (fplog) pclog("%g\n", ST(0)); - CLOCK_CYCLES(21); - return 0; -} - -static int opFSCALE(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSCALE\n"); - temp64 = (int64_t)ST(1); - ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - CLOCK_CYCLES(30); - return 0; -} - -static int opFSIN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FSIN\n"); - ST(0) = sin(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); - return 0; -} - -static int opFCOS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - if (fplog) pclog("FCOS\n"); - ST(0) = cos(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); - return 0; -} - - -static int FLDENV() -{ - FP_ENTER(); - if (fplog) pclog("FLDENV %08X:%08X\n", easeg, cpu_state.eaaddr); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - } - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - return cpu_state.abrt; -} - -static int opFLDENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - FLDENV(); - return cpu_state.abrt; -} -static int opFLDENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - FLDENV(); - return cpu_state.abrt; -} - -static int opFLDCW_a16(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); - 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); - CLOCK_CYCLES(4); - return 0; -} -static int opFLDCW_a32(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); - 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); - CLOCK_CYCLES(4); - return 0; -} - -static int FSTENV() -{ - FP_ENTER(); - if (fplog) pclog("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - break; - } - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - return cpu_state.abrt; -} - -static int opFSTENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - FSTENV(); - return cpu_state.abrt; -} -static int opFSTENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - FSTENV(); - return cpu_state.abrt; -} - -static int opFSTCW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); - return cpu_state.abrt; -} -static int opFSTCW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); - return cpu_state.abrt; -} - -#define opFCMOV(condition) \ - static int opFCMOV ## condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (fplog) pclog("FCMOV %f\n", ST(fetchdat & 7)); \ - 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; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES(4); \ - return 0; \ - } - -#define cond_U ( PF_SET()) -#define cond_NU (!PF_SET()) - -opFCMOV(B) -opFCMOV(E) -opFCMOV(BE) -opFCMOV(U) -opFCMOV(NB) -opFCMOV(NE) -opFCMOV(NBE) -opFCMOV(NU) diff --git a/src - Cópia/crcspeed/crc64speed.c b/src - Cópia/crcspeed/crc64speed.c deleted file mode 100644 index b1a7bbb94..000000000 --- a/src - Cópia/crcspeed/crc64speed.c +++ /dev/null @@ -1,275 +0,0 @@ -/* Copyright (c) 2014, Matt Stancliff - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ - -#include "crc64speed.h" - -/* If CRC64SPEED_DUAL is defined, we allow calls to - * both _little and _big CRC. - * By default, we only allow one endianness to be used - * and the first call to either _init function will set the - * lookup table endianness for the life of this module. - * We don't enable dual lookups by default because - * each 8x256 lookup table is 16k. */ -#ifndef CRC64SPEED_DUAL -static uint64_t crc64_table[8][256] = {{0}}; -static void *crc64_table_little = NULL, *crc64_table_big = NULL; -static const bool dual = false; -#else -static uint64_t crc64_table_little[8][256] = {{0}}; -static uint64_t crc64_table_big[8][256] = {{0}}; -static void *crc64_table = NULL; -static const bool dual = true; -#endif - -/* value of crc64_table[0][1], architecture dependent. */ -#define LITTLE1 UINT64_C(0x7ad870c830358979) -#define BIG1 UINT64_C(0x79893530c870d87a) - -/* Define CRC64SPEED_SAFE if you want runtime checks to stop - * CRCs from being calculated by uninitialized tables (and also stop tables - * from being initialized more than once). */ -#ifdef CRC64SPEED_SAFE -#define should_init(table, val) \ - do { \ - if ((table)[0][1] == (val)) \ - return false; \ - } while (0) -#define check_init(table, val) \ - do { \ - if ((table)[0][1] != (val)) \ - return false; \ - } while (0) -#else -#define should_init(a, b) -#define check_init(a, b) -#endif - -#define POLY UINT64_C(0xad93d23594c935a9) -/******************** BEGIN GENERATED PYCRC FUNCTIONS ********************/ -/** - * Generated on Sun Dec 21 14:14:07 2014, - * by pycrc v0.8.2, https://www.tty1.net/pycrc/ - * - * LICENSE ON GENERATED CODE: - * ========================== - * As of version 0.6, pycrc is released under the terms of the MIT licence. - * The code generated by pycrc is not considered a substantial portion of the - * software, therefore the author of pycrc will not claim any copyright on - * the generated code. - * ========================== - * - * CRC configuration: - * Width = 64 - * Poly = 0xad93d23594c935a9 - * XorIn = 0xffffffffffffffff - * ReflectIn = True - * XorOut = 0x0000000000000000 - * ReflectOut = True - * Algorithm = bit-by-bit-fast - * - * Modifications after generation (by matt): - * - included finalize step in-line with update for single-call generation - * - re-worked some inner variable architectures - * - adjusted function parameters to match expected prototypes. - *****************************************************************************/ - -/** - * Reflect all bits of a \a data word of \a data_len bytes. - * - * \param data The data word to be reflected. - * \param data_len The width of \a data expressed in number of bits. - * \return The reflected data. - *****************************************************************************/ -static inline uint_fast64_t crc_reflect(uint_fast64_t data, size_t data_len) { - uint_fast64_t ret = data & 0x01; - - for (size_t i = 1; i < data_len; i++) { - data >>= 1; - ret = (ret << 1) | (data & 0x01); - } - - return ret; -} - -/** - * Update the crc value with new data. - * - * \param crc The current crc value. - * \param data Pointer to a buffer of \a data_len bytes. - * \param data_len Number of bytes in the \a data buffer. - * \return The updated crc value. - ******************************************************************************/ -uint64_t crc64(uint_fast64_t crc, const void *in_data, const uint64_t len) { - const uint8_t *data = in_data; - bool bit; - - for (uint64_t offset = 0; offset < len; offset++) { - uint8_t c = data[offset]; - for (uint_fast8_t i = 0x01; i & 0xff; i <<= 1) { - bit = crc & 0x8000000000000000; - if (c & i) { - bit = !bit; - } - - crc <<= 1; - if (bit) { - crc ^= POLY; - } - } - - crc &= 0xffffffffffffffff; - } - - crc = crc & 0xffffffffffffffff; - return crc_reflect(crc, 64) ^ 0x0000000000000000; -} - -/******************** END GENERATED PYCRC FUNCTIONS ********************/ - -/* Only for testing; doesn't support DUAL */ -uint64_t crc64_lookup(uint64_t crc, const void *in_data, const uint64_t len) { - const uint8_t *data = in_data; - for (size_t i = 0; i < len; i++) { - crc = crc64_table[0][(uint8_t)crc ^ data[i]] ^ (crc >> 8); - } - - return crc; -} - -/* Returns false if CRC64SPEED_SAFE and table already initialized. */ -bool crc64speed_init(void) { -#ifndef CRC64SPEED_DUAL - should_init(crc64_table, LITTLE1); -#else - should_init(crc64_table_little, LITTLE1); -#endif - crcspeed64little_init(crc64, dual ? crc64_table_little : crc64_table); - return true; -} - -/* Returns false if CRC64SPEED_SAFE and table already initialized. */ -bool crc64speed_init_big(void) { -#ifndef CRC64SPEED_DUAL - should_init(crc64_table, BIG1); -#else - should_init(crc64_table_big, BIG1); -#endif - crcspeed64big_init(crc64, dual ? crc64_table_big : crc64_table); - return true; -} - -uint64_t crc64speed(uint64_t crc, const void *s, const uint64_t l) { -/* Quickly check if CRC table is initialized to little endian correctly. */ -#ifndef CRC64SPEED_DUAL - check_init(crc64_table, LITTLE1); -#else - check_init(crc64_table_little, LITTLE1); -#endif - return crcspeed64little(dual ? crc64_table_little : crc64_table, crc, - (void *)s, l); -} - -uint64_t crc64speed_big(uint64_t crc, const void *s, const uint64_t l) { -/* Quickly check if CRC table is initialized to big endian correctly. */ -#ifndef CRC64SPEED_DUAL - check_init(crc64_table, BIG1); -#else - check_init(crc64_table_big, BIG1); -#endif - return crcspeed64big(dual ? crc64_table_big : crc64_table, crc, (void *)s, - l); -} - -bool crc64speed_init_native(void) { - const uint64_t n = 1; - return *(char *)&n ? crc64speed_init() : crc64speed_init_big(); -} - -/* Iterate over table to fully load it into a cache near the CPU. */ -void crc64speed_cache_table(void) { - uint64_t m; - for (int i = 0; i < 8; ++i) { - for (int j = 0; j < 256; ++j) { -#ifndef CRC64SPEED_DUAL - m = crc64_table[i][j]; -#else - m = crc64_table_little[i][j]; - m += crc64_table_big[i][j]; -#endif - ++m; - } - } -} - -/* If you are on a platform where endianness can change at runtime, this - * will break unless you compile with CRC64SPEED_DUAL and manually run - * _init() and _init_big() instead of using _init_native() */ -uint64_t crc64speed_native(uint64_t crc, const void *s, const uint64_t l) { - const uint64_t n = 1; - return *(char *)&n ? crc64speed(crc, s, l) : crc64speed_big(crc, s, l); -} - -/* Test main */ -#if defined(REDIS_TEST) || defined(REDIS_TEST_MAIN) -#include - -#define UNUSED(x) (void)(x) -int crc64Test(int argc, char *argv[]) { - UNUSED(argc); - UNUSED(argv); - crc64speed_init(); - printf("[calcula]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", - (uint64_t)crc64(0, "123456789", 9)); - printf("[lookupt]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", - (uint64_t)crc64_lookup(0, "123456789", 9)); - printf("[64speed]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", - (uint64_t)crc64speed(0, "123456789", 9)); - char li[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed " - "do eiusmod tempor incididunt ut labore et dolore magna " - "aliqua. Ut enim ad minim veniam, quis nostrud exercitation " - "ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis " - "aute irure dolor in reprehenderit in voluptate velit esse " - "cillum dolore eu fugiat nulla pariatur. Excepteur sint " - "occaecat cupidatat non proident, sunt in culpa qui officia " - "deserunt mollit anim id est laborum."; - printf("[calcula]: c7794709e69683b3 == %016" PRIx64 "\n", - (uint64_t)crc64(0, li, sizeof(li))); - printf("[lookupt]: c7794709e69683b3 == %016" PRIx64 "\n", - (uint64_t)crc64_lookup(0, li, sizeof(li))); - printf("[64speed]: c7794709e69683b3 == %016" PRIx64 "\n", - (uint64_t)crc64speed(0, li, sizeof(li))); - return 0; -} - -#endif - -#ifdef REDIS_TEST_MAIN -int main(int argc, char *argv[]) { - return crc64Test(argc, argv); -} - -#endif diff --git a/src - Cópia/crcspeed/crc64speed.h b/src - Cópia/crcspeed/crc64speed.h deleted file mode 100644 index c72cd8f91..000000000 --- a/src - Cópia/crcspeed/crc64speed.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef CRC64SPEED_H -#define CRC64SPEED_H -#include "crcspeed.h" -#include "stdbool.h" - -/* Does not require init */ -uint64_t crc64(uint64_t crc, const void *data, const uint64_t len); -void crc64speed_cache_table(void); - -/* All other crc functions here require _init() before usage. */ -bool crc64speed_init(void); -uint64_t crc64_lookup(uint64_t crc, const void *in_data, const uint64_t len); -uint64_t crc64speed(uint64_t crc, const void *s, const uint64_t l); - -bool crc64speed_init_big(void); -uint64_t crc64speed_big(uint64_t crc, const void *s, const uint64_t l); - -bool crc64speed_init_native(void); -uint64_t crc64speed_native(uint64_t crc, const void *s, const uint64_t l); -#endif diff --git a/src - Cópia/crcspeed/crcspeed.c b/src - Cópia/crcspeed/crcspeed.c deleted file mode 100644 index d2d97a8c7..000000000 --- a/src - Cópia/crcspeed/crcspeed.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2013 Mark Adler - * Originally by: crc64.c Version 1.4 16 Dec 2013 Mark Adler - * Modifications by Matt Stancliff : - * - removed CRC64-specific behavior - * - added generation of lookup tables by parameters - * - removed inversion of CRC input/result - * - removed automatic initialization in favor of explicit initialization - - This software is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Mark Adler - madler@alumni.caltech.edu - */ - -#include "crcspeed.h" - -/* Fill in a CRC constants table. */ -void crcspeed64little_init(crcfn64 crcfn, uint64_t table[8][256]) { - uint64_t crc; - - /* generate CRCs for all single byte sequences */ - for (int n = 0; n < 256; n++) { - table[0][n] = crcfn(0, &n, 1); - } - - /* generate nested CRC table for future slice-by-8 lookup */ - for (int n = 0; n < 256; n++) { - crc = table[0][n]; - for (int k = 1; k < 8; k++) { - crc = table[0][crc & 0xff] ^ (crc >> 8); - table[k][n] = crc; - } - } -} - -void crcspeed16little_init(crcfn16 crcfn, uint16_t table[8][256]) { - uint16_t crc; - - /* generate CRCs for all single byte sequences */ - for (int n = 0; n < 256; n++) { - table[0][n] = crcfn(0, &n, 1); - } - - /* generate nested CRC table for future slice-by-8 lookup */ - for (int n = 0; n < 256; n++) { - crc = table[0][n]; - for (int k = 1; k < 8; k++) { - crc = table[0][(crc >> 8) & 0xff] ^ (crc << 8); - table[k][n] = crc; - } - } -} - -/* Reverse the bytes in a 64-bit word. */ -static inline uint64_t rev8(uint64_t a) { -#if defined(__GNUC__) || defined(__clang__) - return __builtin_bswap64(a); -#else - uint64_t m; - - m = UINT64_C(0xff00ff00ff00ff); - a = ((a >> 8) & m) | (a & m) << 8; - m = UINT64_C(0xffff0000ffff); - a = ((a >> 16) & m) | (a & m) << 16; - return a >> 32 | a << 32; -#endif -} - -/* This function is called once to initialize the CRC table for use on a - big-endian architecture. */ -void crcspeed64big_init(crcfn64 fn, uint64_t big_table[8][256]) { - /* Create the little endian table then reverse all the entires. */ - crcspeed64little_init(fn, big_table); - for (int k = 0; k < 8; k++) { - for (int n = 0; n < 256; n++) { - big_table[k][n] = rev8(big_table[k][n]); - } - } -} - -void crcspeed16big_init(crcfn16 fn, uint16_t big_table[8][256]) { - /* Create the little endian table then reverse all the entires. */ - crcspeed16little_init(fn, big_table); - for (int k = 0; k < 8; k++) { - for (int n = 0; n < 256; n++) { - big_table[k][n] = rev8(big_table[k][n]); - } - } -} - -/* Calculate a non-inverted CRC multiple bytes at a time on a little-endian - * architecture. If you need inverted CRC, invert *before* calling and invert - * *after* calling. - * 64 bit crc = process 8 bytes at once; - */ -uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc, - void *buf, size_t len) { - unsigned char *next = buf; - - /* process individual bytes until we reach an 8-byte aligned pointer */ - while (len && ((uintptr_t)next & 7) != 0) { - crc = little_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); - len--; - } - - /* fast middle processing, 8 bytes (aligned!) per loop */ - while (len >= 8) { - crc ^= *(uint64_t *)next; - crc = little_table[7][crc & 0xff] ^ - little_table[6][(crc >> 8) & 0xff] ^ - little_table[5][(crc >> 16) & 0xff] ^ - little_table[4][(crc >> 24) & 0xff] ^ - little_table[3][(crc >> 32) & 0xff] ^ - little_table[2][(crc >> 40) & 0xff] ^ - little_table[1][(crc >> 48) & 0xff] ^ - little_table[0][crc >> 56]; - next += 8; - len -= 8; - } - - /* process remaining bytes (can't be larger than 8) */ - while (len) { - crc = little_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); - len--; - } - - return crc; -} - -uint16_t crcspeed16little(uint16_t little_table[8][256], uint16_t crc, - void *buf, size_t len) { - unsigned char *next = buf; - - /* process individual bytes until we reach an 8-byte aligned pointer */ - while (len && ((uintptr_t)next & 7) != 0) { - crc = little_table[0][((crc >> 8) ^ *next++) & 0xff] ^ (crc << 8); - len--; - } - - /* fast middle processing, 8 bytes (aligned!) per loop */ - while (len >= 8) { - uint64_t n = *(uint64_t *)next; - crc = little_table[7][(n & 0xff) ^ ((crc >> 8) & 0xff)] ^ - little_table[6][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ - little_table[5][(n >> 16) & 0xff] ^ - little_table[4][(n >> 24) & 0xff] ^ - little_table[3][(n >> 32) & 0xff] ^ - little_table[2][(n >> 40) & 0xff] ^ - little_table[1][(n >> 48) & 0xff] ^ - little_table[0][n >> 56]; - next += 8; - len -= 8; - } - - /* process remaining bytes (can't be larger than 8) */ - while (len) { - crc = little_table[0][((crc >> 8) ^ *next++) & 0xff] ^ (crc << 8); - len--; - } - - return crc; -} - -/* Calculate a non-inverted CRC eight bytes at a time on a big-endian - * architecture. - */ -uint64_t crcspeed64big(uint64_t big_table[8][256], uint64_t crc, void *buf, - size_t len) { - unsigned char *next = buf; - - crc = rev8(crc); - while (len && ((uintptr_t)next & 7) != 0) { - crc = big_table[0][(crc >> 56) ^ *next++] ^ (crc << 8); - len--; - } - - while (len >= 8) { - crc ^= *(uint64_t *)next; - crc = big_table[0][crc & 0xff] ^ - big_table[1][(crc >> 8) & 0xff] ^ - big_table[2][(crc >> 16) & 0xff] ^ - big_table[3][(crc >> 24) & 0xff] ^ - big_table[4][(crc >> 32) & 0xff] ^ - big_table[5][(crc >> 40) & 0xff] ^ - big_table[6][(crc >> 48) & 0xff] ^ - big_table[7][crc >> 56]; - next += 8; - len -= 8; - } - - while (len) { - crc = big_table[0][(crc >> 56) ^ *next++] ^ (crc << 8); - len--; - } - - return rev8(crc); -} - -/* WARNING: Completely untested on big endian architecture. Possibly broken. */ -uint16_t crcspeed16big(uint16_t big_table[8][256], uint16_t crc_in, void *buf, - size_t len) { - unsigned char *next = buf; - uint64_t crc = crc_in; - - crc = rev8(crc); - while (len && ((uintptr_t)next & 7) != 0) { - crc = big_table[0][((crc >> (56 - 8)) ^ *next++) & 0xff] ^ (crc >> 8); - len--; - } - - while (len >= 8) { - uint64_t n = *(uint64_t *)next; - crc = big_table[0][(n & 0xff) ^ ((crc >> (56 - 8)) & 0xff)] ^ - big_table[1][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ - big_table[2][(n >> 16) & 0xff] ^ - big_table[3][(n >> 24) & 0xff] ^ - big_table[4][(n >> 32) & 0xff] ^ - big_table[5][(n >> 40) & 0xff] ^ - big_table[6][(n >> 48) & 0xff] ^ - big_table[7][n >> 56]; - next += 8; - len -= 8; - } - - while (len) { - crc = big_table[0][((crc >> (56 - 8)) ^ *next++) & 0xff] ^ (crc >> 8); - len--; - } - - return rev8(crc); -} - -/* Return the CRC of buf[0..len-1] with initial crc, processing eight bytes - at a time using passed-in lookup table. - This selects one of two routines depending on the endianess of - the architecture. */ -uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len) { - uint64_t n = 1; - - return *(char *)&n ? crcspeed64little(table, crc, buf, len) - : crcspeed64big(table, crc, buf, len); -} - -uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len) { - uint64_t n = 1; - - return *(char *)&n ? crcspeed16little(table, crc, buf, len) - : crcspeed16big(table, crc, buf, len); -} - -/* Initialize CRC lookup table in architecture-dependent manner. */ -void crcspeed64native_init(crcfn64 fn, uint64_t table[8][256]) { - uint64_t n = 1; - - *(char *)&n ? crcspeed64little_init(fn, table) - : crcspeed64big_init(fn, table); -} - -void crcspeed16native_init(crcfn16 fn, uint16_t table[8][256]) { - uint64_t n = 1; - - *(char *)&n ? crcspeed16little_init(fn, table) - : crcspeed16big_init(fn, table); -} diff --git a/src - Cópia/crcspeed/crcspeed.h b/src - Cópia/crcspeed/crcspeed.h deleted file mode 100644 index d7ee95ebb..000000000 --- a/src - Cópia/crcspeed/crcspeed.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014, Matt Stancliff - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ - -#ifndef CRCSPEED_H -#define CRCSPEED_H - -#include -#include - -typedef uint64_t (*crcfn64)(uint64_t, const void *, const uint64_t); -typedef uint16_t (*crcfn16)(uint16_t, const void *, const uint64_t); - -/* CRC-64 */ -void crcspeed64little_init(crcfn64 fn, uint64_t table[8][256]); -void crcspeed64big_init(crcfn64 fn, uint64_t table[8][256]); -void crcspeed64native_init(crcfn64 fn, uint64_t table[8][256]); - -uint64_t crcspeed64little(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); -uint64_t crcspeed64big(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); -uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); - -/* CRC-16 */ -void crcspeed16little_init(crcfn16 fn, uint16_t table[8][256]); -void crcspeed16big_init(crcfn16 fn, uint16_t table[8][256]); -void crcspeed16native_init(crcfn16 fn, uint16_t table[8][256]); - -uint16_t crcspeed16little(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); -uint16_t crcspeed16big(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); -uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); -#endif diff --git a/src - Cópia/device.c b/src - Cópia/device.c deleted file mode 100644 index 2d1cd5df9..000000000 --- a/src - Cópia/device.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * 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. - * - * Implementation of the generic device interface to handle - * all devices attached to the emulator. - * - * Version: @(#)device.c 1.0.8 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu/cpu.h" -#include "config.h" -#include "device.h" -#include "machine/machine.h" -#include "sound/sound.h" - - -#define DEVICE_MAX 256 /* max # of devices */ - - -static void *device_priv[DEVICE_MAX]; -static device_t *devices[DEVICE_MAX]; -static device_t *device_current; - - -#ifdef ENABLE_DEVICE_LOG -int device_do_log = ENABLE_DEVICE_LOG; -#endif - - -static void -device_log(const char *format, ...) -{ -#ifdef ENABLE_DEVICE_LOG - va_list ap; - - if (device_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -void -device_init(void) -{ - memset(devices, 0x00, sizeof(devices)); -} - - -void * -device_add(const device_t *d) -{ - void *priv = NULL; - int c; - - for (c=0; c<256; c++) { - if (devices[c] == (device_t *)d) { - device_log("DEVICE: device already exists!\n"); - return(NULL); - } - if (devices[c] == NULL) break; - } - if (c >= DEVICE_MAX) - fatal("DEVICE: too many devices\n"); - - device_current = (device_t *)d; - - devices[c] = (device_t *)d; - - if (d->init != NULL) { - priv = d->init(d); - if (priv == NULL) { - if (d->name) - device_log("DEVICE: device '%s' init failed\n", d->name); - else - device_log("DEVICE: device init failed\n"); - - device_priv[c] = NULL; - - return(NULL); - } - } - - device_priv[c] = priv; - - return(priv); -} - - -/* For devices that do not have an init function (internal video etc.) */ -void -device_add_ex(const device_t *d, void *priv) -{ - int c; - - for (c=0; c<256; c++) { - if (devices[c] == (device_t *)d) { - fatal("device_add: device already exists!\n"); - break; - } - if (devices[c] == NULL) break; - } - if (c >= DEVICE_MAX) - fatal("device_add: too many devices\n"); - - device_current = (device_t *)d; - - devices[c] = (device_t *)d; - device_priv[c] = priv; -} - - -void -device_close_all(void) -{ - int c; - - for (c=0; cclose != NULL) - devices[c]->close(device_priv[c]); - devices[c] = device_priv[c] = NULL; - } - } -} - - -void -device_reset_all(void) -{ - int c; - - for (c=0; creset != NULL) - devices[c]->reset(device_priv[c]); - } - } -} - - -/* Reset all attached PCI devices - needed for PCI turbo reset control. */ -void -device_reset_all_pci(void) -{ - int c; - - for (c=0; creset != NULL) && (devices[c]->flags & DEVICE_PCI)) - devices[c]->reset(device_priv[c]); - } - } -} - - -void * -device_get_priv(const device_t *d) -{ - int c; - - for (c=0; cflags & DEVICE_NOT_WORKING) return(0); -#endif - if (d->available != NULL) - return(d->available()); - - return(1); -} - - -void -device_speed_changed(void) -{ - int c; - - for (c=0; cspeed_changed != NULL) - devices[c]->speed_changed(device_priv[c]); - } - } - - sound_speed_changed(); -} - - -void -device_force_redraw(void) -{ - int c; - - for (c=0; cforce_redraw != NULL) - devices[c]->force_redraw(device_priv[c]); - } - } -} - - -char * -device_get_config_string(char *s) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_string((char *)device_current->name, s, (char *)c->default_string)); - - c++; - } - - return(NULL); -} - - -int -device_get_config_int(char *s) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_int((char *)device_current->name, s, c->default_int)); - - c++; - } - - return(0); -} - - -int -device_get_config_int_ex(char *s, int default_int) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_int((char *)device_current->name, s, default_int)); - - c++; - } - - return(default_int); -} - - -int -device_get_config_hex16(char *s) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_hex16((char *)device_current->name, s, c->default_int)); - - c++; - } - - return(0); -} - - -int -device_get_config_hex20(char *s) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_hex20((char *)device_current->name, s, c->default_int)); - - c++; - } - - return(0); -} - - -int -device_get_config_mac(char *s, int default_int) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_mac((char *)device_current->name, s, default_int)); - - c++; - } - - return(default_int); -} - - -void -device_set_config_int(char *s, int val) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) { - config_set_int((char *)device_current->name, s, val); - break; - } - - c++; - } -} - - -void -device_set_config_hex16(char *s, int val) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) { - config_set_hex16((char *)device_current->name, s, val); - break; - } - - c++; - } -} - - -void -device_set_config_hex20(char *s, int val) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) { - config_set_hex20((char *)device_current->name, s, val); - break; - } - - c++; - } -} - - -void -device_set_config_mac(char *s, int val) -{ - const device_config_t *c = device_current->config; - - while (c && c->type != -1) { - if (! strcmp(s, c->name)) { - config_set_mac((char *)device_current->name, s, val); - break; - } - - c++; - } -} - - -int -device_is_valid(const device_t *device, int mflags) -{ - if (device == NULL) return(1); - - if ((device->flags & DEVICE_AT) && !(mflags & MACHINE_AT)) return(0); - - if ((device->flags & DEVICE_CBUS) && !(mflags & MACHINE_CBUS)) return(0); - - if ((device->flags & DEVICE_ISA) && !(mflags & MACHINE_ISA)) return(0); - - if ((device->flags & DEVICE_MCA) && !(mflags & MACHINE_MCA)) return(0); - - if ((device->flags & DEVICE_EISA) && !(mflags & MACHINE_EISA)) return(0); - - if ((device->flags & DEVICE_VLB) && !(mflags & MACHINE_VLB)) return(0); - - if ((device->flags & DEVICE_PCI) && !(mflags & MACHINE_PCI)) return(0); - - if ((device->flags & DEVICE_PS2) && !(mflags & MACHINE_HDC_PS2)) return(0); - if ((device->flags & DEVICE_AGP) && !(mflags & MACHINE_AGP)) return(0); - - return(1); -} - - -int -machine_get_config_int(char *s) -{ - const device_t *d = machine_getdevice(machine); - const device_config_t *c; - - if (d == NULL) return(0); - - c = d->config; - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_int((char *)d->name, s, c->default_int)); - - c++; - } - - return(0); -} - - -char * -machine_get_config_string(char *s) -{ - const device_t *d = machine_getdevice(machine); - const device_config_t *c; - - if (d == NULL) return(0); - - c = d->config; - while (c && c->type != -1) { - if (! strcmp(s, c->name)) - return(config_get_string((char *)d->name, s, (char *)c->default_string)); - - c++; - } - - return(NULL); -} diff --git a/src - Cópia/device.h b/src - Cópia/device.h deleted file mode 100644 index 6256a3ea5..000000000 --- a/src - Cópia/device.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 device handler. - * - * Version: @(#)device.h 1.0.5 2018/04/26 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_DEVICE_H -# define EMU_DEVICE_H - - -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_MIDI 4 -#define CONFIG_FNAME 5 -#define CONFIG_SPINNER 6 -#define CONFIG_HEX16 7 -#define CONFIG_HEX20 8 -#define CONFIG_MAC 9 - - -enum { - DEVICE_NOT_WORKING = 1, /* does not currently work correctly and will be disabled in a release build*/ - DEVICE_AT = 2, /* requires an AT-compatible system */ - DEVICE_PS2 = 4, /* requires a PS/1 or PS/2 system */ - DEVICE_ISA = 8, /* requires the ISA bus */ - DEVICE_CBUS = 0x10, /* requires the C-BUS bus */ - DEVICE_MCA = 0x20, /* requires the MCA bus */ - DEVICE_EISA = 0x40, /* requires the EISA bus */ - DEVICE_VLB = 0x80, /* requires the PCI bus */ - DEVICE_PCI = 0x100, /* requires the VLB bus */ - DEVICE_AGP = 0x200 /* requires the AGP bus */ -}; - - -typedef struct { - const char *description; - int value; -} device_config_selection_t; - -typedef struct { - const char *description; - const char *extensions[5]; -} device_config_file_filter_t; - -typedef struct { - int min; - int max; - int step; -} device_config_spinner_t; - -typedef struct { - const char *name; - const char *description; - int type; - const char *default_string; - int default_int; - device_config_selection_t selection[16]; - device_config_file_filter_t file_filter[16]; - device_config_spinner_t spinner; -} device_config_t; - -typedef struct _device_ { - const char *name; - uint32_t flags; /* system flags */ - uint32_t local; /* flags local to device */ - - void *(*init)(const struct _device_ *); - void (*close)(void *p); - void (*reset)(void *p); - int (*available)(/*void*/); - void (*speed_changed)(void *p); - void (*force_redraw)(void *p); - - const device_config_t *config; -} device_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -extern void device_init(void); -extern void *device_add(const device_t *d); -extern void device_add_ex(const device_t *d, void *priv); -extern void device_close_all(void); -extern void device_reset_all(void); -extern void device_reset_all_pci(void); -extern void *device_get_priv(const device_t *d); -extern int device_available(const device_t *d); -extern void device_speed_changed(void); -extern void device_force_redraw(void); - -extern int device_get_config_int(char *name); -extern int device_get_config_int_ex(char *s, int default_int); -extern int device_get_config_hex16(char *name); -extern int device_get_config_hex20(char *name); -extern int device_get_config_mac(char *name, int default_int); -extern void device_set_config_int(char *s, int val); -extern void device_set_config_hex16(char *s, int val); -extern void device_set_config_hex20(char *s, int val); -extern void device_set_config_mac(char *s, int val); -extern char *device_get_config_string(char *name); -extern int device_is_valid(const device_t *device, int machine_flags); - -extern int machine_get_config_int(char *s); -extern char *machine_get_config_string(char *s); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_DEVICE_H*/ diff --git a/src - Cópia/disk/hdc.c b/src - Cópia/disk/hdc.c deleted file mode 100644 index 37d036e99..000000000 --- a/src - Cópia/disk/hdc.c +++ /dev/null @@ -1,261 +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. - * - * Common code to handle all sorts of disk controllers. - * - * Version: @(#)hdc.c 1.0.15 2018/04/29 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../machine/machine.h" -#include "../device.h" -#include "hdc.h" -#include "hdc_ide.h" -#include "hdd.h" - - -char *hdc_name; /* configured HDC name */ -int hdc_current; - - -#ifdef ENABLE_HDC_LOG -int hdc_do_log = ENABLE_HDC_LOG; -#endif - - -static void -hdc_log(const char *fmt, ...) -{ -#ifdef ENABLE_HDC_LOG - va_list ap; - - if (hdc_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void * -null_init(const device_t *info) -{ - return(NULL); -} - - -static void -null_close(void *priv) -{ -} - - -static const device_t null_device = { - "Null HDC", 0, 0, - null_init, null_close, NULL, - NULL, NULL, NULL, NULL -}; - - -static void * -inthdc_init(const device_t *info) -{ - return(NULL); -} - - -static void -inthdc_close(void *priv) -{ -} - - -static const device_t inthdc_device = { - "Internal Controller", 0, 0, - inthdc_init, inthdc_close, NULL, - NULL, NULL, NULL, NULL -}; - - -static const struct { - const char *name; - const char *internal_name; - const device_t *device; -} controllers[] = { - { "None", "none", - &null_device }, - - { "Internal Controller", "internal", - &inthdc_device }, - - { "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xt", - &mfm_xt_xebec_device }, - - { "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x", - &mfm_xt_dtc5150x_device }, - - { "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at", - &mfm_at_wd1003_device }, - - { "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at", - &esdi_at_wd1007vse1_device }, - - { "[ISA] [IDE] PC/AT IDE Adapter", "ide_isa", - &ide_isa_device }, - - { "[ISA] [IDE] PC/AT IDE Adapter (Dual-Channel)", "ide_isa_2ch", - &ide_isa_2ch_device }, - - { "[ISA] [IDE] PC/AT XTIDE", "xtide_at", - &xtide_at_device }, - - { "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2", - &xtide_at_ps2_device }, - - { "[ISA] [IDE] WDXT-150 IDE (XTA) Adapter", "xta_wdxt150", - &xta_wdxt150_device }, - - { "[ISA] [XT IDE] Acculogic XT IDE", "xtide_acculogic", - &xtide_acculogic_device }, - - { "[ISA] [XT IDE] PC/XT XTIDE", "xtide", - &xtide_device }, - - { "[MCA] [ESDI] IBM PS/2 ESDI Fixed Disk Adapter","esdi_mca", - &esdi_ps2_device }, - - { "[PCI] [IDE] PCI IDE Adapter", "ide_pci", - &ide_pci_device }, - - { "[PCI] [IDE] PCI IDE Adapter (Dual-Channel)", "ide_pci_2ch", - &ide_pci_2ch_device }, - - { "[VLB] [IDE] PC/AT IDE Adapter", "vlb_isa", - &ide_vlb_device }, - - { "[VLB] [IDE] PC/AT IDE Adapter (Dual-Channel)", "vlb_isa_2ch", - &ide_vlb_2ch_device }, - - { "", "", - NULL } -}; - - -/* Initialize the 'hdc_current' value based on configured HDC name. */ -void -hdc_init(char *name) -{ - int c; - - hdc_log("HDC: initializing..\n"); - - for (c = 0; controllers[c].device; c++) { - if (! strcmp(name, (char *) controllers[c].internal_name)) { - hdc_current = c; - break; - } - } - - /* Zero all the hard disk image arrays. */ - hdd_image_init(); -} - - -/* Reset the HDC, whichever one that is. */ -void -hdc_reset(void) -{ - hdc_log("HDC: reset(current=%d, internal=%d)\n", - hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0); - - /* If we have a valid controller, add its device. */ - if (hdc_current > 1) - device_add(controllers[hdc_current].device); - - /* Now, add the tertiary and/or quaternary IDE controllers. */ - if (ide_ter_enabled) - device_add(&ide_ter_device); - if (ide_qua_enabled) - device_add(&ide_qua_device); -} - - -char * -hdc_get_name(int hdc) -{ - return((char *) controllers[hdc].name); -} - - -char * -hdc_get_internal_name(int hdc) -{ - return((char *) controllers[hdc].internal_name); -} - - -int -hdc_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen((char *) controllers[c].internal_name)) - { - if (!strcmp((char *) controllers[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - - -const device_t * -hdc_get_device(int hdc) -{ - return(controllers[hdc].device); -} - - -int -hdc_has_config(int hdc) -{ - const device_t *dev = hdc_get_device(hdc); - - if (dev == NULL) return(0); - - if (dev->config == NULL) return(0); - - return(1); -} - - -int -hdc_get_flags(int hdc) -{ - return(controllers[hdc].device->flags); -} - - -int -hdc_available(int hdc) -{ - return(device_available(controllers[hdc].device)); -} diff --git a/src - Cópia/disk/hdc.h b/src - Cópia/disk/hdc.h deleted file mode 100644 index 89e34a1d9..000000000 --- a/src - Cópia/disk/hdc.h +++ /dev/null @@ -1,74 +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. - * - * Definitions for the common disk controller handler. - * - * Version: @(#)hdc.h 1.0.8 2018/04/05 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_HDC_H -# define EMU_HDC_H - - -#define MFM_NUM 2 /* 2 drives per controller supported */ -#define ESDI_NUM 2 /* 2 drives per controller supported */ -#define XTA_NUM 2 /* 2 drives per controller supported */ -#define IDE_NUM 8 -#define SCSI_NUM 16 /* theoretically the controller can have at - * least 7 devices, with each device being - * able to support 8 units, but hey... */ - -extern char *hdc_name; -extern int hdc_current; - - -extern const device_t mfm_xt_xebec_device; /* mfm_xt_xebec */ -extern const device_t mfm_xt_dtc5150x_device; /* mfm_xt_dtc */ -extern const device_t mfm_at_wd1003_device; /* mfm_at_wd1003 */ - -extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */ -extern const device_t esdi_ps2_device; /* esdi_mca */ - -extern const device_t ide_isa_device; /* isa_ide */ -extern const device_t ide_isa_2ch_device; /* isa_ide_2ch */ -extern const device_t ide_isa_2ch_opt_device; /* isa_ide_2ch_opt */ -extern const device_t ide_vlb_device; /* vlb_ide */ -extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ -extern const device_t ide_pci_device; /* pci_ide */ -extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ - -extern const device_t ide_ter_device; -extern const device_t ide_qua_device; - -extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ -extern const device_t xta_hd20_device; /* EuroPC internal */ - -extern const device_t xtide_device; /* xtide_xt */ -extern const device_t xtide_at_device; /* xtide_at */ -extern const device_t xtide_acculogic_device; /* xtide_ps2 */ -extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ - - -extern void hdc_init(char *name); -extern void hdc_reset(void); - -extern char *hdc_get_name(int hdc); -extern char *hdc_get_internal_name(int hdc); -extern int hdc_get_from_internal_name(char *s); -extern int hdc_has_config(int hdc); -extern const device_t *hdc_get_device(int hdc); -extern int hdc_get_flags(int hdc); -extern int hdc_available(int hdc); - - -#endif /*EMU_HDC_H*/ diff --git a/src - Cópia/disk/hdc_esdi_at.c b/src - Cópia/disk/hdc_esdi_at.c deleted file mode 100644 index 1a4539388..000000000 --- a/src - Cópia/disk/hdc_esdi_at.c +++ /dev/null @@ -1,856 +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. - * - * Driver for the ESDI controller (WD1007-vse1) for PC/AT. - * - * Version: @(#)hdc_esdi_at.c 1.0.13 2018/05/02 - * - * 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. - */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#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 "hdc.h" -#include "hdd.h" - - -#define HDC_TIME (TIMER_USEC*10LL) -#define BIOS_FILE L"roms/hdd/esdi_at/62-000279-061.bin" - -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_CORRECTED_DATA 0x04 -#define STAT_DRQ 0x08 /* Data request */ -#define STAT_DSC 0x10 -#define STAT_SEEK_COMPLETE 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 - -#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ -#define ERR_TR000 0x02 /* track 0 not found */ -#define ERR_ABRT 0x04 /* command aborted */ -#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ -#define ERR_DATA_CRC 0x40 /* data CRC error */ -#define ERR_BAD_BLOCK 0x80 /* bad block detected */ - -#define CMD_NOP 0x00 -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 -#define CMD_READ_PARAMETERS 0xec - - -typedef struct { - int cfg_spt; - int cfg_hpc; - int current_cylinder; - int real_spt; - int real_hpc; - int real_tracks; - int present; - int hdd_num; -} drive_t; - -typedef struct { - uint8_t status; - uint8_t error; - int secount,sector,cylinder,head,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - - int drive_sel; - int reset; - uint16_t buffer[256]; - int irqstat; - - int64_t callback; - - drive_t drives[2]; - - rom_t bios_rom; -} esdi_t; - - -#ifdef ENABLE_ESDI_AT_LOG -int esdi_at_do_log = ENABLE_ESDI_AT_LOG; -#endif - - -static void -esdi_at_log(const char *fmt, ...) -{ -#ifdef ENABLE_ESDI_AT_LOG - va_list ap; - - if (esdi_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static inline void -irq_raise(esdi_t *esdi) -{ - if (!(esdi->fdisk & 2)) - picint(1 << 14); - - esdi->irqstat = 1; -} - - -static inline void -irq_lower(esdi_t *esdi) -{ - if (esdi->irqstat) { - if (!(esdi->fdisk & 2)) - picintc(1 << 14); - - esdi->irqstat = 0; - } -} - - -/* Return the sector offset for the current register values. */ -static int -get_sector(esdi_t *esdi, off64_t *addr) -{ - drive_t *drive = &esdi->drives[esdi->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; - int c, h, s; - - if (esdi->head > heads) { - esdi_at_log("esdi_get_sector: past end of configured heads\n"); - return(1); - } - - if (esdi->sector >= sectors+1) { - esdi_at_log("esdi_get_sector: past end of configured sectors\n"); - return(1); - } - - if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) { - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (esdi->sector - 1); - } else { - /* - * When performing translation, the firmware seems to leave 1 - * sector per track inaccessible (spare sector) - */ - - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (esdi->sector - 1); - - s = *addr % (drive->real_spt - 1); - h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; - c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; - - *addr = ((((off64_t)c * drive->real_hpc) + h) * drive->real_spt) + s; - } - - return(0); -} - - -/* Move to the next sector using CHS addressing. */ -static void -next_sector(esdi_t *esdi) -{ - drive_t *drive = &esdi->drives[esdi->drive_sel]; - - esdi->sector++; - if (esdi->sector == (drive->cfg_spt + 1)) { - esdi->sector = 1; - if (++esdi->head == drive->cfg_hpc) { - esdi->head = 0; - esdi->cylinder++; - if (drive->current_cylinder < drive->real_tracks) - drive->current_cylinder++; - } - } -} - - -static void -esdi_writew(uint16_t port, uint16_t val, void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - - esdi->buffer[esdi->pos >> 1] = val; - esdi->pos += 2; - - if (esdi->pos >= 512) { - esdi->pos = 0; - esdi->status = STAT_BUSY; - timer_clock(); - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - esdi->callback = (3125LL * TIMER_USEC) / 8LL; - timer_update_outstanding(); - } -} - - -static void -esdi_write(uint16_t port, uint8_t val, void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - - esdi_at_log("WD1007 write(%04x, %02x)\n", port, val); - - switch (port) { - case 0x1f0: /* data */ - esdi_writew(port, val | (val << 8), priv); - return; - - case 0x1f1: /* write precompensation */ - esdi->cylprecomp = val; - return; - - case 0x1f2: /* sector count */ - esdi->secount = val; - return; - - case 0x1f3: /* sector */ - esdi->sector = val; - return; - - case 0x1f4: /* cylinder low */ - esdi->cylinder = (esdi->cylinder & 0xFF00) | val; - return; - - case 0x1f5: /* cylinder high */ - esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); - return; - - case 0x1f6: /* drive/Head */ - esdi->head = val & 0xF; - esdi->drive_sel = (val & 0x10) ? 1 : 0; - if (esdi->drives[esdi->drive_sel].present) { - esdi->status = STAT_READY|STAT_DSC; - } else { - esdi->status = 0; - } - return; - - case 0x1f7: /* command register */ - irq_lower(esdi); - esdi->command = val; - esdi->error = 0; - - esdi_at_log("WD1007: command %02x\n", val & 0xf0); - - switch (val & 0xf0) { - case CMD_RESTORE: - esdi->command &= ~0x0f; /*mask off step rate*/ - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_SEEK: - esdi->command &= ~0x0f; /*mask off step rate*/ - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - default: - switch (val) { - case CMD_NOP: - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_READ: - case CMD_READ+1: - case CMD_READ+2: - case CMD_READ+3: - esdi->command &= ~0x03; - if (val & 0x02) - fatal("Read with ECC\n"); - - case 0xa0: - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_WRITE: - case CMD_WRITE+1: - case CMD_WRITE+2: - case CMD_WRITE+3: - esdi->command &= ~0x03; - if (val & 0x02) - fatal("Write with ECC\n"); - esdi->status = STAT_DRQ | STAT_DSC; - esdi->pos = 0; - break; - - case CMD_VERIFY: - case CMD_VERIFY+1: - esdi->command &= ~0x01; - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_FORMAT: - esdi->status = STAT_DRQ; - esdi->pos = 0; - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 30LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case 0xe0: /*???*/ - case CMD_READ_PARAMETERS: - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - default: - esdi_at_log("WD1007: bad command %02X\n", val); - case 0xe8: /*???*/ - esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - } - } - break; - - case 0x3f6: /* Device control */ - if ((esdi->fdisk & 0x04) && !(val & 0x04)) { - timer_clock(); - esdi->callback = 500LL*HDC_TIME; - timer_update_outstanding(); - esdi->reset = 1; - esdi->status = STAT_BUSY; - } - - if (val & 0x04) { - /*Drive held in reset*/ - timer_clock(); - esdi->callback = 0LL; - timer_update_outstanding(); - esdi->status = STAT_BUSY; - } - esdi->fdisk = val; - /* Lower IRQ on IRQ disable. */ - if ((val & 2) && !(esdi->fdisk & 0x02)) - picintc(1 << 14); - break; - } -} - - -static uint16_t -esdi_readw(uint16_t port, void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - uint16_t temp; - - temp = esdi->buffer[esdi->pos >> 1]; - esdi->pos += 2; - - if (esdi->pos >= 512) { - esdi->pos=0; - esdi->status = STAT_READY | STAT_DSC; - if (esdi->command == CMD_READ || esdi->command == 0xa0) { - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - next_sector(esdi); - esdi->status = STAT_BUSY; - timer_clock(); - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - esdi->callback = (3125LL * TIMER_USEC) / 8LL; - timer_update_outstanding(); - } else { - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - } - } - } - - return(temp); -} - - -static uint8_t -esdi_read(uint16_t port, void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - uint8_t temp = 0xff; - - switch (port) { - case 0x1f0: /* data */ - temp = esdi_readw(port, esdi) & 0xff; - break; - - case 0x1f1: /* error */ - temp = esdi->error; - break; - - case 0x1f2: /* sector count */ - temp = esdi->secount; - break; - - case 0x1f3: /* sector */ - temp = esdi->sector; - break; - - case 0x1f4: /* cylinder low */ - temp = (uint8_t)(esdi->cylinder&0xff); - break; - - case 0x1f5: /* cylinder high */ - temp = (uint8_t)(esdi->cylinder>>8); - break; - - case 0x1f6: /* drive/Head */ - temp = (uint8_t)(0xa0|esdi->head|(esdi->drive_sel?0x10:0)); - break; - - case 0x1f7: /* status */ - irq_lower(esdi); - temp = esdi->status; - break; - } - - esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp); - - return(temp); -} - - -static void -esdi_callback(void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - drive_t *drive = &esdi->drives[esdi->drive_sel]; - off64_t addr; - - esdi->callback = 0LL; - if (esdi->reset) { - esdi->status = STAT_READY|STAT_DSC; - esdi->error = 1; - esdi->secount = 1; - esdi->sector = 1; - esdi->head = 0; - esdi->cylinder = 0; - esdi->reset = 0; - - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - - return; - } - - esdi_at_log("WD1007: command %02x\n", esdi->command); - - switch (esdi->command) { - case CMD_RESTORE: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else { - drive->current_cylinder = 0; - esdi->status = STAT_READY|STAT_DSC; - } - irq_raise(esdi); - break; - - case CMD_SEEK: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else { - esdi->status = STAT_READY|STAT_DSC; - } - irq_raise(esdi); - break; - - case CMD_READ: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; - - case CMD_WRITE: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } - - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - irq_raise(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - esdi->pos = 0; - next_sector(esdi); - } else { - esdi->status = STAT_READY|STAT_DSC; - } - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; - - case CMD_VERIFY: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - next_sector(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - esdi->callback = 6LL*HDC_TIME; - else { - esdi->pos = 0; - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - } - break; - - case CMD_FORMAT: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } - - hdd_image_zero(drive->hdd_num, addr, esdi->secount); - - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; - - case CMD_DIAGNOSE: - esdi->error = 1; /*no error detected*/ - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - if (drive->present == 0) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - drive->cfg_spt = esdi->secount; - drive->cfg_hpc = esdi->head+1; - - esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); - - if (! esdi->secount) - fatal("WD1007: secount=0\n"); - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - break; - - case CMD_NOP: - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - - case 0xe0: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - switch (esdi->cylinder >> 8) { - case 0x31: - esdi->cylinder = drive->real_tracks; - break; - - case 0x33: - esdi->cylinder = drive->real_hpc; - break; - - case 0x35: - esdi->cylinder = 0x200; - break; - - case 0x36: - esdi->cylinder = drive->real_spt; - break; - - default: - esdi_at_log("WD1007: bad read config %02x\n", - esdi->cylinder >> 8); - } - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - break; - - case 0xa0: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else { - memset(esdi->buffer, 0x00, 512); - memset(&esdi->buffer[3], 0xff, 512-6); - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - } - irq_raise(esdi); - break; - - case CMD_READ_PARAMETERS: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - memset(esdi->buffer, 0x00, 512); - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->real_hpc; /* number of heads */ - esdi->buffer[4] = 600; /* number of unformatted bytes/track */ - esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */ - esdi->buffer[6] = drive->real_spt; /* number of sectors */ - esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - esdi->buffer[8] = 0; /* minimum bytes in postamble */ - esdi->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ - esdi->buffer[27] = 'W' | ('D' << 8); - esdi->buffer[28] = '1' | ('0' << 8); - esdi->buffer[29] = '0' | ('7' << 8); - esdi->buffer[30] = 'V' | ('-' << 8); - esdi->buffer[31] = 'S' | ('E' << 8); - esdi->buffer[32] = '1'; - esdi->buffer[47] = 0; /* sectors per interrupt */ - esdi->buffer[48] = 0; /* can use double word read/write? */ - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); - break; - - default: - esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command); - /*FALLTHROUGH*/ - - case 0xe8: - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } - - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); -} - - -static void -loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn) -{ - drive_t *drive = &esdi->drives[hdd_num]; - - if (! hdd_image_load(d)) { - esdi_at_log("WD1007: drive %d not present!\n", d); - drive->present = 0; - return; - } - - drive->cfg_spt = drive->real_spt = hdd[d].spt; - drive->cfg_hpc = drive->real_hpc = hdd[d].hpc; - drive->real_tracks = hdd[d].tracks; - drive->hdd_num = d; - drive->present = 1; -} - - -static void * -wd1007vse1_init(const device_t *info) -{ - int c, d; - - esdi_t *esdi = malloc(sizeof(esdi_t)); - memset(esdi, 0x00, sizeof(esdi_t)); - - c = 0; - for (d=0; d= ESDI_NUM) break; - } - } - - esdi->status = STAT_READY|STAT_DSC; - esdi->error = 1; - - rom_init(&esdi->bios_rom, - BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x01f0, 1, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, esdi); - io_sethandler(0x01f1, 7, - esdi_read, NULL, NULL, - esdi_write, NULL, NULL, esdi); - io_sethandler(0x03f6, 1, NULL, NULL, NULL, - esdi_write, NULL, NULL, esdi); - - timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); - - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); - - return(esdi); -} - - -static void -wd1007vse1_close(void *priv) -{ - esdi_t *esdi = (esdi_t *)priv; - drive_t *drive; - int d; - - for (d=0; d<2; d++) { - drive = &esdi->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - free(esdi); - - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); -} - - -static int -wd1007vse1_available(void) -{ - return(rom_present(BIOS_FILE)); -} - - -const device_t esdi_at_wd1007vse1_device = { - "Western Digital WD1007V-SE1 (ESDI)", - DEVICE_ISA | DEVICE_AT, - 0, - wd1007vse1_init, wd1007vse1_close, NULL, - wd1007vse1_available, - NULL, NULL, - NULL -}; diff --git a/src - Cópia/disk/hdc_esdi_mca.c b/src - Cópia/disk/hdc_esdi_mca.c deleted file mode 100644 index f92301415..000000000 --- a/src - Cópia/disk/hdc_esdi_mca.c +++ /dev/null @@ -1,1107 +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. - * - * Driver for IBM PS/2 ESDI disk controller (MCA) - * - * AdapterID: 0xDDFF - * AdapterName: "ESDI Fixed Disk Controller" - * NumBytes 2 - * I/O base: 0x3510-0x3517 - * IRQ: 14 - * - * Primary Board pos[0]=XXxx xx0X 0x3510 - * Secondary Board pos[0]=XXxx xx1X 0x3518 - * - * DMA 5 pos[0]=XX01 01XX - * DMA 6 pos[0]=XX01 10XX - * DMA 7 pos[0]=XX01 11XX - * DMA 0 pos[0]=XX00 00XX - * DMA 1 pos[0]=XX00 01XX - * DMA 3 pos[0]=XX00 11XX - * DMA 4 pos[0]=XX01 00XX - * - * MCA Fairness ON pos[0]=X1XX XXXX - * MCA Fairness OFF pos[0]=X0XX XXXX - * - * ROM C000 pos[1]=XXXX 0000 - * ROM C400 pos[1]=XXXX 0001 - * ROM C800 pos[1]=XXXX 0010 - * ROM CC00 pos[1]=XXXX 0011 - * ROM D000 pos[1]=XXXX 0100 - * ROM D400 pos[1]=XXXX 0101 - * ROM D800 pos[1]=XXXX 0110 - * ROM DC00 pos[1]=XXXX 0111 - * ROM Disabled pos[1]=XXXX 1XXX - * - * DMA Burst 8 pos[1]=XX01 XXXX - * DMA Burst 16 pos[1]=XX10 XXXX - * DMA Burst 24 pos[1]=XX11 XXXX - * DMA Disabled pos[1]=XX00 XXXX - * - * Although this is an MCA device, meaning that the system - * software will take care of device configuration, the ESDI - * controller is a somewhat weird one.. it's I/O base address - * and IRQ channel are locked to 0x3510 and IRQ14, possibly - * to enforce compatibility with the IBM MFM disk controller - * that was also in use on these systems. All other settings, - * however, are auto-configured by the system software as - * shown above. - * - * Version: @(#)hdc_esdi_mca.c 1.0.13 2018/04/29 - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#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 "hdc.h" -#include "hdd.h" - - -/* These are hardwired. */ -#define ESDI_IOADDR_PRI 0x3510 -#define ESDI_IOADDR_SEC 0x3518 -#define ESDI_IRQCHAN 14 - -#define BIOS_FILE_L L"roms/hdd/esdi/90x8969.bin" -#define BIOS_FILE_H L"roms/hdd/esdi/90x8970.bin" - - -#define ESDI_TIME (200LL*TIMER_USEC) -#define CMD_ADAPTER 0 - - -typedef struct esdi_drive { - int spt, hpc; - int tracks; - int sectors; - int present; - int hdd_num; -} drive_t; - -typedef struct esdi { - int8_t dma; - - uint32_t bios; - rom_t bios_rom; - - uint8_t basic_ctrl; - uint8_t status; - uint8_t irq_status; - int irq_in_progress; - int cmd_req_in_progress; - int cmd_pos; - uint16_t cmd_data[4]; - int cmd_dev; - - int status_pos, - status_len; - - uint16_t status_data[256]; - - int data_pos; - uint16_t data[256]; - - uint16_t sector_buffer[256][256]; - - int sector_pos; - int sector_count; - - int command; - int cmd_state; - - int in_reset; - int64_t callback; - - uint32_t rba; - - struct { - int req_in_progress; - } cmds[3]; - - drive_t drives[2]; - - uint8_t pos_regs[8]; -} esdi_t; - -#define STATUS_DMA_ENA (1 << 7) -#define STATUS_IRQ_PENDING (1 << 6) -#define STATUS_CMD_IN_PROGRESS (1 << 5) -#define STATUS_BUSY (1 << 4) -#define STATUS_STATUS_OUT_FULL (1 << 3) -#define STATUS_CMD_IR_FULL (1 << 2) -#define STATUS_TRANSFER_REQ (1 << 1) -#define STATUS_IRQ (1 << 0) - -#define CTRL_RESET (1 << 7) -#define CTRL_DMA_ENA (1 << 1) -#define CTRL_IRQ_ENA (1 << 0) - -#define IRQ_HOST_ADAPTER (7 << 5) -#define IRQ_DEVICE_0 (0 << 5) -#define IRQ_CMD_COMPLETE_SUCCESS 0x1 -#define IRQ_RESET_COMPLETE 0xa -#define IRQ_DATA_TRANSFER_READY 0xb -#define IRQ_CMD_COMPLETE_FAILURE 0xc - -#define ATTN_DEVICE_SEL (7 << 5) -#define ATTN_HOST_ADAPTER (7 << 5) -#define ATTN_DEVICE_0 (0 << 5) -#define ATTN_DEVICE_1 (1 << 5) -#define ATTN_REQ_MASK 0x0f -#define ATTN_CMD_REQ 1 -#define ATTN_EOI 2 -#define ATTN_RESET 4 - -#define CMD_SIZE_4 (1 << 14) - -#define CMD_DEVICE_SEL (7 << 5) -#define CMD_MASK 0x1f -#define CMD_READ 0x01 -#define CMD_WRITE 0x02 -#define CMD_READ_VERIFY 0x03 -#define CMD_WRITE_VERIFY 0x04 -#define CMD_SEEK 0x05 -#define CMD_GET_DEV_STATUS 0x08 -#define CMD_GET_DEV_CONFIG 0x09 -#define CMD_GET_POS_INFO 0x0a - -#define STATUS_LEN(x) ((x) << 8) -#define STATUS_DEVICE(x) ((x) << 5) -#define STATUS_DEVICE_HOST_ADAPTER (7 << 5) - - -#ifdef ENABLE_ESDI_MCA_LOG -int esdi_mca_do_log = ENABLE_ESDI_MCA_LOG; -#endif - - -static void -esdi_mca_log(const char *fmt, ...) -{ -#ifdef ENABLE_ESDI_MCA_LOG - va_list ap; - - if (esdi_mca_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static __inline void -set_irq(esdi_t *dev) -{ - if (dev->basic_ctrl & CTRL_IRQ_ENA) - picint(1 << 14); -} - - -static __inline void -clear_irq(esdi_t *dev) -{ - picintc(1 << 14); -} - - - -static void -cmd_unsupported(esdi_t *dev) -{ - dev->status_len = 9; - dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; - dev->status_data[1] = 0x0f03; /*Attention error, command not supported*/ - dev->status_data[2] = 0x0002; /*Interface fault*/ - dev->status_data[3] = 0; - dev->status_data[4] = 0; - dev->status_data[5] = 0; - dev->status_data[6] = 0; - dev->status_data[7] = 0; - dev->status_data[8] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - dev->irq_in_progress = 1; - set_irq(dev); -} - - -static void -device_not_present(esdi_t *dev) -{ - dev->status_len = 9; - dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; - dev->status_data[1] = 0x0c11; /*Command failed, internal hardware error*/ - dev->status_data[2] = 0x000b; /*Selection error*/ - dev->status_data[3] = 0; - dev->status_data[4] = 0; - dev->status_data[5] = 0; - dev->status_data[6] = 0; - dev->status_data[7] = 0; - dev->status_data[8] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - dev->irq_in_progress = 1; - set_irq(dev); -} - - -static void -rba_out_of_range(esdi_t *dev) -{ - dev->status_len = 9; - dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; - dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ - dev->status_data[2] = 0x0007; /*RBA out of range*/ - dev->status_data[3] = 0; - dev->status_data[4] = 0; - dev->status_data[5] = 0; - dev->status_data[6] = 0; - dev->status_data[7] = 0; - dev->status_data[8] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - dev->irq_in_progress = 1; - set_irq(dev); -} - - -static void -complete_command_status(esdi_t *dev) -{ - dev->status_len = 7; - if (dev->cmd_dev == ATTN_DEVICE_0) - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); - else - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); - dev->status_data[1] = 0x0000; /*Error bits*/ - dev->status_data[2] = 0x1900; /*Device status*/ - dev->status_data[3] = 0; /*Number of blocks left to do*/ - dev->status_data[4] = (dev->rba-1) & 0xffff; /*Last RBA processed*/ - dev->status_data[5] = (dev->rba-1) >> 8; - dev->status_data[6] = 0; /*Number of blocks requiring error recovery*/ -} - -#define ESDI_ADAPTER_ONLY() do \ - { \ - if (dev->cmd_dev != ATTN_HOST_ADAPTER) \ - { \ - cmd_unsupported(dev); \ - return; \ - } \ - } while (0) - -#define ESDI_DRIVE_ONLY() do \ - { \ - if (dev->cmd_dev != ATTN_DEVICE_0 && dev->cmd_dev != ATTN_DEVICE_1) \ - { \ - cmd_unsupported(dev); \ - return; \ - } \ - if (dev->cmd_dev == ATTN_DEVICE_0) \ - drive = &dev->drives[0]; \ - else \ - drive = &dev->drives[1]; \ - } while (0) - - -static void -esdi_callback(void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - drive_t *drive; - int val; - - dev->callback = 0LL; - - /* If we are returning from a RESET, handle this first. */ - if (dev->in_reset) { - dev->in_reset = 0; - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; - - return; - } - - switch (dev->command) { - case CMD_READ: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - switch (dev->cmd_state) { - case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; - - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - dev->callback = ESDI_TIME; - dev->data_pos = 0; - break; - - case 1: - if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { - dev->callback = ESDI_TIME; - return; - } - - while (dev->sector_pos < dev->sector_count) { - if (! dev->data_pos) { - if (dev->rba >= drive->sectors) - fatal("Read past end of drive\n"); - hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); - } - - while (dev->data_pos < 256) { - val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); - - if (val == DMA_NODATA) { - dev->callback = ESDI_TIME; - return; - } - - dev->data_pos++; - } - - dev->data_pos = 0; - dev->sector_pos++; - dev->rba++; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - dev->callback = ESDI_TIME; - break; - - case 2: - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case CMD_WRITE: - case CMD_WRITE_VERIFY: - ESDI_DRIVE_ONLY(); - if (! drive->present) { - device_not_present(dev); - return; - } - - switch (dev->cmd_state) { - case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; - - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - dev->callback = ESDI_TIME; - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - dev->callback = ESDI_TIME; - return; - } - - while (dev->sector_pos < dev->sector_count) { - while (dev->data_pos < 256) { - val = dma_channel_read(dev->dma); - - if (val == DMA_NODATA) { - dev->callback = ESDI_TIME; - return; - } - - dev->data[dev->data_pos++] = val & 0xffff; - } - - if (dev->rba >= drive->sectors) - fatal("Write past end of drive\n"); - hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); - dev->rba++; - dev->sector_pos++; - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, - dev->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); - - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - dev->callback = ESDI_TIME; - break; - - case 2: - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case CMD_READ_VERIFY: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->rba += dev->sector_count; - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_SEEK: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_DEV_STATUS: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 9; - dev->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0x0000; /*Error bits*/ - dev->status_data[2] = 0x1900; /*Device status*/ - dev->status_data[3] = 0; /*ESDI Standard Status*/ - dev->status_data[4] = 0; /*ESDI Vendor Unique Status*/ - dev->status_data[5] = 0; - dev->status_data[6] = 0; - dev->status_data[7] = 0; - dev->status_data[8] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_DEV_CONFIG: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 6; - dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0x10; /*Zero defect*/ - dev->status_data[2] = drive->sectors & 0xffff; - dev->status_data[3] = drive->sectors >> 16; - dev->status_data[4] = drive->tracks; - dev->status_data[5] = drive->hpc | (drive->spt << 16); - - esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", - drive->sectors, - dev->status_data[0], dev->status_data[1], - dev->status_data[2], dev->status_data[3], - dev->status_data[4], dev->status_data[5]); - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_POS_INFO: - ESDI_ADAPTER_ONLY(); - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 5; - dev->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0xffdd; /*MCA ID*/ - dev->status_data[2] = dev->pos_regs[3] | - (dev->pos_regs[2] << 8); - dev->status_data[3] = 0xff; - dev->status_data[4] = 0xff; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case 0x10: - ESDI_ADAPTER_ONLY(); - switch (dev->cmd_state) { - case 0: - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - if (dev->sector_count > 256) - fatal("Write sector buffer count %04x\n", dev->cmd_data[1]); - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - dev->callback = ESDI_TIME; - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - dev->callback = ESDI_TIME; - return; - } - while (dev->sector_pos < dev->sector_count) { - while (dev->data_pos < 256) { - val = dma_channel_read(dev->dma); - - if (val == DMA_NODATA) { - dev->callback = ESDI_TIME; - return; - } - - dev->data[dev->data_pos++] = val & 0xffff;; - } - - memcpy(dev->sector_buffer[dev->sector_pos++], dev->data, 512); - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - dev->callback = ESDI_TIME; - break; - - case 2: - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case 0x11: - ESDI_ADAPTER_ONLY(); - switch (dev->cmd_state) { - case 0: - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - if (dev->sector_count > 256) - fatal("Read sector buffer count %04x\n", dev->cmd_data[1]); - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - dev->callback = ESDI_TIME; - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - dev->callback = ESDI_TIME; - return; - } - - while (dev->sector_pos < dev->sector_count) { - if (! dev->data_pos) - memcpy(dev->data, dev->sector_buffer[dev->sector_pos++], 512); - while (dev->data_pos < 256) { - val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); - - if (val == DMA_NODATA) { - dev->callback = ESDI_TIME; - return; - } - - dev->data_pos++; - } - - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - dev->callback = ESDI_TIME; - break; - - case 2: - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case 0x12: - ESDI_ADAPTER_ONLY(); - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 2; - dev->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - default: - fatal("BAD COMMAND %02x %i\n", dev->command, dev->cmd_dev); - } -} - - -static uint8_t -esdi_read(uint16_t port, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - uint8_t ret = 0xff; - - switch (port & 7) { - case 2: /*Basic status register*/ - ret = dev->status; - break; - - case 3: /*IRQ status*/ - dev->status &= ~STATUS_IRQ; - ret = dev->irq_status; - break; - - default: - fatal("esdi_read port=%04x\n", port); - } - - return(ret); -} - - -static void -esdi_write(uint16_t port, uint8_t val, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - - esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val); - - switch (port & 7) { - case 2: /*Basic control register*/ - if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { - dev->in_reset = 1; - dev->callback = ESDI_TIME * 50LL; - dev->status = STATUS_BUSY; - } - dev->basic_ctrl = val; - - if (! (dev->basic_ctrl & CTRL_IRQ_ENA)) - picintc(1 << 14); - break; - - case 3: /*Attention register*/ - switch (val & ATTN_DEVICE_SEL) { - case ATTN_HOST_ADAPTER: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress adapter\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_HOST_ADAPTER; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; - - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; - - case ATTN_RESET: - dev->in_reset = 1; - dev->callback = ESDI_TIME * 50LL; - dev->status = STATUS_BUSY; - break; - - default: - fatal("Bad attention request %02x\n", val); - } - break; - - case ATTN_DEVICE_0: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_DEVICE_0; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; - - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; - - default: - fatal("Bad attention request %02x\n", val); - } - break; - - case ATTN_DEVICE_1: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_DEVICE_1; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; - - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; - - default: - fatal("Bad attention request %02x\n", val); - } - break; - - default: - fatal("Attention to unknown device %02x\n", val); - } - break; - - default: - fatal("esdi_write port=%04x val=%02x\n", port, val); - } -} - - -static uint16_t -esdi_readw(uint16_t port, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - uint16_t ret = 0xffff; - - switch (port & 7) { - case 0: /*Status Interface Register*/ - if (dev->status_pos >= dev->status_len) - return(0); - ret = dev->status_data[dev->status_pos++]; if (dev->status_pos >= dev->status_len) { - dev->status &= ~STATUS_STATUS_OUT_FULL; - dev->status_pos = dev->status_len = 0; - } - break; - - default: - fatal("esdi_readw port=%04x\n", port); - } - - return(ret); -} - - -static void -esdi_writew(uint16_t port, uint16_t val, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - - esdi_mca_log("ESDI: wrw(%04x, %04x)\n", port & 7, val); - - switch (port & 7) { - case 0: /*Command Interface Register*/ - if (dev->cmd_pos >= 4) - fatal("CIR pos 4\n"); - dev->cmd_data[dev->cmd_pos++] = val; - if (((dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 4) || - (!(dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 2)) { - dev->cmd_pos = 0; - dev->cmd_req_in_progress = 0; - dev->cmd_state = 0; - - if ((dev->cmd_data[0] & CMD_DEVICE_SEL) != dev->cmd_dev) - fatal("Command device mismatch with attn\n"); - dev->command = dev->cmd_data[0] & CMD_MASK; - dev->callback = ESDI_TIME; - dev->status = STATUS_BUSY; - dev->data_pos = 0; - } - break; - - default: - fatal("esdi_writew port=%04x val=%04x\n", port, val); - } -} - - -static uint8_t -esdi_mca_read(int port, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - - esdi_mca_log("ESDI: mcard(%04x)\n", port); - - return(dev->pos_regs[port & 7]); -} - - -static void -esdi_mca_write(int port, uint8_t val, void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - - esdi_mca_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", - port, val, dev->pos_regs[2], dev->pos_regs[3]); - - if (port < 0x102) - return; - - /* Save the new value. */ - dev->pos_regs[port & 7] = val; - - io_removehandler(ESDI_IOADDR_PRI, 8, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, dev); - mem_mapping_disable(&dev->bios_rom.mapping); - - switch(dev->pos_regs[2] & 0x3c) { - case 0x14: - dev->dma = 5; - break; - case 0x18: - dev->dma = 6; - break; - case 0x1c: - dev->dma = 7; - break; - case 0x00: - dev->dma = 0; - break; - case 0x04: - dev->dma = 1; - break; - case 0x0c: - dev->dma = 3; - break; - case 0x10: - dev->dma = 4; - break; - } - - if (dev->pos_regs[2] & 1) { - io_sethandler(ESDI_IOADDR_PRI, 8, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, dev); - - if (!(dev->pos_regs[3] & 8)) { - mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - ((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); - } - - /* Say hello. */ - esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n", - dev->dma, dev->bios); - } -} - - -static void * -esdi_init(const device_t *info) -{ - drive_t *drive; - esdi_t *dev; - int c, i; - - dev = malloc(sizeof(esdi_t)); - if (dev == NULL) return(NULL); - memset(dev, 0x00, sizeof(esdi_t)); - - /* Mark as unconfigured. */ - dev->irq_status = 0xff; - - rom_init_interleaved(&dev->bios_rom, - BIOS_FILE_H, BIOS_FILE_L, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&dev->bios_rom.mapping); - - dev->drives[0].present = dev->drives[1].present = 0; - - for (c=0,i=0; idrives[hdd[i].esdi_channel]; - - /* Try to load an image for the drive. */ - if (! hdd_image_load(i)) { - /* Nope. */ - drive->present = 0; - continue; - } - - /* OK, so fill in geometry info. */ - drive->spt = hdd[i].spt; - drive->hpc = hdd[i].hpc; - drive->tracks = hdd[i].tracks; - drive->sectors = hdd_image_get_last_sector(i) + 1; - drive->hdd_num = i; - - /* Mark drive as present. */ - drive->present = 1; - } - - if (++c >= ESDI_NUM) break; - } - - /* Set the MCA ID for this controller, 0xFFDD. */ - dev->pos_regs[0] = 0xff; - dev->pos_regs[1] = 0xdd; - - /* Enable the device. */ - mca_add(esdi_mca_read, esdi_mca_write, dev); - - /* Mark for a reset. */ - dev->in_reset = 1; - dev->callback = ESDI_TIME * 50LL; - dev->status = STATUS_BUSY; - - /* Set the reply timer. */ - timer_add(esdi_callback, &dev->callback, &dev->callback, dev); - - return(dev); -} - - -static void -esdi_close(void *priv) -{ - esdi_t *dev = (esdi_t *)priv; - drive_t *drive; - int d; - - dev->drives[0].present = dev->drives[1].present = 0; - - for (d=0; d<2; d++) { - drive = &dev->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - free(dev); -} - - -static int -esdi_available(void) -{ - return(rom_present(BIOS_FILE_L) && rom_present(BIOS_FILE_H)); -} - - -const device_t esdi_ps2_device = { - "IBM ESDI Fixed Disk Adapter (MCA)", - DEVICE_MCA, 0, - esdi_init, esdi_close, NULL, - esdi_available, NULL, NULL, NULL -}; diff --git a/src - Cópia/disk/hdc_ide.c b/src - Cópia/disk/hdc_ide.c deleted file mode 100644 index 8ed9d188e..000000000 --- a/src - Cópia/disk/hdc_ide.c +++ /dev/null @@ -1,3023 +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. - * - * Implementation of the IDE emulation for hard disks and ATAPI - * CD-ROM devices. - * - * Version: @(#)hdc_ide.c 1.0.47 2018/06/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#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.h" -#include "../cdrom/cdrom.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdc_ide.h" -#include "hdd.h" -#include "zip.h" - - -/* Bits of 'atastat' */ -#define ERR_STAT 0x01 /* Error */ -#define IDX_STAT 0x02 /* Index */ -#define CORR_STAT 0x04 /* Corrected data */ -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 /* Drive seek complete */ -#define SERVICE_STAT 0x10 /* ATAPI service */ -#define DWF_STAT 0x20 /* Drive write fault */ -#define DRDY_STAT 0x40 /* Ready */ -#define BSY_STAT 0x80 /* Busy */ - -/* Bits of 'error' */ -#define AMNF_ERR 0x01 /* Address mark not found */ -#define TK0NF_ERR 0x02 /* Track 0 not found */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ -#define IDNF_ERR 0x10 /* Sector ID not found */ -#define MC_ERR 0x20 /* Media change */ -#define UNC_ERR 0x40 /* Uncorrectable data error */ -#define BBK_ERR 0x80 /* Bad block mark detected */ - -/* ATA Commands */ -#define WIN_NOP 0x00 -#define WIN_SRST 0x08 /* ATAPI Device Reset */ -#define WIN_RECAL 0x10 -#define WIN_READ 0x20 /* 28-Bit Read */ -#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry */ -#define WIN_WRITE 0x30 /* 28-Bit Write */ -#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write - no retry */ -#define WIN_VERIFY 0x40 /* 28-Bit Verify */ -#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ -#define WIN_FORMAT 0x50 -#define WIN_SEEK 0x70 -#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ -#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 - -#define FEATURE_SET_TRANSFER_MODE 0x03 -#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d -#define FEATURE_ENABLE_IRQ_SERVICE 0x5e -#define FEATURE_DISABLE_REVERT 0x66 -#define FEATURE_ENABLE_REVERT 0xcc -#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd -#define FEATURE_DISABLE_IRQ_SERVICE 0xde - -#if 0 -/* In the future, there's going to be just the IDE_ATAPI type, - leaving it to the common ATAPI/SCSI device handler to know - what type the device is. */ -enum -{ - IDE_NONE = 0, - IDE_HDD, - IDE_ATAPI -}; -#else -enum -{ - IDE_NONE = 0, - IDE_HDD, - IDE_CDROM, - IDE_ZIP -}; -#endif - -#define IDE_PCI (PCI && (romset != ROM_PB640)) - - -typedef struct { - int bit32, cur_dev, - irq; - int64_t callback; -} ide_board_t; - -static ide_board_t *ide_boards[4]; - -ide_t *ide_drives[IDE_NUM]; -int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -void (*ide_bus_master_set_irq)(int channel, void *priv); -void *ide_bus_master_priv[2]; -int ide_inited = 0; -int ide_ter_enabled = 0, ide_qua_enabled = 0; - -static uint16_t ide_base_main[4] = { 0x1f0, 0x170, 0x168, 0x1e8 }; -static uint16_t ide_side_main[4] = { 0x3f6, 0x376, 0x36e, 0x3ee }; - -static void ide_callback(void *priv); - - -#define IDE_TIME (20LL * TIMER_USEC) / 3LL - - -#ifdef ENABLE_IDE_LOG -int ide_do_log = ENABLE_IDE_LOG; -#endif - - -static void -ide_log(const char *fmt, ...) -{ -#ifdef ENABLE_IDE_LOG - va_list ap; - - if (ide_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -uint8_t -getstat(ide_t *ide) { - return ide->atastat; -} - - -int64_t -ide_get_period(ide_t *ide, int size) -{ - double period = 10.0 / 3.0; - - switch(ide->mdma_mode & 0x300) { - case 0x000: /* PIO */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 10.0 / 3.0; - break; - case 1: - period = (period * 600.0) / 383.0; - break; - case 2: - period = 25.0 / 3.0; - break; - case 3: - period = 100.0 / 9.0; - break; - case 4: - period = 50.0 / 3.0; - break; - } - break; - case 0x100: /* Single Word DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 25.0 / 12.0; - break; - case 1: - period = 25.0 / 6.0; - break; - case 2: - period = 25.0 / 3.0; - break; - } - break; - case 0x200: /* Multiword DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 25.0 / 6.0; - break; - case 1: - period = 40.0 / 3.0; - break; - case 2: - period = 50.0 / 3.0; - break; - } - break; - case 0x300: /* Ultra DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 50.0 / 3.0; - break; - case 1: - period = 25.0; - break; - case 2: - period = 100.0 / 3.0; - break; - case 3: - period = 400.0 / 9.0; - break; - case 4: - period = 200.0 / 3.0; - break; - case 5: - period = 100.0; - break; - } - break; - } - - period *= 1048576.0; /* period * MB */ - period = 1000000.0 / period; - period *= (double) TIMER_USEC; - period *= (double) size; - return (int64_t) period; -} - - -#if 0 -int64_t -ide_get_seek_time(ide_t *ide, uint32_t new_pos) -{ - double dusec, time; - uint32_t pos = hdd_image_get_pos(ide->hdd_num); - uint32_t t, nt; - t = pos / ide->spt; - nt = new_pos / ide->spt; - - dusec = (double) TIMER_USEC; - time = (1000000.0 / 2800.0) * dusec; /* Revolution (1/2800 s). */ - - if ((t % ide->hpc) != (pos % ide->hpc)) /* Head change. */ - time += (dusec / 250.0); /* 4ns */ - - t /= ide->hpc; - nt /= ide->hpc; - - if (t != nt) { - t = ABS(t - nt); - time += ((40000.0 * dusec) / ((double) ide->tracks)) * ((double) t); - } - return (int64_t) time; -} -#endif - - -int -ide_drive_is_cdrom(ide_t *ide) -{ - int ch = ide->channel; - - if (ch >= 8) - return 0; - - if (atapi_cdrom_drives[ch] >= CDROM_NUM) - return 0; - else { - if (cdrom_drives[atapi_cdrom_drives[ch]].bus_type == CDROM_BUS_ATAPI) - return 1; - else - return 0; - } -} - - -int -ide_drive_is_zip(ide_t *ide) -{ - int ch = ide->channel; - - if (ch >= 8) - return 0; - - if (atapi_zip_drives[ch] >= ZIP_NUM) - return 0; - else { - if (zip_drives[atapi_zip_drives[ch]].bus_type == ZIP_BUS_ATAPI) - return 1; - else - return 0; - } -} - - -void -ide_irq_raise(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - if (!(ide->fdisk & 2) && (ide_boards[ide->board]->irq != -1)) { - if ((ide->board < 2) && ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board | 0x40, ide_bus_master_priv[ide->board]); - else - picint(1 << ide_boards[ide->board]->irq); - } - - ide->irqstat=1; - ide->service=1; -} - - -void -ide_irq_lower(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - if ((ide_boards[ide->board]->irq != -1) && ide->irqstat) { - if ((ide->board < 2) && ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board, ide_bus_master_priv[ide->board]); - else - picintc(1 << ide_boards[ide->board]->irq); - } - - ide->irqstat=0; -} - - -/** - * Copy a string into a buffer, padding with spaces, and placing characters as - * if they were packed into 16-bit values, stored little-endian. - * - * @param str Destination buffer - * @param src Source string - * @param len Length of destination buffer to fill in. Strings shorter than - * this length will be padded with spaces. - */ -static void -ide_padstr(char *str, const char *src, int len) -{ - int i, v; - - for (i = 0; i < len; i++) { - if (*src != '\0') - v = *src++; - else - v = ' '; - str[i ^ 1] = v; - } -} - - -/** - * Copy a string into a buffer, padding with spaces. Does not add string - * terminator. - * - * @param buf Destination buffer - * @param buf_size Size of destination buffer to fill in. Strings shorter than - * this length will be padded with spaces. - * @param src Source string - */ -void ide_padstr8(uint8_t *buf, int buf_size, const char *src) -{ - int i; - - for (i = 0; i < buf_size; i++) { - if (*src != '\0') - buf[i] = *src++; - else - buf[i] = ' '; - } -} - - -/* Type: - 0 = PIO, - 1 = SDMA, - 2 = MDMA, - 3 = UDMA - Return: - -1 = Not supported, - Anything else = maximum mode - - This will eventually be hookable. */ -enum { - TYPE_PIO = 0, - TYPE_SDMA, - TYPE_MDMA, - TYPE_UDMA -}; - -static int -ide_get_max(ide_t *ide, int type) -{ - switch(type) { - case TYPE_PIO: /* PIO */ - if (!IDE_PCI || (ide->board >= 2)) - return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ - else { - if (ide_drive_is_zip(ide)) - return 3; - else - return 4; - } - break; - case TYPE_SDMA: /* SDMA */ - if (!IDE_PCI || (ide->board >= 2) || ide_drive_is_zip(ide)) - return -1; - else - return 2; - case TYPE_MDMA: /* MDMA */ - if (!IDE_PCI || (ide->board >= 2)) - return -1; - else { - if (ide_drive_is_zip(ide)) - return 1; - else - return 2; - } - case TYPE_UDMA: /* UDMA */ - if (!IDE_PCI || (ide->board >= 2)) - return -1; - else - return 2; - default: - fatal("Unknown transfer type: %i\n", type); - return -1; - } -} - - -/* Return: - 0 = Not supported, - Anything else = timings - - This will eventually be hookable. */ -enum { - TIMINGS_DMA = 0, - TIMINGS_PIO, - TIMINGS_PIO_FC -}; - -static int -ide_get_timings(ide_t *ide, int type) -{ - switch(type) { - case TIMINGS_DMA: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0x96; - else - return 120; - } - break; - case TIMINGS_PIO: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0xb4; - else - return 120; - } - break; - case TIMINGS_PIO_FC: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0xb4; - else - return 0; - } - break; - default: - fatal("Unknown transfer type: %i\n", type); - return 0; - } -} - - -/** - * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command - */ -static void ide_hd_identify(ide_t *ide) -{ - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - - uint32_t d_hpc, d_spt, d_tracks; - uint64_t full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - - device_identify[6] = (ide->hdd_num / 10) + 0x30; - device_identify[7] = (ide->hdd_num % 10) + 0x30; - ide_log("IDE Identify: %s\n", device_identify); - - d_spt = ide->spt; - if (ide->hpc <= 16) { - /* HPC <= 16, report as needed. */ - d_tracks = ide->tracks; - d_hpc = ide->hpc; - } else { - /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; - } - - /* Specify default CHS translation */ - if (full_size <= 16514064) { - ide->buffer[1] = d_tracks; /* Tracks in default CHS translation. */ - ide->buffer[3] = d_hpc; /* Heads in default CHS translation. */ - ide->buffer[6] = d_spt; /* Heads in default CHS translation. */ - } else { - ide->buffer[1] = 16383; /* Tracks in default CHS translation. */ - ide->buffer[3] = 16; /* Heads in default CHS translation. */ - ide->buffer[6] = 63; /* Heads in default CHS translation. */ - } - ide_log("Default CHS translation: %i, %i, %i\n", ide->buffer[1], ide->buffer[3], ide->buffer[6]); - - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[20] = 3; /*Buffer type*/ - ide->buffer[21] = 512; /*Buffer size*/ - ide->buffer[50] = 0x4000; /* Capabilities */ - ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; - - if ((ide->tracks >= 1024) || (ide->hpc > 16) || (ide->spt > 63)) { - ide->buffer[49] = (1 << 9); - ide_log("LBA supported\n"); - - ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (full_size >> 16) & 0x0FFF; - ide_log("Full size: %" PRIu64 "\n", full_size); - - /* - Bit 0 = The fields reported in words 54-58 are valid; - Bit 1 = The fields reported in words 64-70 are valid; - Bit 2 = The fields reported in word 88 are valid. */ - ide->buffer[53] = 1; - - if (ide->cfg_spt != 0) { - ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; - ide->buffer[55] = ide->cfg_hpc; - ide->buffer[56] = ide->cfg_spt; - } else { - if (full_size <= 16514064) { - ide->buffer[54] = d_tracks; - ide->buffer[55] = d_hpc; - ide->buffer[56] = d_spt; - } else { - ide->buffer[54] = 16383; - ide->buffer[55] = 16; - ide->buffer[56] = 63; - } - } - - full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * ((uint64_t) ide->buffer[56]); - - ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[58] = (full_size >> 16) & 0x0FFF; - - ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); - } - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/ - ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ - ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/ - } else { - ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/ - ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ - } -} - - -/** - * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command - */ -static void -ide_atapi_cdrom_identify(ide_t *ide) -{ - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - - uint8_t cdrom_id; - - cdrom_id = atapi_cdrom_drives[ide->channel]; - - device_identify[7] = cdrom_id + 0x30; - ide_log("ATAPI Identify: %s\n", device_identify); - - ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ -#if 0 - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ -#else - ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ -#endif - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[71] = 30; - ide->buffer[72] = 30; - } -} - - -static void -ide_atapi_zip_100_identify(ide_t *ide) -{ - ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ -} - - -static void -ide_atapi_zip_250_identify(ide_t *ide) -{ - ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */ - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/ - ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/ - } -} - - -static void -ide_atapi_zip_identify(ide_t *ide) -{ - uint8_t zip_id; - - zip_id = atapi_zip_drives[ide->channel]; - - /* Using (2<<5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive - as a LS-120. */ - ide->buffer[0] = 0x8000 | (0<<8) | 0x80 | (1<<5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ - - if (zip_drives[zip_id].is_250) - ide_atapi_zip_250_identify(ide); - else - ide_atapi_zip_100_identify(ide); -} - -static void -ide_identify(ide_t *ide) -{ - int d, i, max_pio, max_sdma, max_mdma, max_udma; - - ide_log("IDE IDENTIFY or IDENTIFY PACKET DEVICE on board %i (channel %i)\n", ide->board, ide->channel); - - memset(ide->buffer, 0, 512); - - if (ide_drive_is_cdrom(ide)) - ide_atapi_cdrom_identify(ide); - else if (ide_drive_is_zip(ide)) - ide_atapi_zip_identify(ide); - else if (ide->type != IDE_NONE) - ide_hd_identify(ide); - else { - fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); - return; - } - - max_pio = ide_get_max(ide, TYPE_PIO); - max_sdma = ide_get_max(ide, TYPE_SDMA); - max_mdma = ide_get_max(ide, TYPE_MDMA); - max_udma = ide_get_max(ide, TYPE_UDMA); - - if (ide_boards[ide->board]->bit32) - ide->buffer[48] |= 1; /*Dword transfers supported*/ - ide->buffer[51] = ide_get_timings(ide, TIMINGS_PIO); - ide->buffer[53] &= 0x0006; - ide->buffer[52] = ide->buffer[62] = ide->buffer[63] = ide->buffer[64] = 0x0000; - ide->buffer[65] = ide->buffer[66] = ide->buffer[67] = ide->buffer[68] = 0x0000; - ide->buffer[88] = 0x0000; - - if (max_pio >= 3) { - ide->buffer[53] |= 0x0002; - ide->buffer[67] = ide_get_timings(ide, TIMINGS_PIO); - ide->buffer[68] = ide_get_timings(ide, TIMINGS_PIO_FC); - for (i = 3; i <= max_pio; i++) - ide->buffer[64] |= (1 << (i - 3)); - } - if (max_sdma != -1) { - for (i = 0; i <= max_sdma; i++) - ide->buffer[62] |= (1 << i); - } - if (max_mdma != -1) { - for (i = 0; i <= max_mdma; i++) - ide->buffer[63] |= (1 << i); - } - if (max_udma != -1) { - ide->buffer[53] |= 0x0004; - for (i = 0; i <= max_udma; i++) - ide->buffer[88] |= (1 << i); - } - - if ((max_sdma != -1) || (max_mdma != -1) || (max_udma != -1)) { - ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = ide_get_timings(ide, TIMINGS_DMA); - } - - if ((max_mdma != -1) || (max_udma != -1)) { - ide->buffer[65] = ide_get_timings(ide, TIMINGS_DMA); - ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); - } - - if (ide->mdma_mode != -1) { - d = (ide->mdma_mode & 0xff); - d <<= 8; - if ((ide->mdma_mode & 0x300) == 0x000) { - if ((ide->mdma_mode & 0xff) >= 3) - ide->buffer[64] |= d; - } else if ((ide->mdma_mode & 0x300) == 0x100) - ide->buffer[62] |= d; - else if ((ide->mdma_mode & 0x300) == 0x200) - ide->buffer[63] |= d; - else if ((ide->mdma_mode & 0x300) == 0x300) - ide->buffer[88] |= d; - ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); - } -} - - -/* - * Return the sector offset for the current register values - */ -static off64_t -ide_get_sector(ide_t *ide) -{ - uint32_t heads, sectors; - - if (ide->lba) - return (off64_t)ide->lba_addr + ide->skip512; - else { - heads = ide->cfg_hpc; - sectors = ide->cfg_spt; - - return ((((off64_t) ide->cylinder * heads) + ide->head) * - sectors) + (ide->sector - 1) + ide->skip512; - } -} - - -/** - * Move to the next sector using CHS addressing - */ -static void -ide_next_sector(ide_t *ide) -{ - if (ide->lba) - ide->lba_addr++; - else { - ide->sector++; - if (ide->sector == (ide->cfg_spt + 1)) { - ide->sector = 1; - ide->head++; - if (ide->head == ide->cfg_hpc) { - ide->head = 0; - ide->cylinder++; - } - } - } -} - - -static void -loadhd(ide_t *ide, int d, const wchar_t *fn) -{ - if (! hdd_image_load(d)) { - ide->type = IDE_NONE; - return; - } - - ide->spt = hdd[d].spt; - ide->hpc = hdd[d].hpc; - ide->tracks = hdd[d].tracks; - ide->type = IDE_HDD; - ide->hdd_num = d; -} - - -void -ide_set_signature(ide_t *ide) -{ - uint8_t cdrom_id = atapi_cdrom_drives[ide->channel]; - uint8_t zip_id = atapi_zip_drives[ide->channel]; - - ide->sector=1; - ide->head=0; - - if (ide_drive_is_zip(ide)) { - zip_set_signature(zip[zip_id]); - ide->secount = zip[zip_id]->phase; - ide->cylinder = zip[zip_id]->request_length; - } else if (ide_drive_is_cdrom(ide)) { - cdrom_set_signature(cdrom[cdrom_id]); - ide->secount = cdrom[cdrom_id]->phase; - ide->cylinder = cdrom[cdrom_id]->request_length; - } else { - ide->secount=1; - ide->cylinder=((ide->type == IDE_HDD) ? 0 : 0xFFFF); - if (ide->type == IDE_HDD) - ide->drive = 0; - } -} - - -static int -ide_set_features(ide_t *ide) -{ - uint8_t features, features_data; - int mode, submode, max; - - features = ide->cylprecomp; - features_data = ide->secount; - - ide_log("Features code %02X\n", features); - - ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data); - - switch(features) { - case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */ - ide_log("Transfer mode %02X\n", features_data >> 3); - - mode = (features_data >> 3); - submode = features_data & 7; - - switch(mode) { - case 0x00: /* PIO default */ - if (submode != 0) - return 0; - max = ide_get_max(ide, TYPE_PIO); - ide->mdma_mode = (1 << max); - ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x01: /* PIO mode */ - max = ide_get_max(ide, TYPE_PIO); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode); - ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x02: /* Singleword DMA mode */ - max = ide_get_max(ide, TYPE_SDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x100; - ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x04: /* Multiword DMA mode */ - max = ide_get_max(ide, TYPE_MDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x200; - ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x08: /* Ultra DMA mode */ - max = ide_get_max(ide, TYPE_UDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x300; - ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - default: - return 0; - } - - case FEATURE_ENABLE_IRQ_OVERLAPPED: - case FEATURE_ENABLE_IRQ_SERVICE: - case FEATURE_DISABLE_IRQ_OVERLAPPED: - case FEATURE_DISABLE_IRQ_SERVICE: - max = ide_get_max(ide, TYPE_MDMA); - if (max == -1) - return 0; - else - return 1; - - case FEATURE_DISABLE_REVERT: /* Disable reverting to power on defaults. */ - case FEATURE_ENABLE_REVERT: /* Enable reverting to power on defaults. */ - return 1; - - default: - return 0; - } - - return 1; -} - - -void -ide_set_sector(ide_t *ide, int64_t sector_num) -{ - unsigned int cyl, r; - if (ide->lba) { - ide->head = (sector_num >> 24); - ide->cylinder = (sector_num >> 8); - ide->sector = (sector_num); - } else { - cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - ide->cylinder = cyl; - ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); - ide->sector = (r % hdd[ide->hdd_num].spt) + 1; - } -} - - -static void -ide_zero(int d) -{ - ide_t *dev; - ide_drives[d] = (ide_t *) malloc(sizeof(ide_t)); - memset(ide_drives[d], 0, sizeof(ide_t)); - dev = ide_drives[d]; - dev->channel = d; - dev->type = IDE_NONE; - dev->hdd_num = -1; - dev->atastat = DRDY_STAT | DSC_STAT; - dev->service = 0; - dev->board = d >> 1; -} - - -static void -ide_board_close(int board) -{ - ide_t *dev; - int c, d; - - /* Close hard disk image files (if previously open) */ - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; - - if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) - hdd_image_close(dev->hdd_num); - - if (board < 4) { - if (ide_drive_is_zip(dev)) - zip[atapi_zip_drives[c]]->status = DRDY_STAT | DSC_STAT; - else if (ide_drive_is_cdrom(dev)) - cdrom[atapi_cdrom_drives[c]]->status = DRDY_STAT | DSC_STAT; - } - - if (dev->buffer) - free(dev->buffer); - - if (dev->sector_buffer) - free(dev->sector_buffer); - - if (dev) - free(dev); - } -} - - -static void -ide_board_init(int board) -{ - ide_t *dev; - int c, d; - int max, ch; - int is_ide, valid_ch; - int min_ch, max_ch; - - min_ch = (board << 1); - max_ch = min_ch + 1; - - ide_log("IDE: board %i: loading disks...\n", board); - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - ide_zero(c); - } - - c = 0; - for (d = 0; d < HDD_NUM; d++) { - is_ide = (hdd[d].bus == HDD_BUS_IDE); - ch = hdd[d].ide_channel; - - if (board == 4) { - valid_ch = ((ch >= 0) && (ch <= 1)); - ch |= 8; - } else - valid_ch = ((ch >= min_ch) && (ch <= max_ch)); - - if (is_ide && valid_ch) { - ide_log("Found IDE hard disk on channel %i\n", ch); - loadhd(ide_drives[ch], d, hdd[d].fn); - ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256*512); - memset(ide_drives[ch]->sector_buffer, 0, 256*512); - if (++c >= 2) break; - } - } - ide_log("IDE: board %i: done, loaded %d disks.\n", board, c); - - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; - - if (board < 4) { - if (ide_drive_is_zip(dev) && (dev->type == IDE_NONE)) - dev->type = IDE_ZIP; - else if (ide_drive_is_cdrom(dev) && (dev->type == IDE_NONE)) - dev->type = IDE_CDROM; - } - - if (dev->type != IDE_NONE) { - dev->buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); - memset(dev->buffer, 0, 65536 * sizeof(uint16_t)); - } - - ide_set_signature(dev); - - max = ide_get_max(dev, TYPE_PIO); - dev->mdma_mode = (1 << max); - dev->error = 1; - dev->cfg_spt = dev->cfg_hpc = 0; - } -} - - -void -ide_set_callback(uint8_t board, int64_t callback) -{ - ide_board_t *dev = ide_boards[board]; - - ide_log("ide_set_callback(%i)\n", board); - - if (!dev) { - ide_log("Set callback failed\n"); - return; - } - - if (callback) - dev->callback = callback; - else - dev->callback = 0LL; -} - - -void -ide_write_data(ide_t *ide, uint32_t val, int length) -{ - int ch = ide->channel; - - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; - - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - return; - - if (ide_drive_is_zip(ide)) - zip_write(ch, val, length); - else - cdrom_write(ch, val, length); - return; - } else { - switch(length) { - case 1: - idebufferb[ide->pos] = val & 0xff; - ide->pos++; - break; - case 2: - idebufferw[ide->pos >> 1] = val & 0xffff; - ide->pos += 2; - break; - case 4: - idebufferl[ide->pos >> 2] = val; - ide->pos += 4; - break; - default: - return; - } - - if (ide->pos>=512) { - ide->pos=0; - ide->atastat = BSY_STAT; - timer_process(); - if (ide->command == WIN_WRITE_MULTIPLE) - ide_callback(ide_boards[ide->board]); - else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - timer_update_outstanding(); - } - } -} - - -void -ide_writew(uint16_t addr, uint16_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* ide_log("ide_writew %04X %04X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); */ - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val, 2); - break; - } -} - - -static void -ide_writel(uint16_t addr, uint32_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* ide_log("ide_writel %04X %08X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); */ - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val & 0xffff, 2); - ide_write_data(ide, val >> 16, 2); - break; - } -} - - -void -ide_write_devctl(uint16_t addr, uint8_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide, *ide_other; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_log("ide_write_devctl %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - - if ((ide->fdisk & 4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { - timer_process(); - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 0LL; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; - ide_set_callback(ide->board, 500LL * IDE_TIME); - timer_update_outstanding(); - - if (ide->type != IDE_NONE) - ide->reset = 1; - if (ide_other->type != IDE_NONE) - ide->reset = 1; - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - ide->atastat = ide_other->atastat = BSY_STAT; - } - - if (val & 4) { - /*Drive held in reset*/ - timer_process(); - ide_set_callback(ide->board, 0LL); - timer_update_outstanding(); - ide->atastat = ide_other->atastat = BSY_STAT; - } - ide->fdisk = ide_other->fdisk = val; - return; -} - - -void -ide_writeb(uint16_t addr, uint8_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide, *ide_other; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_log("ide_write %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val | (val << 8), 2); - return; - - /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ - case 0x1: /* Features */ - if (ide_drive_is_zip(ide)) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - zip[atapi_zip_drives[ch]]->features = val; - } else if (ide_drive_is_cdrom(ide)) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - cdrom[atapi_cdrom_drives[ch]]->features = val; - } - ide->cylprecomp = val; - - if (ide_drive_is_zip(ide_other)) - zip[atapi_zip_drives[ch ^ 1]]->features = val; - else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ch ^ 1]]->features = val; - ide_other->cylprecomp = val; - return; - - case 0x2: /* Sector count */ - if (ide_drive_is_zip(ide)) { - ide_log("Sector count write: %i\n", val); - zip[atapi_zip_drives[ch]]->phase = val; - } else if (ide_drive_is_cdrom(ide)) { - ide_log("Sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[ch]]->phase = val; - } - ide->secount = val; - - if (ide_drive_is_zip(ide_other)) { - ide_log("Other sector count write: %i\n", val); - zip[atapi_zip_drives[ch ^ 1]]->phase = val; - } else if (ide_drive_is_cdrom(ide_other)) { - ide_log("Other sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[ch ^ 1]]->phase = val; - } - ide_other->secount = val; - return; - - case 0x3: /* Sector */ - ide->sector = val; - ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; - ide_other->sector = val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; - return; - - case 0x4: /* Cylinder low */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->request_length &= 0xFF00; - zip[atapi_zip_drives[ch]]->request_length |= val; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[ch]]->request_length |= val; - } - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ch ^ 1]]->request_length &= 0xFF00; - zip[atapi_zip_drives[ch ^ 1]]->request_length |= val; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length |= val; - } - ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); - return; - - case 0x5: /* Cylinder high */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->request_length &= 0xFF; - zip[atapi_zip_drives[ch]]->request_length |= (val << 8); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->request_length &= 0xFF; - cdrom[atapi_cdrom_drives[ch]]->request_length |= (val << 8); - } - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ch ^ 1]]->request_length &= 0xFF; - zip[atapi_zip_drives[ch ^ 1]]->request_length |= (val << 8); - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length &= 0xFF; - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length |= (val << 8); - } - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; - - case 0x6: /* Drive/Head */ - if (ch != ((val >> 4) & 1) + (ide->board << 1)) { - ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); - ch = ide_boards[ide->board]->cur_dev; - - if (ide->reset || ide_other->reset) { - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - ide->reset = ide_other->reset = 0; - - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ide->channel]]->error = 1; - zip[atapi_zip_drives[ide->channel]]->phase = 1; - zip[atapi_zip_drives[ide->channel]]->request_length = 0xEB14; - zip[atapi_zip_drives[ide->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->error = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ide_other->channel]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ide_other->channel]]->error = 1; - zip[atapi_zip_drives[ide_other->channel]]->phase = 1; - zip[atapi_zip_drives[ide_other->channel]]->request_length = 0xEB14; - zip[atapi_zip_drives[ide_other->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ide_other->channel]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide_other->channel]]->error = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]]->request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide_other->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } - - ide_set_callback(ide->board, 0LL); - timer_update_outstanding(); - return; - } - - ide = ide_drives[ch]; - } - - ide->head = val & 0xF; - ide->lba = val & 0x40; - ide_other->head = val & 0xF; - ide_other->lba = val & 0x40; - - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24); - return; - - case 0x7: /* Command register */ - if (ide->type == IDE_NONE) - return; - - ide_irq_lower(ide); - ide->command=val; - - ide->error=0; - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->error = 0; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->error = 0; - - if (((val >= WIN_RECAL) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 100LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; - ide_set_callback(ide->board, 100LL * IDE_TIME); - timer_update_outstanding(); - return; - } - - switch (val) { - case WIN_SRST: /* ATAPI Device Reset */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = DRDY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 100LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; - ide_set_callback(ide->board, 100LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_READ_MULTIPLE: - /* Fatal removed in accordance with the official ATAPI reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - ide->blockcount = 0; - /* Turn on the activity indicator *here* so that it gets turned on - less times. */ - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - - case WIN_READ: - case WIN_READ_NORETRY: - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; - if (ide->type == IDE_HDD) { - if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); - } else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - } else - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - ide->do_initial_read = 1; - return; - - case WIN_WRITE_MULTIPLE: - if (!ide->blocksize && !ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - fatal("Write_MULTIPLE - blocksize = 0\n"); - ide->blockcount = 0; - /* Turn on the activity indicator *here* so that it gets turned on - less times. */ - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - zip[atapi_zip_drives[ide->channel]]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->pos = 0; - } else { - ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->pos=0; - } - return; - - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - case WIN_IDENTIFY: /* Identify Device */ - case WIN_SET_FEATURES: /* Set Features */ - case WIN_READ_NATIVE_MAX: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; - if ((ide->type == IDE_HDD) && - ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { - if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); - } else if ((ide->type == IDE_HDD) && - ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) - ide_set_callback(ide->board, ide_get_period(ide, 512)); - else - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_FORMAT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto ide_bad_command; - else { - ide->atastat = DRQ_STAT; - ide->pos=0; - } - return; - - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 30LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 30LL*IDE_TIME; - ide_set_callback(ide->board, 30LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - - if (ide_drive_is_zip(ide_other)) - zip[atapi_zip_drives[ide_other->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ide_other->channel]]->status = BSY_STAT; - else - ide_other->atastat = BSY_STAT; - - timer_process(); - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL * IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL * IDE_TIME; - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_PIDENTIFY: /* Identify Packet Device */ - case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: /* Idle */ - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - ide_callback(dev); - timer_update_outstanding(); - return; - - case WIN_PACKETCMD: /* ATAPI Packet */ - /* Skip the command callback wait, and process immediately. */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->packet_status = ZIP_PHASE_IDLE; - zip[atapi_zip_drives[ide->channel]]->pos=0; - zip[atapi_zip_drives[ide->channel]]->phase = 1; - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | DRQ_STAT; - ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; - cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; - cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | DRQ_STAT; - } else { - ide->atastat = BSY_STAT; - timer_process(); - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - ide->pos=0; - } - return; - - case 0xF0: - default: -ide_bad_command: - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - zip[atapi_zip_drives[ide->channel]]->error = ABRT_ERR; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->error = ABRT_ERR; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - } - ide_irq_raise(ide); - return; - } - return; - } -} - - -static uint32_t -ide_read_data(ide_t *ide, int length) -{ - int ch = ide->channel; - uint32_t temp; - - if (!ide->buffer) { - switch (length) { - case 1: - return 0xff; - case 2: - return 0xffff; - case 4: - return 0xffffffff; - default: - return 0; - } - } - - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; - - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) { - ide_log("Drive not ZIP or CD-ROM (position: %i)\n", ide->pos); - return 0; - } - if (ide_drive_is_zip(ide)) - temp = zip_read(ch, length); - else - temp = cdrom_read(ch, length); - } else { - switch (length) { - case 1: - temp = idebufferb[ide->pos]; - ide->pos++; - break; - case 2: - temp = idebufferw[ide->pos >> 1]; - ide->pos += 2; - break; - case 4: - temp = idebufferl[ide->pos >> 2]; - ide->pos += 4; - break; - default: - return 0; - } - } - if (ide->pos>=512 && ide->command != WIN_PACKETCMD) { - ide->pos=0; - ide->atastat = DRDY_STAT | DSC_STAT; - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ch]]->packet_status = ZIP_PHASE_IDLE; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ch]]->packet_status = CDROM_PHASE_IDLE; - } - if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BSY_STAT; - timer_process(); - if (ide->command == WIN_READ_MULTIPLE) - ide_callback(ide_boards[ide->board]); - else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - timer_update_outstanding(); - } else { - if (ide->command != WIN_READ_MULTIPLE) - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } - } - - return temp; -} - - -static uint8_t -ide_status(ide_t *ide, int ch) -{ - if (ide->type == IDE_NONE) - return 0; - else { - if (ide_drive_is_zip(ide)) - return (zip[atapi_zip_drives[ch]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - else if (ide_drive_is_cdrom(ide)) - return (cdrom[atapi_cdrom_drives[ch]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - else - return ide->atastat; - } -} - - -uint8_t -ide_readb(uint16_t addr, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - int ch; - ide_t *ide; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - uint8_t temp = 0xff; - uint16_t tempw; - - addr |= 0x90; - addr &= 0xFFF7; - - switch (addr & 0x7) { - case 0x0: /* Data */ - tempw = ide_read_data(ide, 2); - temp = tempw & 0xff; - break; - - /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), - Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), - and Bit 0 = ILI (illegal length indication). */ - case 0x1: /* Error */ - if (ide->type == IDE_NONE) - temp = 0; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->error; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->error; - else - temp = ide->error; - } - break; - - /* For ATAPI: - Bit 0: Command or Data: - Data if clear, Command if set; - Bit 1: I/OB - Direction: - To device if set; - From device if clear. - IO DRQ CoD - 0 1 1 Ready to accept command packet - 1 1 1 Message - ready to send message to host - 1 1 0 Data to host - 0 1 0 Data from host - 1 0 1 Status. */ - case 0x2: /* Sector count */ - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->phase; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->phase; - else - temp = ide->secount; - break; - - case 0x3: /* Sector */ - temp = (uint8_t)ide->sector; - break; - - case 0x4: /* Cylinder low */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->request_length & 0xff; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->request_length & 0xff; - else - temp = ide->cylinder & 0xff; - } - break; - - case 0x5: /* Cylinder high */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->request_length >> 8; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->request_length >> 8; - else - temp = ide->cylinder >> 8; - } - break; - - case 0x6: /* Drive/Head */ - temp = (uint8_t)(ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); - break; - - /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is - DF (drive fault). */ - case 0x7: /* Status */ - ide_irq_lower(ide); - temp = ide_status(ide, ch); - break; - } - - ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; -} - - -uint8_t -ide_read_alt_status(uint16_t addr, void *priv) -{ - uint8_t temp = 0xff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* Per the Seagate ATA-3 specification: - Reading the alternate status does *NOT* clear the IRQ. */ - temp = ide_status(ide, ch); - - ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; -} - - -uint16_t -ide_readw(uint16_t addr, void *priv) -{ - uint16_t temp = 0xffff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - switch (addr & 0x7) { - case 0x0: /* Data */ - temp = ide_read_data(ide, 2); - break; - } - - /* ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); */ - return temp; -} - - -static uint32_t -ide_readl(uint16_t addr, void *priv) -{ - uint16_t temp2; - uint32_t temp = 0xffffffff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - switch (addr & 0x7) { - case 0x0: /* Data */ - temp2 = ide_read_data(ide, 2); - temp = temp2 | (ide_read_data(ide, 2) << 16); - break; - } - - /* ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, temp); */ - return temp; -} - - -static void -ide_callback(void *priv) -{ - ide_t *ide, *ide_other; - int snum, ret, ch; - int cdrom_id, cdrom_id_other; - int zip_id, zip_id_other; - - ide_board_t *dev = (ide_board_t *) priv; - ch = dev->cur_dev; - - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_set_callback(ide->board, 0LL); - - if (ide->reset) { - ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - - // ide->cfg_spt = ide->cfg_hpc = 0; /* need new parameters (drive 0) */ - // ide_other->cfg_spt = ide_other->cfg_hpc = 0; /* need new parameters (drive 1) */ - - ide->reset = ide_other->reset = 0; - - ide_set_signature(ide); - if (ide_drive_is_zip(ide)) { - zip_id = atapi_zip_drives[ch]; - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->error = 1; - } else if (ide_drive_is_cdrom(ide)) { - cdrom_id = atapi_cdrom_drives[ch]; - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->error = 1; - if (cdrom[cdrom_id]->handler->stop) - cdrom[cdrom_id]->handler->stop(cdrom_id); - } - - ide_set_signature(ide_other); - if (ide_drive_is_zip(ide_other)) { - zip_id_other = atapi_zip_drives[ch ^ 1]; - zip[zip_id_other]->status = DRDY_STAT | DSC_STAT; - zip[zip_id_other]->error = 1; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom_id_other = atapi_cdrom_drives[ch ^ 1]; - cdrom[cdrom_id_other]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id_other]->error = 1; - if (cdrom[cdrom_id_other]->handler->stop) - cdrom[cdrom_id_other]->handler->stop(cdrom_id_other); - } - - return; - } - - ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset,ch); - - cdrom_id = atapi_cdrom_drives[ch]; - cdrom_id_other = atapi_cdrom_drives[ch ^ 1]; - - zip_id = atapi_zip_drives[ch]; - zip_id_other = atapi_zip_drives[ch ^ 1]; - - if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || - ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { - if (ide->type != IDE_HDD) - goto abort_cmd; - if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F)) { - if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || - !ide->sector || (ide->sector > ide->spt)) - goto id_not_found; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } - - switch (ide->command) { - /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, - Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ - case WIN_SRST: /*ATAPI Device Reset */ - - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = 1; - ide->sector = 1; - - ide_set_signature(ide); - - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->error = 1; - zip_reset(zip[zip_id]); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->error = 1; - cdrom_reset(cdrom[cdrom_id]); - } - ide_irq_raise(ide); - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - ide->service = 0; - return; - - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: - if (ide_drive_is_zip(ide)) - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - else - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide_drive_is_zip(ide)) { - zip[zip_id]->phase = 0xFF; - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->phase = 0xFF; - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - } - ide->secount = 0xFF; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_READ: - case WIN_READ_NORETRY: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) { - ide_set_signature(ide); - goto abort_cmd; - } - if (ide->cfg_spt == 0) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); - - ide->sector_pos++; - ide->pos = 0; - - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; - - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || (ide->board >= 2)) { - ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); - goto abort_cmd; - } - if (ide->cfg_spt == 0) { - ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - ide->sector_pos = 0; - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->pos=0; - - if (ide_bus_master_read) { - /* We should not abort - we should simply wait for the host to start DMA. */ - ret = ide_bus_master_read(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - ide_bus_master_priv[ide->board]); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6LL * IDE_TIME); - return; - } else if (ret == 1) { - /* Bus master DMAS error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } else { - /*DMA successful*/ - ide_log("IDE %i: DMA read successful\n", ide->channel); - - ide->atastat = DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } else { - ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } - return; - - case WIN_READ_MULTIPLE: - /* According to the official ATA reference: - - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || !ide->blocksize) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); - - ide->sector_pos++; - ide->pos=0; - - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - if (!ide->blockcount) - ide_irq_raise(ide); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize) - ide->blockcount = 0; - return; - - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide_irq_raise(ide); - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; - - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || (ide->board >= 2)) { - ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); - goto abort_cmd; - } - if (ide->cfg_spt == 0) { - ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - if (ide_bus_master_read) { - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - - ret = ide_bus_master_write(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - ide_bus_master_priv[ide->board]); - - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6LL * IDE_TIME); - return; - } else if (ret == 1) { - /* Bus master DMA error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } else { - /*DMA successful*/ - ide_log("IDE %i: DMA write successful\n", ide->channel); - - hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->atastat = DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } else { - ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } - - return; - - case WIN_WRITE_MULTIPLE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize || ide->secount == 1) { - ide->blockcount = 0; - ide_irq_raise(ide); - } - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; - - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - ide->pos=0; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; - - case WIN_FORMAT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); - - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - return; - - case WIN_DRIVE_DIAGNOSTICS: - ide_set_signature(ide); - ide->error=1; /*No error detected*/ - - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = 0; - zip[zip_id]->error = 1; - ide_irq_raise(ide); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = 0; - cdrom[cdrom_id]->error = 1; - ide_irq_raise(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - } - - ide_set_signature(ide_other); - ide_other->error=1; /*No error detected*/ - - if (ide_drive_is_zip(ide_other)) { - zip[zip_id_other]->status = 0; - zip[zip_id_other]->error = 1; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[cdrom_id_other]->status = 0; - cdrom[cdrom_id_other]->error = 1; - } else { - ide_other->atastat = DRDY_STAT | DSC_STAT; - ide_other->error = 1; - } - - ide_boards[ide->board]->cur_dev &= ~1; - ch = ide_boards[ide->board]->cur_dev; - return; - - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - ide->cfg_spt = ide->secount; - ide->cfg_hpc = ide->head + 1; - } - ide->command = 0x00; - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - return; - - case WIN_PIDENTIFY: /* Identify Packet Device */ - if (ide_drive_is_zip(ide)) { - ide_identify(ide); - ide->pos = 0; - zip[zip_id]->phase = 2; - zip[zip_id]->pos = 0; - zip[zip_id]->error = 0; - zip[zip_id]->status = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } else if (ide_drive_is_cdrom(ide)) { - ide_identify(ide); - ide->pos = 0; - cdrom[cdrom_id]->phase = 2; - cdrom[cdrom_id]->pos = 0; - cdrom[cdrom_id]->error = 0; - cdrom[cdrom_id]->status = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } - goto abort_cmd; - - case WIN_SET_MULTIPLE_MODE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - ide->blocksize = ide->secount; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_SET_FEATURES: - if (ide->type == IDE_NONE) - goto abort_cmd; - - if (!ide_set_features(ide)) - goto abort_cmd; - else { - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->pos = 0; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; - - case WIN_READ_NATIVE_MAX: - if (ide->type != IDE_HDD) - goto abort_cmd; - snum = hdd[ide->hdd_num].spt; - snum *= hdd[ide->hdd_num].hpc; - snum *= hdd[ide->hdd_num].tracks; - ide_set_sector(ide, snum - 1); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_IDENTIFY: /* Identify Device */ - if (ide->type != IDE_HDD) { - ide_set_signature(ide); - goto abort_cmd; - } else { - ide_identify(ide); - ide->pos=0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; - - case WIN_PACKETCMD: /* ATAPI Packet */ - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - goto abort_cmd; - - if (ide_drive_is_zip(ide)) - zip_phase_callback(zip[atapi_zip_drives[ch]]); - else - cdrom_phase_callback(cdrom[atapi_cdrom_drives[ch]]); - return; - - case 0xFF: - goto abort_cmd; - } - -abort_cmd: - ide->command = 0; - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - zip[zip_id]->error = ABRT_ERR; - zip[zip_id]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - cdrom[cdrom_id]->error = ABRT_ERR; - cdrom[cdrom_id]->pos = 0; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; - } - ide_irq_raise(ide); - return; - -id_not_found: - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = IDNF_ERR; - ide->pos = 0; - ide_irq_raise(ide); -} - - -static void -ide_set_handlers(uint8_t board) -{ - if (ide_base_main[board] & 0x300) { - if (ide_boards[board]->bit32) { - io_sethandler(ide_base_main[board], 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_sethandler(ide_base_main[board], 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } - io_sethandler(ide_base_main[board] + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, - ide_boards[board]); - } - if (ide_side_main[board] & 0x300) { - io_sethandler(ide_side_main[board], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); - } -} - - -static void -ide_remove_handlers(uint8_t board) -{ - if (ide_boards[board]->bit32) { - io_removehandler(ide_base_main[board], 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_removehandler(ide_base_main[board], 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } - io_removehandler(ide_base_main[board] + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, - ide_boards[board]); - io_removehandler(ide_side_main[board], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); -} - - -void -ide_pri_enable(void) -{ - ide_set_handlers(0); -} - - -void -ide_pri_disable(void) -{ - ide_remove_handlers(0); -} - - -void -ide_sec_enable(void) -{ - ide_set_handlers(1); -} - - -void -ide_sec_disable(void) -{ - ide_remove_handlers(1); -} - - -void -ide_set_base(int controller, uint16_t port) -{ - ide_base_main[controller] = port; -} - - -void -ide_set_side(int controller, uint16_t port) -{ - ide_side_main[controller] = port; -} - - -static void * -ide_ter_init(const device_t *info) -{ - ide_boards[2] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[2], 0, sizeof(ide_board_t)); - - ide_boards[2]->irq = device_get_config_int("irq"); - ide_boards[2]->cur_dev = 4; - - ide_set_handlers(2); - - timer_add(ide_callback, &ide_boards[2]->callback, &ide_boards[2]->callback, ide_boards[2]); - - ide_board_init(2); - - return(ide_drives); -} - - -/* Close a standalone IDE unit. */ -static void -ide_ter_close(void *priv) -{ - if (ide_boards[2]) { - free(ide_boards[2]); - ide_boards[2] = NULL; - - ide_board_close(2); - } -} - - -static void * -ide_qua_init(const device_t *info) -{ - ide_boards[3] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[3], 0, sizeof(ide_board_t)); - - ide_boards[3]->irq = device_get_config_int("irq"); - ide_boards[3]->cur_dev = 6; - - ide_set_handlers(3); - - timer_add(ide_callback, &ide_boards[3]->callback, &ide_boards[3]->callback, ide_boards[3]); - - ide_board_init(3); - - return(ide_drives); -} - - -/* Close a standalone IDE unit. */ -static void -ide_qua_close(void *priv) -{ - if (ide_boards[3]) { - free(ide_boards[3]); - ide_boards[3] = NULL; - - ide_board_close(3); - } -} - - -static void -ide_clear_bus_master(void) -{ - ide_bus_master_read = ide_bus_master_write = NULL; - ide_bus_master_set_irq = NULL; - ide_bus_master_priv[0] = ide_bus_master_priv[1] = NULL; -} - - -void * -ide_xtide_init(void) -{ - ide_clear_bus_master(); - - if (!ide_boards[0]) { - ide_boards[0] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[0], 0, sizeof(ide_board_t)); - ide_boards[0]->cur_dev = 0; - - timer_add(ide_callback, &ide_boards[0]->callback, &ide_boards[0]->callback, - ide_boards[0]); - - ide_board_init(0); - } - ide_boards[0]->irq = -1; - - return ide_boards[0]; -} - - -void -ide_xtide_close(void) -{ - if (ide_boards[0]) { - free(ide_boards[0]); - ide_boards[0] = NULL; - - ide_board_close(0); - } -} - - -void -ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv), - int (*write)(int channel, uint8_t *data, int transfer_length, void *priv), - void (*set_irq)(int channel, void *priv), - void *priv0, void *priv1) -{ - ide_bus_master_read = read; - ide_bus_master_write = write; - ide_bus_master_set_irq = set_irq; - ide_bus_master_priv[0] = priv0; - ide_bus_master_priv[1] = priv1; -} - - -void -secondary_ide_check(void) -{ - int i = 0; - int secondary_cdroms = 0; - int secondary_zips = 0; - - for (i=0; i= 2) && (zip_drives[i].ide_channel <= 3) && - (zip_drives[i].bus_type == ZIP_BUS_ATAPI)) - secondary_zips++; - } - for (i=0; i= 2) && (cdrom_drives[i].ide_channel <= 3) && - (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI)) - secondary_cdroms++; - } - if (!secondary_zips && !secondary_cdroms) - ide_remove_handlers(1); -} - - -/* - * Initialization of standalone IDE controller instance. - * - * Eventually, we should clean up the whole mess by only - * using const device_t units, with configuration parameters to - * indicate primary/secondary and all that, rather than - * keeping a zillion of duplicate functions around. - */ -static void * -ide_sainit(const device_t *info) -{ - ide_log("Initializing IDE...\n"); - - switch(info->local) { - case 0: /* ISA, single-channel */ - case 2: /* ISA, dual-channel */ - case 3: /* ISA, dual-channel, optional 2nd channel */ - case 4: /* VLB, single-channel */ - case 6: /* VLB, dual-channel */ - case 8: /* PCI, single-channel */ - case 10: /* PCI, dual-channel */ - if (!ide_inited) { - if (!(info->local & 8)) - ide_clear_bus_master(); - } - - if (!(ide_inited & 1)) { - ide_boards[0] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[0], 0, sizeof(ide_board_t)); - ide_boards[0]->irq = 14; - ide_boards[0]->cur_dev = 0; - if (info->local & 8) - ide_boards[0]->bit32 = 1; - ide_base_main[0] = 0x1f0; - ide_side_main[0] = 0x3f6; - ide_set_handlers(0); - timer_add(ide_callback, &ide_boards[0]->callback, &ide_boards[0]->callback, - ide_boards[0]); - ide_log("Callback 0 pointer: %08X\n", &ide_boards[0]->callback); - - ide_board_init(0); - - ide_inited |= 1; - } - - if ((info->local & 3) && !(ide_inited & 2)) { - ide_boards[1] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[1], 0, sizeof(ide_board_t)); - ide_boards[1]->irq = 15; - ide_boards[1]->cur_dev = 2; - if (info->local & 8) - ide_boards[1]->bit32 = 1; - ide_base_main[1] = 0x170; - ide_side_main[1] = 0x376; - ide_set_handlers(1); - timer_add(ide_callback, &ide_boards[1]->callback, &ide_boards[1]->callback, - ide_boards[1]); - ide_log("Callback 1 pointer: %08X\n", &ide_boards[1]->callback); - - ide_board_init(1); - - if (info->local & 1) - secondary_ide_check(); - - ide_inited |= 2; - } - break; - } - - return(ide_drives); -} - - -static void -ide_drive_reset(int d) -{ - ide_drives[d]->channel = d; - ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; - ide_drives[d]->service = 0; - ide_drives[d]->board = d >> 1; - - if (ide_boards[d >> 1]) { - ide_boards[d >> 1]->cur_dev = d & ~1; - ide_boards[d >> 1]->callback = 0LL; - } - - ide_set_signature(ide_drives[d]); - - if (ide_drives[d]->sector_buffer) - memset(ide_drives[d]->sector_buffer, 0, 256*512); - - if (ide_drives[d]->buffer) - memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t)); -} - - -/* Reset a standalone IDE unit. */ -static void -ide_sareset(void *p) -{ - int d; - - ide_log("Resetting IDE...\n"); - - if (ide_inited & 1) { - for (d = 0; d < 2; d++) - ide_drive_reset(d); - } - - if (ide_inited & 2) { - for (d = 2; d < 4; d++) - ide_drive_reset(d); - } -} - - -/* Close a standalone IDE unit. */ -static void -ide_saclose(void *priv) -{ - ide_log("Closing IDE...\n"); - - if ((ide_inited & 1) && (ide_boards[0])) { - free(ide_boards[0]); - ide_boards[0] = NULL; - - ide_board_close(0); - } - - if ((ide_inited & 2) && (ide_boards[1])) { - free(ide_boards[1]); - ide_boards[1] = NULL; - - ide_board_close(1); - } - - ide_inited = 0; -} - - -const device_t ide_isa_device = { - "ISA PC/AT IDE Controller", - DEVICE_ISA | DEVICE_AT, - 0, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_isa_2ch_device = { - "ISA PC/AT IDE Controller (Dual-Channel)", - DEVICE_ISA | DEVICE_AT, - 2, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_isa_2ch_opt_device = { - "ISA PC/AT IDE Controller (Single/Dual)", - DEVICE_ISA | DEVICE_AT, - 3, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_vlb_device = { - "VLB IDE Controller", - DEVICE_VLB | DEVICE_AT, - 4, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_vlb_2ch_device = { - "VLB IDE Controller (Dual-Channel)", - DEVICE_VLB | DEVICE_AT, - 6, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_pci_device = { - "PCI IDE Controller", - DEVICE_PCI | DEVICE_AT, - 8, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_pci_2ch_device = { - "PCI IDE Controller (Dual-Channel)", - DEVICE_PCI | DEVICE_AT, - 10, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -static const device_config_t ide_ter_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t ide_qua_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 11, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t ide_ter_device = { - "Tertiary IDE Controller", - DEVICE_AT, - 0, - ide_ter_init, ide_ter_close, NULL, - NULL, NULL, NULL, - ide_ter_config -}; - -const device_t ide_qua_device = { - "Quaternary IDE Controller", - DEVICE_AT, - 0, - ide_qua_init, ide_qua_close, NULL, - NULL, NULL, NULL, - ide_qua_config -}; diff --git a/src - Cópia/disk/hdc_ide.h b/src - Cópia/disk/hdc_ide.h deleted file mode 100644 index 69a81276d..000000000 --- a/src - Cópia/disk/hdc_ide.h +++ /dev/null @@ -1,93 +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. - * - * Implementation of the IDE emulation for hard disks and ATAPI - * CD-ROM devices. - * - * Version: @(#)hdd_ide.h 1.0.10 2018/05/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef EMU_IDE_H -# define EMU_IDE_H - - -typedef struct { - uint8_t atastat, error, - command, fdisk; - int type, board, - irqstat, service, - blocksize, blockcount, - hdd_num, channel, - pos, sector_pos, - lba, skip512, - reset, tracks, - spt, hpc, - mdma_mode, do_initial_read; - uint32_t secount, sector, - cylinder, head, - drive, cylprecomp, - cfg_spt, cfg_hpc, - lba_addr; - - uint16_t *buffer; - uint8_t *sector_buffer; -} ide_t; - - -extern int ideboard; -extern int ide_ter_enabled, ide_qua_enabled; - -extern ide_t *ide_drives[IDE_NUM]; -extern int64_t idecallback[5]; - - -extern void ide_irq_raise(ide_t *ide); -extern void ide_irq_lower(ide_t *ide); - -extern void * ide_xtide_init(void); -extern void ide_xtide_close(void); - -extern void ide_writew(uint16_t addr, uint16_t val, void *priv); -extern void ide_write_devctl(uint16_t addr, uint8_t val, void *priv); -extern void ide_writeb(uint16_t addr, uint8_t val, void *priv); -extern uint8_t ide_readb(uint16_t addr, void *priv); -extern uint8_t ide_read_alt_status(uint16_t addr, void *priv); -extern uint16_t ide_readw(uint16_t addr, void *priv); - -extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv), - int (*write)(int channel, uint8_t *data, int transfer_length, void *priv), - void (*set_irq)(int channel, void *priv), - void *priv0, void *priv1); - -extern void win_cdrom_eject(uint8_t id); -extern void win_cdrom_reload(uint8_t id); - -extern void ide_set_base(int controller, uint16_t port); -extern void ide_set_side(int controller, uint16_t port); - -extern void ide_pri_enable(void); -extern void ide_pri_disable(void); -extern void ide_sec_enable(void); -extern void ide_sec_disable(void); - -extern void ide_set_callback(uint8_t channel, int64_t callback); -extern void secondary_ide_check(void); - -extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; - - -#endif /*EMU_IDE_H*/ diff --git a/src - Cópia/disk/hdc_mfm_at.c b/src - Cópia/disk/hdc_mfm_at.c deleted file mode 100644 index de2bf728e..000000000 --- a/src - Cópia/disk/hdc_mfm_at.c +++ /dev/null @@ -1,769 +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. - * - * Driver for the IBM PC-AT MFM/RLL Fixed Disk controller. - * - * This controller was a 16bit ISA card, and it used a WD1003 - * based design. Most cards were WD1003-WA2 or -WAH, where the - * -WA2 cards had a floppy controller as well (to save space.) - * - * Version: @(#)hdc_mfm_at.c 1.0.17 2018/05/02 - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#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 "hdc.h" -#include "hdd.h" - - -#define MFM_TIME (TIMER_USEC*10LL) - -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_ECC 0x04 -#define STAT_DRQ 0x08 /* data request */ -#define STAT_DSC 0x10 -#define STAT_WRFLT 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 - -#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ -#define ERR_TR000 0x02 /* track 0 not found */ -#define ERR_ABRT 0x04 /* command aborted */ -#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ -#define ERR_DATA_CRC 0x40 /* data CRC error */ -#define ERR_BAD_BLOCK 0x80 /* bad block detected */ - -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 - - -typedef struct { - int8_t present, /* drive is present */ - hdd_num, /* drive number in system */ - steprate, /* current servo step rate */ - spt, /* physical #sectors per track */ - hpc, /* physical #heads per cylinder */ - pad; - int16_t tracks; /* physical #tracks per cylinder */ - - int8_t cfg_spt, /* configured #sectors per track */ - cfg_hpc; /* configured #heads per track */ - - int16_t curcyl; /* current track number */ -} drive_t; - - -typedef struct { - uint8_t precomp, /* 1: precomp/error register */ - error, - secount, /* 2: sector count register */ - sector, /* 3: sector number */ - head, /* 6: head number + drive select */ - command, /* 7: command/status */ - status, - fdisk; /* 8: control register */ - uint16_t cylinder; /* 4/5: cylinder LOW and HIGH */ - - int8_t reset, /* controller in reset */ - irqstat, /* current IRQ status */ - drvsel, /* current selected drive */ - pad; - - int pos; /* offset within data buffer */ - int64_t callback; /* callback delay timer */ - - uint16_t buffer[256]; /* data buffer (16b wide) */ - - drive_t drives[MFM_NUM]; /* attached drives */ -} mfm_t; - - -#ifdef ENABLE_MFM_AT_LOG -int mfm_at_do_log = ENABLE_MFM_AT_LOG; -#endif - - -static void -mfm_at_log(const char *fmt, ...) -{ -#ifdef ENABLE_MFM_AT_LOG - va_list ap; - - if (mfm_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static inline void -irq_raise(mfm_t *mfm) -{ - if (!(mfm->fdisk & 2)) - picint(1 << 14); - - mfm->irqstat = 1; -} - - -static inline void -irq_lower(mfm_t *mfm) -{ - if (mfm->irqstat) { - if (!(mfm->fdisk & 2)) - picintc(1 << 14); - - mfm->irqstat = 0; - } -} - - -/* - * Return the sector offset for the current register values. - * - * According to the WD1002/WD1003 technical reference manual, - * this is not done entirely correct. It specifies that the - * parameters set with the SET_DRIVE_PARAMETERS command are - * to be used only for multi-sector operations, and that any - * such operation can only be executed AFTER these parameters - * have been set. This would imply that for regular single - * transfers, the controller uses (or, can use) the actual - * geometry information... - */ -static int -get_sector(mfm_t *mfm, off64_t *addr) -{ - drive_t *drive = &mfm->drives[mfm->drvsel]; - - if (drive->curcyl != mfm->cylinder) { - mfm_at_log("WD1003(%d) sector: wrong cylinder\n"); - return(1); - } - - if (mfm->head > drive->cfg_hpc) { - mfm_at_log("WD1003(%d) get_sector: past end of configured heads\n", - mfm->drvsel); - return(1); - } - - if (mfm->sector >= drive->cfg_spt+1) { - mfm_at_log("WD1003(%d) get_sector: past end of configured sectors\n", - mfm->drvsel); - return(1); - } - -#if 1 - /* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */ - if (mfm->head > drive->hpc) { - mfm_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); - return(1); - } - - if (mfm->sector >= drive->spt+1) { - mfm_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); - return(1); - } -#endif - - *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * - drive->cfg_spt) + (mfm->sector - 1); - - return(0); -} - - -/* Move to the next sector using CHS addressing. */ -static void -next_sector(mfm_t *mfm) -{ - drive_t *drive = &mfm->drives[mfm->drvsel]; - - if (++mfm->sector == (drive->cfg_spt+1)) { - mfm->sector = 1; - if (++mfm->head == drive->cfg_hpc) { - mfm->head = 0; - mfm->cylinder++; - if (drive->curcyl < drive->tracks) - drive->curcyl++; - } - } -} - - -static void -mfm_cmd(mfm_t *mfm, uint8_t val) -{ - drive_t *drive = &mfm->drives[mfm->drvsel]; - - if (! drive->present) { - /* This happens if sofware polls all drives. */ - mfm_at_log("WD1003(%d) command %02x on non-present drive\n", - mfm->drvsel, val); - mfm->command = 0xff; - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - - return; - } - - irq_lower(mfm); - mfm->command = val; - mfm->error = 0; - - switch (val & 0xf0) { - case CMD_RESTORE: - drive->steprate = (val & 0x0f); - mfm_at_log("WD1003(%d) restore, step=%d\n", - mfm->drvsel, drive->steprate); - drive->curcyl = 0; - mfm->status = STAT_READY|STAT_DSC; - mfm->command &= 0xf0; - irq_raise(mfm); - break; - - case CMD_SEEK: - drive->steprate = (val & 0x0f); - mfm->command &= 0xf0; - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - break; - - default: - mfm->command = val; - switch (val) { - case CMD_READ: - case CMD_READ+1: - case CMD_READ+2: - case CMD_READ+3: - mfm_at_log("WD1003(%d) read, opt=%d\n", - mfm->drvsel, val&0x03); - mfm->command &= 0xfc; - if (val & 2) - fatal("WD1003: READ with ECC\n"); - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - break; - - case CMD_WRITE: - case CMD_WRITE+1: - case CMD_WRITE+2: - case CMD_WRITE+3: - mfm_at_log("WD1003(%d) write, opt=%d\n", - mfm->drvsel, val & 0x03); - mfm->command &= 0xfc; - if (val & 2) - fatal("WD1003: WRITE with ECC\n"); - mfm->status = STAT_DRQ|STAT_DSC; - mfm->pos = 0; - break; - - case CMD_VERIFY: - case CMD_VERIFY+1: - mfm->command &= 0xfe; - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - break; - - case CMD_FORMAT: - mfm->status = STAT_DRQ|STAT_BUSY; - mfm->pos = 0; - break; - - case CMD_DIAGNOSE: - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - break; - - case CMD_SET_PARAMETERS: - /* - * NOTE: - * - * We currently just set these parameters, and - * never bother to check if they "fit within" - * the actual parameters, as determined by the - * image loader. - * - * The difference in parameters is OK, and - * occurs when the BIOS or operating system - * decides to use a different translation - * scheme, but either way, it SHOULD always - * fit within the actual parameters! - * - * We SHOULD check that here!! --FvK - */ - if (drive->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head+1; - mfm_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } else { - mfm_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } - mfm->command = 0x00; - mfm->status = STAT_READY|STAT_DSC; - mfm->error = 1; - irq_raise(mfm); - break; - - default: - mfm_at_log("WD1003: bad command %02X\n", val); - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*MFM_TIME; - timer_update_outstanding(); - break; - } - } -} - - -static void -mfm_writew(uint16_t port, uint16_t val, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - - mfm->buffer[mfm->pos >> 1] = val; - mfm->pos += 2; - - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_BUSY; - timer_clock(); - /* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */ - mfm->callback = ((3125LL * TIMER_USEC) / 4LL); - /* mfm->callback = 10LL * MFM_TIME; */ - timer_update_outstanding(); - } -} - - -static void -mfm_write(uint16_t port, uint8_t val, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - - mfm_at_log("WD1003 write(%04x, %02x)\n", port, val); - - switch (port) { - case 0x01f0: /* data */ - mfm_writew(port, val | (val << 8), priv); - return; - - case 0x01f1: /* write precompenstation */ - mfm->precomp = val; - return; - - case 0x01f2: /* sector count */ - mfm->secount = val; - return; - - case 0x01f3: /* sector */ - mfm->sector = val; - return; - - case 0x01f4: /* cylinder low */ - mfm->cylinder = (mfm->cylinder & 0xff00) | val; - return; - - case 0x01f5: /* cylinder high */ - mfm->cylinder = (mfm->cylinder & 0xff) | (val << 8); - return; - - case 0x01f6: /* drive/head */ - mfm->head = val & 0xF; - mfm->drvsel = (val & 0x10) ? 1 : 0; - if (mfm->drives[mfm->drvsel].present) - mfm->status = STAT_READY|STAT_DSC; - else - mfm->status = 0; - return; - - case 0x01f7: /* command register */ - mfm_cmd(mfm, val); - break; - - case 0x03f6: /* device control */ - val &= 0x0f; - if ((mfm->fdisk & 0x04) && !(val & 0x04)) { - timer_clock(); - mfm->callback = 500LL*MFM_TIME; - timer_update_outstanding(); - mfm->reset = 1; - mfm->status = STAT_BUSY; - } - - if (val & 0x04) { - /* Drive held in reset. */ - timer_clock(); - mfm->callback = 0LL; - timer_update_outstanding(); - mfm->status = STAT_BUSY; - } - mfm->fdisk = val; - /* Lower IRQ on IRQ disable. */ - if ((val & 2) && !(mfm->fdisk & 0x02)) - picintc(1 << 14); - break; - } -} - - -static uint16_t -mfm_readw(uint16_t port, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - uint16_t ret; - - ret = mfm->buffer[mfm->pos >> 1]; - mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - if (mfm->command == CMD_READ) { - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - next_sector(mfm); - mfm->status = STAT_BUSY; - timer_clock(); - /* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */ - mfm->callback = ((3125LL * TIMER_USEC) / 4LL); - /* mfm->callback = 10LL * MFM_TIME; */ - timer_update_outstanding(); - } else { - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - } - } - } - - return(ret); -} - - -static uint8_t -mfm_read(uint16_t port, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x01f0: /* data */ - ret = mfm_readw(port, mfm) & 0xff; - break; - - case 0x01f1: /* error */ - ret = mfm->error; - break; - - case 0x01f2: /* sector count */ - ret = mfm->secount; - break; - - case 0x01f3: /* sector */ - ret = mfm->sector; - break; - - case 0x01f4: /* CYlinder low */ - ret = (uint8_t)(mfm->cylinder&0xff); - break; - - case 0x01f5: /* Cylinder high */ - ret = (uint8_t)(mfm->cylinder>>8); - break; - - case 0x01f6: /* drive/head */ - ret = (uint8_t)(0xa0 | mfm->head | (mfm->drvsel?0x10:0)); - break; - - case 0x01f7: /* Status */ - irq_lower(mfm); - ret = mfm->status; - break; - - default: - break; - } - - mfm_at_log("WD1003 read(%04x) = %02x\n", port, ret); - - return(ret); -} - - -static void -do_seek(mfm_t *mfm) -{ - drive_t *drive = &mfm->drives[mfm->drvsel]; - - mfm_at_log("WD1003(%d) seek(%d) max=%d\n", - mfm->drvsel,mfm->cylinder,drive->tracks); - - if (mfm->cylinder < drive->tracks) - drive->curcyl = mfm->cylinder; - else - drive->curcyl = drive->tracks-1; -} - - -static void -do_callback(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - drive_t *drive = &mfm->drives[mfm->drvsel]; - off64_t addr; - - mfm->callback = 0LL; - if (mfm->reset) { - mfm_at_log("WD1003(%d) reset\n", mfm->drvsel); - - mfm->status = STAT_READY|STAT_DSC; - mfm->error = 1; - mfm->secount = 1; - mfm->sector = 1; - mfm->head = 0; - mfm->cylinder = 0; - - drive->steprate = 0x0f; /* default steprate */ - drive->cfg_spt = 0; /* need new parameters */ - - mfm->reset = 0; - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - - return; - } - - switch (mfm->command) { - case CMD_SEEK: - mfm_at_log("WD1003(%d) seek, step=%d\n", - mfm->drvsel, drive->steprate); - do_seek(mfm); - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - case CMD_READ: - mfm_at_log("WD1003(%d) read(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)mfm->buffer); - - mfm->pos = 0; - mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_WRITE: - mfm_at_log("WD1003(%d) write(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer); - irq_raise(mfm); - mfm->secount = (mfm->secount - 1) & 0xff; - - mfm->status = STAT_READY|STAT_DSC; - if (mfm->secount) { - /* More sectors to do.. */ - mfm->status |= STAT_DRQ; - mfm->pos = 0; - next_sector(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - } else - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - break; - - case CMD_VERIFY: - mfm_at_log("WD1003(%d) verify(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_FORMAT: - mfm_at_log("WD1003(%d) format(%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_zero(drive->hdd_num, addr, mfm->secount); - - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_DIAGNOSE: - mfm_at_log("WD1003(%d) diag\n", mfm->drvsel); - drive->steprate = 0x0f; - mfm->error = 1; - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - default: - mfm_at_log("WD1003(%d) callback on unknown command %02x\n", - mfm->drvsel, mfm->command); - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } -} - - -static void -loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) -{ - drive_t *drive = &mfm->drives[c]; - - if (! hdd_image_load(d)) { - drive->present = 0; - - return; - } - - drive->spt = hdd[d].spt; - drive->hpc = hdd[d].hpc; - drive->tracks = hdd[d].tracks; - drive->hdd_num = d; - drive->present = 1; -} - - -static void * -mfm_init(const device_t *info) -{ - mfm_t *mfm; - int c, d; - - mfm_at_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n"); - mfm = malloc(sizeof(mfm_t)); - memset(mfm, 0x00, sizeof(mfm_t)); - - c = 0; - for (d=0; d= MFM_NUM) break; - } - } - - mfm->status = STAT_READY|STAT_DSC; /* drive is ready */ - mfm->error = 1; /* no errors */ - - io_sethandler(0x01f0, 1, - mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); - io_sethandler(0x01f1, 7, - mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); - io_sethandler(0x03f6, 1, - NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); - - timer_add(do_callback, &mfm->callback, &mfm->callback, mfm); - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - - return(mfm); -} - - -static void -mfm_close(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - int d; - - for (d=0; d<2; d++) { - drive_t *drive = &mfm->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - free(mfm); - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); -} - - -const device_t mfm_at_wd1003_device = { - "WD1003 AT MFM/RLL Controller", - DEVICE_ISA | DEVICE_AT, - 0, - mfm_init, mfm_close, NULL, - NULL, NULL, NULL, NULL -}; diff --git a/src - Cópia/disk/hdc_mfm_xt.c b/src - Cópia/disk/hdc_mfm_xt.c deleted file mode 100644 index 6d86fe070..000000000 --- a/src - Cópia/disk/hdc_mfm_xt.c +++ /dev/null @@ -1,949 +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. - * - * Driver for the IBM PC-XT Fixed Disk controller. - * - * The original controller shipped by IBM was made by Xebec, and - * several variations had been made: - * - * #1 Original, single drive (ST412), 10MB, 2 heads. - * #2 Update, single drive (ST412) but with option for a - * switch block that can be used to 'set' the actual - * drive type. Four switches are define, where switches - * 1 and 2 define drive0, and switches 3 and 4 drive1. - * - * 0 ON ON 306 2 0 - * 1 ON OFF 375 8 0 - * 2 OFF ON 306 6 256 - * 3 OFF OFF 306 4 0 - * - * The latter option is the default, in use on boards - * without the switch block option. - * - * #3 Another updated board, mostly to accomodate the new - * 20MB disk now being shipped. The controller can have - * up to 2 drives, the type of which is set using the - * switch block: - * - * SW1 SW2 CYLS HD SPT WPC - * 0 ON ON 306 4 17 0 - * 1 ON OFF 612 4 17 0 (type 16) - * 2 OFF ON 615 4 17 300 (Seagate ST-225, 2) - * 3 OFF OFF 306 8 17 128 (IBM WD25, 13) - * - * Examples of #3 are IBM/Xebec, WD10004A-WX1 and ST11R. - * - * Since all controllers (including the ones made by DTC) use - * (mostly) the same API, we keep them all in this module. - * - * Version: @(#)hdc_mfm_xt.c 1.0.17 2018/04/29 - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../dma.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdd.h" - - -// #define MFM_TIME (2000LL*TIMER_USEC) -#define MFM_TIME (50LL*TIMER_USEC) -#define XEBEC_BIOS_FILE L"roms/hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin" -#define DTC_BIOS_FILE L"roms/hdd/mfm_xebec/dtc_cxd21a.bin" - - -enum { - STATE_IDLE, - STATE_RECEIVE_COMMAND, - STATE_START_COMMAND, - STATE_RECEIVE_DATA, - STATE_RECEIVED_DATA, - STATE_SEND_DATA, - STATE_SENT_DATA, - STATE_COMPLETION_BYTE, - STATE_DUNNO -}; - - -typedef struct { - int spt, hpc; - int tracks; - int cfg_spt; - int cfg_hpc; - int cfg_cyl; - int current_cylinder; - int present; - int hdd_num; -} drive_t; - -typedef struct { - rom_t bios_rom; - int64_t callback; - int state; - uint8_t status; - uint8_t command[6]; - int command_pos; - uint8_t data[512]; - int data_pos, data_len; - uint8_t sector_buf[512]; - uint8_t irq_dma_mask; - uint8_t completion_byte; - uint8_t error; - int drive_sel; - drive_t drives[2]; - int sector, head, cylinder; - int sector_count; - uint8_t switches; -} mfm_t; - -#define STAT_IRQ 0x20 -#define STAT_DRQ 0x10 -#define STAT_BSY 0x08 -#define STAT_CD 0x04 -#define STAT_IO 0x02 -#define STAT_REQ 0x01 - -#define IRQ_ENA 0x02 -#define DMA_ENA 0x01 - -#define CMD_TEST_DRIVE_READY 0x00 -#define CMD_RECALIBRATE 0x01 -#define CMD_READ_STATUS 0x03 -#define CMD_VERIFY_SECTORS 0x05 -#define CMD_FORMAT_TRACK 0x06 -#define CMD_READ_SECTORS 0x08 -#define CMD_WRITE_SECTORS 0x0a -#define CMD_SEEK 0x0b -#define CMD_INIT_DRIVE_PARAMS 0x0c -#define CMD_WRITE_SECTOR_BUFFER 0x0f -#define CMD_BUFFER_DIAGNOSTIC 0xe0 -#define CMD_CONTROLLER_DIAGNOSTIC 0xe4 -#define CMD_DTC_GET_DRIVE_PARAMS 0xfb -#define CMD_DTC_SET_STEP_RATE 0xfc -#define CMD_DTC_SET_GEOMETRY 0xfe -#define CMD_DTC_GET_GEOMETRY 0xff - -#define ERR_NOT_READY 0x04 -#define ERR_SEEK_ERROR 0x15 -#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21 - - -#ifdef ENABLE_MFM_XT_LOG -int mfm_xt_do_log = ENABLE_MFM_XT_LOG; -#endif - - -static void -mfm_xt_log(const char *fmt, ...) -{ -#ifdef ENABLE_MFM_XT_LOG - va_list ap; - - if (mfm_xt_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static uint8_t -mfm_read(uint16_t port, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - uint8_t temp = 0xff; - - switch (port) { - case 0x320: /*Read data*/ - mfm->status &= ~STAT_IRQ; - switch (mfm->state) { - case STATE_COMPLETION_BYTE: - if ((mfm->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", mfm->status); - - temp = mfm->completion_byte; - mfm->status = 0; - mfm->state = STATE_IDLE; - break; - - case STATE_SEND_DATA: - if ((mfm->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", mfm->status); - if (mfm->data_pos >= mfm->data_len) - fatal("Data write with full data!\n"); - temp = mfm->data[mfm->data_pos++]; - if (mfm->data_pos == mfm->data_len) { - mfm->status = STAT_BSY; - mfm->state = STATE_SENT_DATA; - mfm->callback = MFM_TIME; - } - break; - - default: - fatal("Read data register - %i, %02x\n", mfm->state, mfm->status); - } - break; - - case 0x321: /*Read status*/ - temp = mfm->status; - break; - - case 0x322: /*Read option jumpers*/ - temp = mfm->switches; - break; - } - - return(temp); -} - - -static void -mfm_write(uint16_t port, uint8_t val, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - - switch (port) { - case 0x320: /*Write data*/ - switch (mfm->state) { - case STATE_RECEIVE_COMMAND: - if ((mfm->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) - fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", mfm->status); - if (mfm->command_pos >= 6) - fatal("Command write with full command!\n"); - /*Command data*/ - mfm->command[mfm->command_pos++] = val; - if (mfm->command_pos == 6) { - mfm->status = STAT_BSY; - mfm->state = STATE_START_COMMAND; - mfm->callback = MFM_TIME; - } - break; - - case STATE_RECEIVE_DATA: - if ((mfm->status & 0xf) != (STAT_BSY | STAT_REQ)) - fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", mfm->status); - if (mfm->data_pos >= mfm->data_len) - fatal("Data write with full data!\n"); - /*Command data*/ - mfm->data[mfm->data_pos++] = val; - if (mfm->data_pos == mfm->data_len) { - mfm->status = STAT_BSY; - mfm->state = STATE_RECEIVED_DATA; - mfm->callback = MFM_TIME; - } - break; - - default: - fatal("Write data unknown state - %i %02x\n", mfm->state, mfm->status); - } - break; - - case 0x321: /*Controller reset*/ - mfm->status = 0; - break; - - case 0x322: /*Generate controller-select-pulse*/ - mfm->status = STAT_BSY | STAT_CD | STAT_REQ; - mfm->command_pos = 0; - mfm->state = STATE_RECEIVE_COMMAND; - break; - - case 0x323: /*DMA/IRQ mask register*/ - mfm->irq_dma_mask = val; - break; - } -} - - -static void mfm_complete(mfm_t *mfm) -{ - mfm->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; - mfm->state = STATE_COMPLETION_BYTE; - - if (mfm->irq_dma_mask & IRQ_ENA) { - mfm->status |= STAT_IRQ; - picint(1 << 5); - } -} - - -static void -mfm_error(mfm_t *mfm, uint8_t error) -{ - mfm->completion_byte |= 0x02; - mfm->error = error; - - mfm_xt_log("mfm_error - %02x\n", mfm->error); -} - - -static int -get_sector(mfm_t *mfm, off64_t *addr) -{ - drive_t *drive = &mfm->drives[mfm->drive_sel]; - int heads = drive->cfg_hpc; - - if (drive->current_cylinder != mfm->cylinder) { - mfm_xt_log("mfm_get_sector: wrong cylinder\n"); - mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return(1); - } - if (mfm->head > heads) { - mfm_xt_log("mfm_get_sector: past end of configured heads\n"); - mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return(1); - } - if (mfm->head > drive->hpc) { - mfm_xt_log("mfm_get_sector: past end of heads\n"); - mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return(1); - } - if (mfm->sector >= 17) { - mfm_xt_log("mfm_get_sector: past end of sectors\n"); - mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return(1); - } - - *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * - 17) + mfm->sector; - - return(0); -} - - -static void -next_sector(mfm_t *mfm) -{ - drive_t *drive = &mfm->drives[mfm->drive_sel]; - - mfm->sector++; - if (mfm->sector >= 17) { - mfm->sector = 0; - mfm->head++; - if (mfm->head >= drive->cfg_hpc) { - mfm->head = 0; - mfm->cylinder++; - drive->current_cylinder++; - if (drive->current_cylinder >= drive->cfg_cyl) - drive->current_cylinder = drive->cfg_cyl-1; - } - } -} - - -static void -mfm_callback(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - drive_t *drive; - off64_t addr; - - mfm->callback = 0LL; - - mfm->drive_sel = (mfm->command[1] & 0x20) ? 1 : 0; - mfm->completion_byte = mfm->drive_sel & 0x20; - drive = &mfm->drives[mfm->drive_sel]; - - switch (mfm->command[0]) { - case CMD_TEST_DRIVE_READY: - if (!drive->present) - mfm_error(mfm, ERR_NOT_READY); - mfm_complete(mfm); - break; - - case CMD_RECALIBRATE: - if (!drive->present) - mfm_error(mfm, ERR_NOT_READY); - else { - mfm->cylinder = 0; - drive->current_cylinder = 0; - } - mfm_complete(mfm); - break; - - case CMD_READ_STATUS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_SEND_DATA; - mfm->data_pos = 0; - mfm->data_len = 4; - mfm->status = STAT_BSY | STAT_IO | STAT_REQ; - mfm->data[0] = mfm->error; - mfm->data[1] = mfm->drive_sel ? 0x20 : 0; - mfm->data[2] = mfm->data[3] = 0; - mfm->error = 0; - break; - - case STATE_SENT_DATA: - mfm_complete(mfm); - break; - } - break; - - case CMD_VERIFY_SECTORS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); - drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; - mfm->head = mfm->command[1] & 0x1f; - mfm->sector = mfm->command[2] & 0x1f; - mfm->sector_count = mfm->command[4]; - do { - if (get_sector(mfm, &addr)) { - mfm_xt_log("get_sector failed\n"); - mfm_error(mfm, mfm->error); - mfm_complete(mfm); - return; - } - - next_sector(mfm); - - mfm->sector_count = (mfm->sector_count-1) & 0xff; - } while (mfm->sector_count); - - mfm_complete(mfm); - - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - break; - - default: - fatal("CMD_VERIFY_SECTORS: bad state %i\n", mfm->state); - } - break; - - case CMD_FORMAT_TRACK: - mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); - drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; - mfm->head = mfm->command[1] & 0x1f; - - if (get_sector(mfm, &addr)) { - mfm_xt_log("get_sector failed\n"); - mfm_error(mfm, mfm->error); - mfm_complete(mfm); - return; - } - - hdd_image_zero(drive->hdd_num, addr, 17); - - mfm_complete(mfm); - break; - - case CMD_READ_SECTORS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); - drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; - mfm->head = mfm->command[1] & 0x1f; - mfm->sector = mfm->command[2] & 0x1f; - mfm->sector_count = mfm->command[4]; - mfm->state = STATE_SEND_DATA; - mfm->data_pos = 0; - mfm->data_len = 512; - - if (get_sector(mfm, &addr)) { - mfm_error(mfm, mfm->error); - mfm_complete(mfm); - return; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *) mfm->sector_buf); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - - if (mfm->irq_dma_mask & DMA_ENA) - mfm->callback = MFM_TIME; - else { - mfm->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(mfm->data, mfm->sector_buf, 512); - } - break; - - case STATE_SEND_DATA: - mfm->status = STAT_BSY; - if (mfm->irq_dma_mask & DMA_ENA) { - for (; mfm->data_pos < 512; mfm->data_pos++) { - int val = dma_channel_write(3, mfm->sector_buf[mfm->data_pos]); - - if (val == DMA_NODATA) { - mfm_xt_log("CMD_READ_SECTORS out of data!\n"); - mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - mfm->callback = MFM_TIME; - return; - } - } - mfm->state = STATE_SENT_DATA; - mfm->callback = MFM_TIME; - } else - fatal("Read sectors no DMA! - shouldn't get here\n"); - break; - - case STATE_SENT_DATA: - next_sector(mfm); - - mfm->data_pos = 0; - - mfm->sector_count = (mfm->sector_count-1) & 0xff; - - if (mfm->sector_count) { - if (get_sector(mfm, &addr)) { - mfm_error(mfm, mfm->error); - mfm_complete(mfm); - return; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *) mfm->sector_buf); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - - mfm->state = STATE_SEND_DATA; - - if (mfm->irq_dma_mask & DMA_ENA) - mfm->callback = MFM_TIME; - else { - mfm->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(mfm->data, mfm->sector_buf, 512); - } - } else { - mfm_complete(mfm); - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - } - break; - - default: - fatal("CMD_READ_SECTORS: bad state %i\n", mfm->state); - } - break; - - case CMD_WRITE_SECTORS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); - drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; - mfm->head = mfm->command[1] & 0x1f; - mfm->sector = mfm->command[2] & 0x1f; - mfm->sector_count = mfm->command[4]; - mfm->state = STATE_RECEIVE_DATA; - mfm->data_pos = 0; - mfm->data_len = 512; - if (mfm->irq_dma_mask & DMA_ENA) - mfm->callback = MFM_TIME; - else - mfm->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA: - mfm->status = STAT_BSY; - if (mfm->irq_dma_mask & DMA_ENA) { - for (; mfm->data_pos < 512; mfm->data_pos++) { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) { - mfm_xt_log("CMD_WRITE_SECTORS out of data!\n"); - mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - mfm->callback = MFM_TIME; - return; - } - - mfm->sector_buf[mfm->data_pos] = val & 0xff; - } - - mfm->state = STATE_RECEIVED_DATA; - mfm->callback = MFM_TIME; - } else - fatal("Write sectors no DMA! - should never get here\n"); - break; - - case STATE_RECEIVED_DATA: - if (! (mfm->irq_dma_mask & DMA_ENA)) - memcpy(mfm->sector_buf, mfm->data, 512); - - if (get_sector(mfm, &addr)) - { - mfm_error(mfm, mfm->error); - mfm_complete(mfm); - return; - } - - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *) mfm->sector_buf); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - - next_sector(mfm); - mfm->data_pos = 0; - mfm->sector_count = (mfm->sector_count-1) & 0xff; - - if (mfm->sector_count) { - mfm->state = STATE_RECEIVE_DATA; - if (mfm->irq_dma_mask & DMA_ENA) - mfm->callback = MFM_TIME; - else - mfm->status = STAT_BSY | STAT_REQ; - } else - mfm_complete(mfm); - break; - - default: - fatal("CMD_WRITE_SECTORS: bad state %i\n", mfm->state); - } - break; - - case CMD_SEEK: - if (! drive->present) - mfm_error(mfm, ERR_NOT_READY); - else { - int cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); - - drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : cylinder; - - if (cylinder != drive->current_cylinder) - mfm_error(mfm, ERR_SEEK_ERROR); - } - mfm_complete(mfm); - break; - - case CMD_INIT_DRIVE_PARAMS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_RECEIVE_DATA; - mfm->data_pos = 0; - mfm->data_len = 8; - mfm->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVED_DATA: - drive->cfg_cyl = mfm->data[1] | (mfm->data[0] << 8); - drive->cfg_hpc = mfm->data[2]; - mfm_xt_log("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - mfm_complete(mfm); - break; - - default: - fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", mfm->state); - } - break; - - case CMD_WRITE_SECTOR_BUFFER: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_RECEIVE_DATA; - mfm->data_pos = 0; - mfm->data_len = 512; - if (mfm->irq_dma_mask & DMA_ENA) - mfm->callback = MFM_TIME; - else - mfm->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA: - if (mfm->irq_dma_mask & DMA_ENA) { - mfm->status = STAT_BSY; - - for (; mfm->data_pos < 512; mfm->data_pos++) { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) { - mfm_xt_log("CMD_WRITE_SECTOR_BUFFER out of data!\n"); - mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - mfm->callback = MFM_TIME; - return; - } - - mfm->data[mfm->data_pos] = val & 0xff; - } - - mfm->state = STATE_RECEIVED_DATA; - mfm->callback = MFM_TIME; - } else - fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); - break; - - case STATE_RECEIVED_DATA: - memcpy(mfm->sector_buf, mfm->data, 512); - mfm_complete(mfm); - break; - - default: - fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", mfm->state); - } - break; - - case CMD_BUFFER_DIAGNOSTIC: - case CMD_CONTROLLER_DIAGNOSTIC: - mfm_complete(mfm); - break; - - case 0xfa: - mfm_complete(mfm); - break; - - case CMD_DTC_SET_STEP_RATE: - mfm_complete(mfm); - break; - - case CMD_DTC_GET_DRIVE_PARAMS: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_SEND_DATA; - mfm->data_pos = 0; - mfm->data_len = 4; - mfm->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(mfm->data, 0, 4); - mfm->data[0] = drive->tracks & 0xff; - mfm->data[1] = 17 | ((drive->tracks >> 2) & 0xc0); - mfm->data[2] = drive->hpc-1; - mfm_xt_log("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks); - break; - - case STATE_SENT_DATA: - mfm_complete(mfm); - break; - - default: - fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", mfm->state); - } - break; - - case CMD_DTC_GET_GEOMETRY: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_SEND_DATA; - mfm->data_pos = 0; - mfm->data_len = 16; - mfm->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(mfm->data, 0, 16); - mfm->data[0x4] = drive->tracks & 0xff; - mfm->data[0x5] = (drive->tracks >> 8) & 0xff; - mfm->data[0xa] = drive->hpc; - break; - - case STATE_SENT_DATA: - mfm_complete(mfm); - break; - } - break; - - case CMD_DTC_SET_GEOMETRY: - switch (mfm->state) { - case STATE_START_COMMAND: - mfm->state = STATE_RECEIVE_DATA; - mfm->data_pos = 0; - mfm->data_len = 16; - mfm->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVED_DATA: - /*Bit of a cheat here - we always report the actual geometry of the drive in use*/ - mfm_complete(mfm); - break; - } - break; - - default: - fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", - mfm->command[0], mfm->command[1], - mfm->command[2], mfm->command[3], - mfm->command[4], mfm->command[5]); - } -} - - -static void -loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) -{ - drive_t *drive = &mfm->drives[d]; - - if (! hdd_image_load(c)) { - drive->present = 0; - return; - } - - drive->spt = hdd[c].spt; - drive->hpc = hdd[c].hpc; - drive->tracks = hdd[c].tracks; - drive->hdd_num = c; - drive->present = 1; -} - - -static struct { - int tracks, hpc; -} hd_types[4] = { - { 306, 4 }, /* Type 0 */ - { 612, 4 }, /* Type 16 */ - { 615, 4 }, /* Type 2 */ - { 306, 8 } /* Type 13 */ -}; - - -static void -mfm_set_switches(mfm_t *mfm) -{ - int c, d; - - mfm->switches = 0; - - for (d=0; d<2; d++) { - drive_t *drive = &mfm->drives[d]; - - if (! drive->present) continue; - - for (c=0; c<4; c++) { - if (drive->spt == 17 && - drive->hpc == hd_types[c].hpc && - drive->tracks == hd_types[c].tracks) { - mfm->switches |= (c << (d ? 0 : 2)); - break; - } - } - - if (c == 4) - mfm_xt_log("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); - } -} - - -static void * -xebec_init(const device_t *info) -{ - int i, c = 0; - - mfm_t *xebec = malloc(sizeof(mfm_t)); - memset(xebec, 0x00, sizeof(mfm_t)); - - mfm_xt_log("MFM: looking for disks..\n"); - for (i=0; i MFM_NUM) break; - } - } - mfm_xt_log("MFM: %d disks loaded.\n", c); - - mfm_set_switches(xebec); - - rom_init(&xebec->bios_rom, XEBEC_BIOS_FILE, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x0320, 4, - mfm_read, NULL, NULL, mfm_write, NULL, NULL, xebec); - - timer_add(mfm_callback, &xebec->callback, &xebec->callback, xebec); - - return(xebec); -} - - -static void -mfm_close(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - int d; - - for (d=0; d<2; d++) { - drive_t *drive = &mfm->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - free(mfm); -} - - -static int -xebec_available(void) -{ - return(rom_present(XEBEC_BIOS_FILE)); -} - - -const device_t mfm_xt_xebec_device = { - "IBM PC Fixed Disk Adapter", - DEVICE_ISA, - 0, - xebec_init, mfm_close, NULL, - xebec_available, NULL, NULL, NULL -}; - - -static void * -dtc5150x_init(const device_t *info) -{ - int i, c = 0; - - mfm_t *dtc = malloc(sizeof(mfm_t)); - memset(dtc, 0x00, sizeof(mfm_t)); - - mfm_xt_log("MFM: looking for disks..\n"); - for (i=0; i MFM_NUM) break; - } - } - mfm_xt_log("MFM: %d disks loaded.\n", c); - - dtc->switches = 0xff; - - dtc->drives[0].cfg_cyl = dtc->drives[0].tracks; - dtc->drives[0].cfg_hpc = dtc->drives[0].hpc; - dtc->drives[1].cfg_cyl = dtc->drives[1].tracks; - dtc->drives[1].cfg_hpc = dtc->drives[1].hpc; - - rom_init(&dtc->bios_rom, DTC_BIOS_FILE, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x0320, 4, - mfm_read, NULL, NULL, mfm_write, NULL, NULL, dtc); - - timer_add(mfm_callback, &dtc->callback, &dtc->callback, dtc); - - return(dtc); -} - - -static int -dtc5150x_available(void) -{ - return(rom_present(DTC_BIOS_FILE)); -} - - -const device_t mfm_xt_dtc5150x_device = { - "DTC 5150X", - DEVICE_ISA, - 0, - dtc5150x_init, mfm_close, NULL, - dtc5150x_available, NULL, NULL, NULL -}; diff --git a/src - Cópia/disk/hdc_xta.c b/src - Cópia/disk/hdc_xta.c deleted file mode 100644 index 00528b096..000000000 --- a/src - Cópia/disk/hdc_xta.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* - * 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. - * - * Implementation of a generic IDE-XTA disk controller. - * - * XTA is the acronym for 'XT-Attached', which was basically - * the XT-counterpart to what we know now as IDE (which is - * also named ATA - AT Attachment.) The basic ideas was to - * put the actual drive controller electronics onto the drive - * itself, and have the host machine just talk to that using - * a simpe, standardized I/O path- hence the name IDE, for - * Integrated Drive Electronics. - * - * In the ATA version of IDE, the programming interface of - * the IBM PC/AT (which used the Western Digitial 1002/1003 - * controllers) was kept, and, so, ATA-IDE assumes a 16bit - * data path: it reads and writes 16bit words of data. The - * disk drives for this bus commonly have an 'A' suffix to - * identify them as 'ATBUS'. - * - * In XTA-IDE, which is slightly older, the programming - * interface of the IBM PC/XT (which used the MFM controller - * from Xebec) was kept, and, so, it uses an 8bit data path. - * Disk drives for this bus commonly have the 'X' suffix to - * mark them as being for this XTBUS variant. - * - * So, XTA and ATA try to do the same thing, but they use - * different ways to achive their goal. - * - * Also, XTA is **not** the same as XTIDE. XTIDE is a modern - * variant of ATA-IDE, but retro-fitted for use on 8bit XT - * systems: an extra register is used to deal with the extra - * data byte per transfer. XTIDE uses regular IDE drives, - * and uses the regular ATA/IDE programming interface, just - * with the extra register. - * - * NOTE: This driver implements both the 'standard' XTA interface, - * sold by Western Digital as the WDXT-140 (no BIOS) and the - * WDXT-150 (with BIOS), as well as some variants customized - * for specific machines. - * - * NOTE: The XTA interface is 0-based for sector numbers !! - * - * Version: @(#)hdc_ide_xta.c 1.0.8 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Based on my earlier HD20 driver for the EuroPC. - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#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 "hdc.h" -#include "hdd.h" - - -#define HDC_TIME (50*TIMER_USEC) - -#define WD_BIOS_FILE L"roms/hdd/xta/idexywd2.bin" - - -enum { - STATE_IDLE = 0, - STATE_RECV, - STATE_RDATA, - STATE_RDONE, - STATE_SEND, - STATE_SDATA, - STATE_SDONE, - STATE_COMPL -}; - - -/* Command values. */ -#define CMD_TEST_READY 0x00 -#define CMD_RECALIBRATE 0x01 - /* unused 0x02 */ -#define CMD_READ_SENSE 0x03 -#define CMD_FORMAT_DRIVE 0x04 -#define CMD_READ_VERIFY 0x05 -#define CMD_FORMAT_TRACK 0x06 -#define CMD_FORMAT_BAD_TRACK 0x07 -#define CMD_READ_SECTORS 0x08 - /* unused 0x09 */ -#define CMD_WRITE_SECTORS 0x0a -#define CMD_SEEK 0x0b -#define CMD_SET_DRIVE_PARAMS 0x0c -#define CMD_READ_ECC_BURST 0x0d -#define CMD_READ_SECTOR_BUFFER 0x0e -#define CMD_WRITE_SECTOR_BUFFER 0x0f -#define CMD_RAM_DIAGS 0xe0 - /* unused 0xe1 */ - /* unused 0xe2 */ -#define CMD_DRIVE_DIAGS 0xe3 -#define CMD_CTRL_DIAGS 0xe4 -#define CMD_READ_LONG 0xe5 -#define CMD_WRITE_LONG 0xe6 - -/* Status register (reg 1) values. */ -#define STAT_REQ 0x01 /* controller needs data transfer */ -#define STAT_IO 0x02 /* direction of transfer (TO bus) */ -#define STAT_CD 0x04 /* transfer of Command or Data */ -#define STAT_BSY 0x08 /* controller is busy */ -#define STAT_DRQ 0x10 /* DMA requested */ -#define STAT_IRQ 0x20 /* interrupt requested */ -#define STAT_DCB 0x80 /* not seen by driver */ - -/* Sense Error codes. */ -#define ERR_NOERROR 0x00 /* no error detected */ -#define ERR_NOINDEX 0x01 /* drive did not detect IDX pulse */ -#define ERR_NOSEEK 0x02 /* drive did not complete SEEK */ -#define ERR_WRFAULT 0x03 /* write fault during last cmd */ -#define ERR_NOTRDY 0x04 /* drive did not go READY after cmd */ -#define ERR_NOTRK000 0x06 /* drive did not see TRK0 signal */ -#define ERR_LONGSEEK 0x08 /* long seek in progress */ -#define ERR_IDREAD 0x10 /* ECC error during ID field */ -#define ERR_DATA 0x11 /* uncorrectable ECC err in data */ -#define ERR_NOMARK 0x12 /* no address mark detected */ -#define ERR_NOSECT 0x14 /* sector not found */ -#define ERR_SEEK 0x15 /* seek error */ -#define ERR_ECCDATA 0x18 /* ECC corrected data */ -#define ERR_BADTRK 0x19 /* bad track detected */ -#define ERR_ILLCMD 0x20 /* invalid command received */ -#define ERR_ILLADDR 0x21 /* invalid disk address received */ -#define ERR_BADRAM 0x30 /* bad RAM in sector data buffer */ -#define ERR_BADROM 0x31 /* bad checksum in ROM test */ -#define ERR_BADECC 0x32 /* ECC polynomial generator bad */ - -/* Completion Byte fields. */ -#define COMP_DRIVE 0x20 -#define COMP_ERR 0x02 - -#define IRQ_ENA 0x02 -#define DMA_ENA 0x01 - - -/* The device control block (6 bytes) */ -#pragma pack(push,1) -typedef struct { - uint8_t cmd; /* [7:5] class, [4:0] opcode */ - - uint8_t head :5, /* [4:0] head number */ - drvsel :1, /* [5] drive select */ - mbz :2; /* [7:6] 00 */ - - uint8_t sector :6, /* [5:0] sector number 0-63 */ - cyl_high :2; /* [7:6] cylinder [9:8] bits */ - - uint8_t cyl_low; /* [7:0] cylinder [7:0] bits */ - - uint8_t count; /* [7:0] blk count / interleave */ - - uint8_t ctrl; /* [7:0] control field */ -} dcb_t; -#pragma pack(pop) - -/* The (configured) Drive Parameters. */ -#pragma pack(push,1) -typedef struct { - uint8_t cyl_high; /* (MSB) number of cylinders */ - uint8_t cyl_low; /* (LSB) number of cylinders */ - uint8_t heads; /* number of heads per cylinder */ - uint8_t rwc_high; /* (MSB) reduced write current cylinder */ - uint8_t rwc_low; /* (LSB) reduced write current cylinder */ - uint8_t wp_high; /* (MSB) write precompensation cylinder */ - uint8_t wp_low; /* (LSB) write precompensation cylinder */ - uint8_t maxecc; /* max ECC data burst length */ -} dprm_t; -#pragma pack(pop) - -/* Define an attached drive. */ -typedef struct { - int8_t id, /* drive ID on bus */ - present, /* drive is present */ - hdd_num, /* index to global disk table */ - type; /* drive type ID */ - - uint16_t cur_cyl; /* last known position of heads */ - - uint8_t spt, /* active drive parameters */ - hpc; - uint16_t tracks; - - uint8_t cfg_spt, /* configured drive parameters */ - cfg_hpc; - uint16_t cfg_tracks; -} drive_t; - - -typedef struct { - const char *name; /* controller name */ - - uint16_t base; /* controller base I/O address */ - int8_t irq; /* controller IRQ channel */ - int8_t dma; /* controller DMA channel */ - int8_t type; /* controller type ID */ - - uint32_t rom_addr; /* address where ROM is */ - rom_t bios_rom; /* descriptor for the BIOS */ - - /* Controller state. */ - int8_t state; /* controller state */ - uint8_t sense; /* current SENSE ERROR value */ - uint8_t status; /* current operational status */ - uint8_t intr; - int64_t callback; - - /* Data transfer. */ - int16_t buf_idx, /* buffer index and pointer */ - buf_len; - uint8_t *buf_ptr; - - /* Current operation parameters. */ - dcb_t dcb; /* device control block */ - uint16_t track; /* requested track# */ - uint8_t head, /* requested head# */ - sector, /* requested sector# */ - comp; /* operation completion byte */ - int count; /* requested sector count */ - - drive_t drives[XTA_NUM]; /* the attached drive(s) */ - - uint8_t data[512]; /* data buffer */ - uint8_t sector_buf[512]; /* sector buffer */ -} hdc_t; - - -#ifdef ENABLE_XTA_LOG -int xta_do_log = ENABLE_XTA_LOG; -#endif - - -static void -xta_log(const char *fmt, ...) -{ -#ifdef ENABLE_XTA_LOG - va_list ap; - - if (xta_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -set_intr(hdc_t *dev) -{ - dev->status = STAT_REQ|STAT_CD|STAT_IO|STAT_BSY; - dev->state = STATE_COMPL; - - if (dev->intr & IRQ_ENA) { - dev->status |= STAT_IRQ; - picint(1 << dev->irq); - } -} - - -/* Get the logical (block) address of a CHS triplet. */ -static int -get_sector(hdc_t *dev, drive_t *drive, off64_t *addr) -{ - if (drive->cur_cyl != dev->track) { - xta_log("%s: get_sector: wrong cylinder %d/%d\n", - dev->name, drive->cur_cyl, dev->track); - dev->sense = ERR_ILLADDR; - return(1); - } - - if (dev->head >= drive->hpc) { - xta_log("%s: get_sector: past end of heads\n", dev->name); - dev->sense = ERR_ILLADDR; - return(1); - } - - if (dev->sector >= drive->spt) { - xta_log("%s: get_sector: past end of sectors\n", dev->name); - dev->sense = ERR_ILLADDR; - return(1); - } - - /* Calculate logical address (block number) of desired sector. */ - *addr = ((((off64_t) dev->track*drive->hpc) + \ - dev->head)*drive->spt) + dev->sector; - - return(0); -} - - -static void -next_sector(hdc_t *dev, drive_t *drive) -{ - if (++dev->sector >= drive->spt) { - dev->sector = 0; - if (++dev->head >= drive->hpc) { - dev->head = 0; - dev->track++; - if (++drive->cur_cyl >= drive->tracks) - drive->cur_cyl = (drive->tracks - 1); - } - } -} - - -/* Perform the seek operation. */ -static void -do_seek(hdc_t *dev, drive_t *drive, int cyl) -{ - dev->track = cyl; - - if (dev->track >= drive->tracks) - drive->cur_cyl = (drive->tracks - 1); - else - drive->cur_cyl = dev->track; - - if (drive->cur_cyl < 0) - drive->cur_cyl = 0; -} - - -/* Format a track or an entire drive. */ -static void -do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb) -{ - int start_cyl, end_cyl; - int start_hd, end_hd; - off64_t addr; - int h, s; - - /* Get the parameters from the DCB. */ - if (dcb->cmd == CMD_FORMAT_DRIVE) { - start_cyl = 0; - start_hd = 0; - end_cyl = drive->tracks; - end_hd = drive->hpc; - } else { - start_cyl = (dcb->cyl_low | (dcb->cyl_high << 8)); - start_hd = dcb->head; - end_cyl = start_cyl + 1; - end_hd = start_hd + 1; - } - - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, start_cyl); - dev->head = dcb->head; - dev->sector = 0; - - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); - -do_fmt: - /* - * For now, we don't use the interleave factor (in - * dcb->count), although we should one day use an - * image format that can handle it.. - * - * That said, we have been given a sector_buf of - * data to fill the sectors with, so we will use - * that at least. - */ - for (h = start_hd; h < end_hd; h++) { - for (s = 0; s < drive->spt; s++) { - /* Set the sector we need to write. */ - dev->head = h; - dev->sector = s; - - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) break; - - /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - } - } - - /* One more track done. */ - if (++start_cyl == end_cyl) break; - - /* This saves us a LOT of code. */ - goto do_fmt; - } - - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); -} - - -/* Execute the DCB we just received. */ -static void -hdc_callback(void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - dcb_t *dcb = &dev->dcb; - drive_t *drive; - dprm_t *params; - off64_t addr; - int no_data = 0; - int val; - - /* Cancel timer. */ - dev->callback = 0; - - drive = &dev->drives[dcb->drvsel]; - dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00; - dev->status |= STAT_DCB; - - switch (dcb->cmd) { - case CMD_TEST_READY: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; - - case CMD_RECALIBRATE: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } else { - dev->track = drive->cur_cyl = 0; - } - set_intr(dev); - break; - - case CMD_READ_SENSE: - switch(dev->state) { - case STATE_IDLE: - dev->buf_idx = 0; - dev->buf_len = 4; - dev->buf_ptr = dev->data; - dev->buf_ptr[0] = dev->sense; - dev->buf_ptr[1] = dcb->drvsel ? 0x20 : 0x00; - dev->buf_ptr[2] = (drive->cur_cyl >> 2) | \ - (dev->sector & 0x3f); - dev->buf_ptr[3] = (drive->cur_cyl & 0xff); - dev->sense = ERR_NOERROR; - dev->status |= (STAT_IO | STAT_REQ); - dev->state = STATE_SDATA; - break; - - case STATE_SDONE: - set_intr(dev); - } - break; - - case CMD_READ_VERIFY: - no_data = 1; - /*FALLTHROUGH*/ - - case CMD_READ_SECTORS: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - break; - } - - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, - (dcb->cyl_low|(dcb->cyl_high<<8))); - dev->head = dcb->head; - dev->sector = dcb->sector; - - /* Get sector count; count=0 means 256. */ - dev->count = (int)dcb->count; - if (dev->count == 0) - dev->count = 256; - dev->buf_len = 512; - - dev->state = STATE_SEND; - /*FALLTHROUGH*/ - - case STATE_SEND: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); -do_send: - /* Get address of sector to load. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - dev->comp |= COMP_ERR; - set_intr(dev); - return; - } - - /* Read the block from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - - /* Ready to transfer the data out. */ - dev->state = STATE_SDATA; - dev->buf_idx = 0; - if (no_data) { - /* Delay a bit, no actual transfer. */ - dev->callback = HDC_TIME; - } else { - if (dev->intr & DMA_ENA) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - dev->callback = HDC_TIME; - } else { - /* Copy from sector to data. */ - memcpy(dev->data, - dev->sector_buf, - dev->buf_len); - dev->buf_ptr = dev->data; - - dev->status |= (STAT_IO | STAT_REQ); - } - } - break; - - case STATE_SDATA: - if (! no_data) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_write(dev->dma, - *dev->buf_ptr); - if (val == DMA_NODATA) { - xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); - - dev->status |= (STAT_CD | STAT_IO| STAT_REQ); - dev->callback = HDC_TIME; - return; - } - dev->buf_ptr++; - dev->buf_idx++; - } - } - dev->callback = HDC_TIME; - dev->state = STATE_SDONE; - break; - - case STATE_SDONE: - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - set_intr(dev); - return; - } - - /* Addvance to next sector. */ - next_sector(dev, drive); - - /* This saves us a LOT of code. */ - dev->state = STATE_SEND; - goto do_send; - } - break; - -#if 0 - case CMD_WRITE_VERIFY: - no_data = 1; - /*FALLTHROUGH*/ -#endif - - case CMD_WRITE_SECTORS: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - break; - } - - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, - (dcb->cyl_low|(dcb->cyl_high<<8))); - dev->head = dcb->head; - dev->sector = dcb->sector; - - /* Get sector count; count=0 means 256. */ - dev->count = (int)dev->dcb.count; - if (dev->count == 0) - dev->count = 256; - dev->buf_len = 512; - - dev->state = STATE_RECV; - /*FALLTHROUGH*/ - - case STATE_RECV: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); -do_recv: - /* Ready to transfer the data in. */ - dev->state = STATE_RDATA; - dev->buf_idx = 0; - if (no_data) { - /* Delay a bit, no actual transfer. */ - dev->callback = HDC_TIME; - } else { - if (dev->intr & DMA_ENA) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - dev->callback = HDC_TIME; - } else { - /* No DMA, do PIO. */ - dev->buf_ptr = dev->data; - dev->status |= STAT_REQ; - } - } - break; - - case STATE_RDATA: - if (! no_data) { - /* Perform DMA. */ - dev->status = STAT_BSY; - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - xta_log("%s: CMD_WRITE_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); - - xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name); - dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - dev->callback = HDC_TIME; - return; - } - - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - dev->state = STATE_RDONE; - dev->callback = HDC_TIME; - } - break; - - case STATE_RDONE: - /* Copy from data to sector if PIO. */ - if (! (dev->intr & DMA_ENA)) - memcpy(dev->sector_buf, dev->data, - dev->buf_len); - - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - dev->comp |= COMP_ERR; - set_intr(dev); - return; - } - - /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - set_intr(dev); - return; - } - - /* Advance to next sector. */ - next_sector(dev, drive); - - /* This saves us a LOT of code. */ - dev->state = STATE_RECV; - goto do_recv; - } - break; - - case CMD_FORMAT_DRIVE: - case CMD_FORMAT_TRACK: - if (drive->present) { - do_format(dev, drive, dcb); - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; - - case CMD_SEEK: - /* Seek to cylinder. */ - val = (dcb->cyl_low | (dcb->cyl_high << 8)); - if (drive->present) { - do_seek(dev, drive, val); - if (val != drive->cur_cyl) { - dev->comp |= COMP_ERR; - dev->sense = ERR_SEEK; - } - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; - - case CMD_SET_DRIVE_PARAMS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDATA; - dev->buf_idx = 0; - dev->buf_len = sizeof(dprm_t); - dev->buf_ptr = (uint8_t *)dev->data; - dev->status |= STAT_REQ; - break; - - case STATE_RDONE: - params = (dprm_t *)dev->data; - drive->tracks = - (params->cyl_high << 8) | params->cyl_low; - drive->hpc = params->heads; - drive->spt = 17 /*hardcoded*/; - dev->status &= ~STAT_REQ; - set_intr(dev); - break; - } - break; - - case CMD_WRITE_SECTOR_BUFFER: - switch (dev->state) { - case STATE_IDLE: - dev->buf_idx = 0; - dev->buf_len = 512; - dev->state = STATE_RDATA; - if (dev->intr & DMA_ENA) { - dev->buf_ptr = dev->sector_buf; - dev->callback = HDC_TIME; - } else { - dev->buf_ptr = dev->data; - dev->status |= STAT_REQ; - } - break; - - case STATE_RDATA: - if (dev->intr & DMA_ENA) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name); - dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - dev->callback = HDC_TIME; - return; - } - - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - dev->state = STATE_RDONE; - dev->callback = HDC_TIME; - } - break; - - case STATE_RDONE: - if (! (dev->intr & DMA_ENA)) - memcpy(dev->sector_buf, - dev->data, dev->buf_len); - set_intr(dev); - break; - } - break; - - case CMD_RAM_DIAGS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDONE; - dev->callback = 5*HDC_TIME; - break; - - case STATE_RDONE: - set_intr(dev); - break; - } - break; - - case CMD_DRIVE_DIAGS: - switch(dev->state) { - case STATE_IDLE: - if (drive->present) { - dev->state = STATE_RDONE; - dev->callback = 5*HDC_TIME; - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - } - break; - - case STATE_RDONE: - set_intr(dev); - break; - } - break; - - case CMD_CTRL_DIAGS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDONE; - dev->callback = 10*HDC_TIME; - break; - - case STATE_RDONE: - set_intr(dev); - break; - } - break; - - default: - xta_log("%s: unknown command - %02x\n", dev->name, dcb->cmd); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - set_intr(dev); - } -} - - -/* Read one of the controller registers. */ -static uint8_t -hdc_read(uint16_t port, void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: /* DATA register */ - dev->status &= ~STAT_IRQ; - - if (dev->state == STATE_SDATA) { - if (dev->buf_idx > dev->buf_len) { - xta_log("%s: read with empty buffer!\n", - dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } - - ret = dev->buf_ptr[dev->buf_idx]; - if (++dev->buf_idx == dev->buf_len) { - /* All data sent. */ - dev->status &= ~STAT_REQ; - dev->state = STATE_SDONE; - dev->callback = HDC_TIME; - } - } else if (dev->state == STATE_COMPL) { -xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp); - ret = dev->comp; - dev->status = 0x00; - dev->state = STATE_IDLE; - } - break; - - case 1: /* STATUS register */ - ret = (dev->status & ~STAT_DCB); - break; - - case 2: /* "read option jumpers" */ - ret = 0xff; /* all switches off */ - break; - } - - return(ret); -} - - -/* Write to one of the controller registers. */ -static void -hdc_write(uint16_t port, uint8_t val, void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - - switch (port & 7) { - case 0: /* DATA register */ - if (dev->state == STATE_RDATA) { - if (! (dev->status & STAT_REQ)) { - xta_log("%s: not ready for command/data!\n", dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } - - if (dev->buf_idx >= dev->buf_len) { - xta_log("%s: write with full buffer!\n", dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } - - /* Store the data into the buffer. */ - dev->buf_ptr[dev->buf_idx] = val; - if (++dev->buf_idx == dev->buf_len) { - /* We got all the data we need. */ - dev->status &= ~STAT_REQ; - if (dev->status & STAT_DCB) - dev->state = STATE_RDONE; - else - dev->state = STATE_IDLE; - dev->status &= ~STAT_CD; - dev->callback = HDC_TIME; - } - } - break; - - case 1: /* RESET register */ - dev->sense = 0x00; - dev->state = STATE_IDLE; - break; - - case 2: /* "controller-select" */ - /* Reset the DCB buffer. */ - dev->buf_idx = 0; - dev->buf_len = sizeof(dcb_t); - dev->buf_ptr = (uint8_t *)&dev->dcb; - dev->state = STATE_RDATA; - dev->status = (STAT_BSY | STAT_CD | STAT_REQ); - break; - - case 3: /* DMA/IRQ intr register */ -//xta_log("%s: WriteMASK(%02X)\n", dev->name, val); - dev->intr = val; - break; - } -} - - -static void * -xta_init(const device_t *info) -{ - drive_t *drive; - wchar_t *fn = NULL; - hdc_t *dev; - int c, i; - int max = XTA_NUM; - - /* Allocate and initialize device block. */ - dev = malloc(sizeof(hdc_t)); - memset(dev, 0x00, sizeof(hdc_t)); - dev->type = info->local; - - /* Do per-controller-type setup. */ - switch(dev->type) { - case 0: /* WDXT-150, with BIOS */ - dev->name = "WDXT-150"; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->rom_addr = device_get_config_hex20("bios_addr"); - dev->dma = 3; - fn = WD_BIOS_FILE; - max = 1; - break; - - case 1: /* EuroPC */ - dev->name = "HD20"; - dev->base = 0x0320; - dev->irq = 5; - dev->dma = 3; - break; - } - - xta_log("%s: initializing (I/O=%04X, IRQ=%d, DMA=%d", - dev->name, dev->base, dev->irq, dev->dma); - if (dev->rom_addr != 0x000000) - xta_log(", BIOS=%06X", dev->rom_addr); - xta_log(")\n"); - - /* Load any disks for this device class. */ - c = 0; - for (i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { - drive = &dev->drives[hdd[i].xta_channel]; - - if (! hdd_image_load(i)) { - drive->present = 0; - continue; - } - drive->id = c; - drive->hdd_num = i; - drive->present = 1; - - /* These are the "hardware" parameters (from the image.) */ - drive->cfg_spt = (uint8_t)(hdd[i].spt & 0xff); - drive->cfg_hpc = (uint8_t)(hdd[i].hpc & 0xff); - drive->cfg_tracks = (uint16_t)hdd[i].tracks; - - /* Use them as "configured" parameters until overwritten. */ - drive->spt = drive->cfg_spt; - drive->hpc = drive->cfg_hpc; - drive->tracks = drive->cfg_tracks; - - xta_log("%s: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n", - dev->name, hdd[i].xta_channel, drive->tracks, - drive->hpc, drive->spt, i); - - if (++c > max) break; - } - } - - /* Enable the I/O block. */ - io_sethandler(dev->base, 4, - hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev); - - /* Load BIOS if it has one. */ - if (dev->rom_addr != 0x000000) - rom_init(&dev->bios_rom, fn, - dev->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - - /* Create a timer for command delays. */ - timer_add(hdc_callback, &dev->callback, &dev->callback, dev); - - return(dev); -} - - -static void -xta_close(void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - drive_t *drive; - int d; - - /* Remove the I/O handler. */ - io_removehandler(dev->base, 4, - hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev); - - /* Close all disks and their images. */ - for (d = 0; d < XTA_NUM; d++) { - drive = &dev->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - /* Release the device. */ - free(dev); -} - - -static const device_config_t wdxt150_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x0320, /*W2*/ - { - { - "320H", 0x0320 - }, - { - "324H", 0x0324 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, /*W3*/ - { - { - "IRQ 5", 5 - }, - { - "IRQ 4", 4 - }, - { - "" - } - }, - }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xc8000, /*W1*/ - { - { - "C800H", 0xc8000 - }, - { - "CA00H", 0xca000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - - -const device_t xta_wdxt150_device = { - "WDXT-150 Fixed Disk Controller", - DEVICE_ISA, - 0, - xta_init, xta_close, NULL, - NULL, NULL, NULL, - wdxt150_config -}; - - -const device_t xta_hd20_device = { - "EuroPC HD20 Fixed Disk Controller", - DEVICE_ISA, - 1, - xta_init, xta_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/disk/hdc_xtide.c b/src - Cópia/disk/hdc_xtide.c deleted file mode 100644 index a558a3318..000000000 --- a/src - Cópia/disk/hdc_xtide.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. - * - * XT-IDE controller emulation. - * - * The XT-IDE project is intended to allow 8-bit ("XT") systems - * to use regular IDE drives. IDE is a standard based on the - * 16b PC/AT design, and so a special board (with its own BIOS) - * had to be created for this. - * - * XT-IDE is *NOT* the same as XTA, or X-IDE, which is an older - * standard where the actual MFM/RLL controller for the PC/XT - * was placed on the hard drive (hard drives where its drive - * type would end in "X" or "XT", such as the 8425XT.) This was - * more or less the original IDE, but since those systems were - * already on their way out, the newer IDE standard based on the - * PC/AT controller and 16b design became the IDE we now know. - * - * Version: @(#)hdc_xtide.c 1.0.13 2018/04/26 - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "hdc.h" -#include "hdc_ide.h" - - -#define ROM_PATH_XT L"roms/hdd/xtide/ide_xt.bin" -#define ROM_PATH_AT L"roms/hdd/xtide/ide_at.bin" -#define ROM_PATH_PS2 L"roms/hdd/xtide/SIDE1V12.BIN" -#define ROM_PATH_PS2AT L"roms/hdd/xtide/ide_at_1_1_5.bin" - - -typedef struct { - void *ide_board; - uint8_t data_high; - rom_t bios_rom; -} xtide_t; - - -static void -xtide_write(uint16_t port, uint8_t val, void *priv) -{ - xtide_t *xtide = (xtide_t *)priv; - - switch (port & 0xf) { - case 0x0: - ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board); - return; - - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - ide_writeb((port & 0xf), val, xtide->ide_board); - return; - - case 0x8: - xtide->data_high = val; - return; - - case 0xe: - ide_write_devctl(0x0, val, xtide->ide_board); - return; - } -} - - -static uint8_t -xtide_read(uint16_t port, void *priv) -{ - xtide_t *xtide = (xtide_t *)priv; - uint16_t tempw = 0xffff; - - switch (port & 0xf) { - case 0x0: - tempw = ide_readw(0x0, xtide->ide_board); - xtide->data_high = tempw >> 8; - break; - - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - tempw = ide_readb((port & 0xf), xtide->ide_board); - break; - - case 0x8: - tempw = xtide->data_high; - break; - - case 0xe: - tempw = ide_read_alt_status(0x0, xtide->ide_board); - break; - - default: - break; - } - - return(tempw & 0xff); -} - - -static void * -xtide_init(const device_t *info) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, ROM_PATH_XT, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - xtide->ide_board = ide_xtide_init(); - - io_sethandler(0x0300, 16, - xtide_read, NULL, NULL, - xtide_write, NULL, NULL, xtide); - - return(xtide); -} - - -static int -xtide_available(void) -{ - return(rom_present(ROM_PATH_XT)); -} - - -static void * -xtide_at_init(const device_t *info) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, ROM_PATH_AT, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - device_add(&ide_isa_2ch_device); - - return(xtide); -} - - -static int -xtide_at_available(void) -{ - return(rom_present(ROM_PATH_AT)); -} - - -static void * -xtide_acculogic_init(const device_t *info) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, ROM_PATH_PS2, - 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - xtide->ide_board = ide_xtide_init(); - - io_sethandler(0x0360, 16, - xtide_read, NULL, NULL, - xtide_write, NULL, NULL, xtide); - - return(xtide); -} - - -static int -xtide_acculogic_available(void) -{ - return(rom_present(ROM_PATH_PS2)); -} - - -static void -xtide_close(void *priv) -{ - xtide_t *xtide = (xtide_t *)priv; - - free(xtide); - - ide_xtide_close(); -} - - -static void * -xtide_at_ps2_init(const device_t *info) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, ROM_PATH_PS2AT, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - device_add(&ide_isa_2ch_device); - - return(xtide); -} - - -static int -xtide_at_ps2_available(void) -{ - return(rom_present(ROM_PATH_PS2AT)); -} - - -static void -xtide_at_close(void *priv) -{ - xtide_t *xtide = (xtide_t *)priv; - - free(xtide); -} - - -const device_t xtide_device = { - "XTIDE", - DEVICE_ISA, - 0, - xtide_init, xtide_close, NULL, - xtide_available, NULL, NULL, - NULL -}; - -const device_t xtide_at_device = { - "XTIDE (AT)", - DEVICE_ISA | DEVICE_AT, - 0, - xtide_at_init, xtide_at_close, NULL, - xtide_at_available, NULL, NULL, - NULL -}; - -const device_t xtide_acculogic_device = { - "XTIDE (Acculogic)", - DEVICE_ISA, - 0, - xtide_acculogic_init, xtide_close, NULL, - xtide_acculogic_available, NULL, NULL, - NULL -}; - -const device_t xtide_at_ps2_device = { - "XTIDE (AT) (1.1.5)", - DEVICE_ISA | DEVICE_PS2, - 0, - xtide_at_ps2_init, xtide_at_close, NULL, - xtide_at_ps2_available, NULL, NULL, - NULL -}; diff --git a/src - Cópia/disk/hdd.c b/src - Cópia/disk/hdd.c deleted file mode 100644 index 805618a75..000000000 --- a/src - Cópia/disk/hdd.c +++ /dev/null @@ -1,150 +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. - * - * Common code to handle all sorts of hard disk images. - * - * Version: @(#)hdd.c 1.0.9 2018/05/25 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../plat.h" -#include "../ui.h" -#include "hdd.h" - - -hard_disk_t hdd[HDD_NUM]; - - -int -hdd_init(void) -{ - /* Clear all global data. */ - memset(hdd, 0x00, sizeof(hdd)); - - return(0); -} - - -int -hdd_string_to_bus(char *str, int cdrom) -{ - if (! strcmp(str, "none")) - return(HDD_BUS_DISABLED); - - if (! strcmp(str, "mfm")) { - if (cdrom) { -no_cdrom: - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4099); - return(0); - } - - return(HDD_BUS_MFM); - } - - /* FIXME: delete 'rll' in a year or so.. --FvK */ - if (!strcmp(str, "esdi") || !strcmp(str, "rll")) { - if (cdrom) goto no_cdrom; - - return(HDD_BUS_ESDI); - } - - if (! strcmp(str, "ide_pio_only")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "ide")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "atapi_pio_only")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "atapi")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "eide")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "xta")) - return(HDD_BUS_XTA); - - if (! strcmp(str, "atide")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "ide_pio_and_dma")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "atapi_pio_and_dma")) - return(HDD_BUS_IDE); - - if (! strcmp(str, "scsi")) - return(HDD_BUS_SCSI); - - if (! strcmp(str, "usb")) - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4110); - - return(0); -} - - -char * -hdd_bus_to_string(int bus, int cdrom) -{ - char *s = "none"; - - switch (bus) { - case HDD_BUS_DISABLED: - default: - break; - - case HDD_BUS_MFM: - s = "mfm"; - break; - - case HDD_BUS_XTA: - s = "xta"; - break; - - case HDD_BUS_ESDI: - s = "esdi"; - break; - - case HDD_BUS_IDE: - s = cdrom ? "atapi" : "ide"; - break; - - case HDD_BUS_SCSI: - s = "scsi"; - break; - } - - return(s); -} - - -int -hdd_is_valid(int c) -{ - if (hdd[c].bus == HDD_BUS_DISABLED) - return(0); - - if (wcslen(hdd[c].fn) == 0) - return(0); - - if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0)) - return(0); - - return(1); -} diff --git a/src - Cópia/disk/hdd.h b/src - Cópia/disk/hdd.h deleted file mode 100644 index cc5f75a38..000000000 --- a/src - Cópia/disk/hdd.h +++ /dev/null @@ -1,132 +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. - * - * Definitions for the hard disk image handler. - * - * Version: @(#)hdd.h 1.0.5 2018/04/30 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_HDD_H -# define EMU_HDD_H - - -#define HDD_NUM 30 /* total of 30 images supported */ - - -/* Hard Disk bus types. */ -#if 0 -/* Bit 4 = DMA supported (0 = no, 1 yes) - used for IDE and ATAPI only; - Bit 5 = Removable (0 = no, 1 yes). */ - -enum { - BUS_DISABLED = 0x00, - - BUS_MFM = 0x01, /* These four are for hard disk only. */ - BUS_XIDE = 0x02, - BUS_XTA = 0x03, - BUS_ESDI = 0x04, - - BUS_PANASONIC = 0x21, / These four are for CD-ROM only. */ - BUS_PHILIPS = 0x22, - BUS_SONY = 0x23, - BUS_MITSUMI = 0x24, - - BUS_IDE_PIO_ONLY = 0x05, - BUS_IDE_PIO_AND_DMA = 0x15, - BUS_IDE_R_PIO_ONLY = 0x25, - BUS_IDE_R_PIO_AND_DMA = 0x35, - - BUS_ATAPI_PIO_ONLY = 0x06, - BUS_ATAPI_PIO_AND_DMA = 0x16, - BUS_ATAPI_R_PIO_ONLY = 0x26, - BUS_ATAPI_R_PIO_AND_DMA = 0x36, - - BUS_SASI = 0x07, - BUS_SASI_R = 0x27, - - BUS_SCSI = 0x08, - BUS_SCSI_R = 0x28, - - BUS_USB = 0x09, - BUS_USB_R = 0x29 -}; -#else -enum { - HDD_BUS_DISABLED = 0, - HDD_BUS_MFM, - HDD_BUS_XTA, - HDD_BUS_ESDI, - HDD_BUS_IDE, - HDD_BUS_SCSI, - HDD_BUS_USB -}; -#endif - - -/* Define the virtual Hard Disk. */ -typedef struct { - int8_t is_hdi; /* image type (should rename) */ - int8_t wp; /* disk has been mounted READ-ONLY */ - - uint8_t bus; - - uint8_t mfm_channel; /* should rename and/or unionize */ - uint8_t esdi_channel; - uint8_t xta_channel; - uint8_t ide_channel; - uint8_t scsi_id; - uint8_t scsi_lun; - - uint32_t base, - spt, - hpc, /* physical geometry parameters */ - tracks, - at_spt, /* [Translation] parameters */ - at_hpc; - - FILE *f; /* current file handle to image */ - - wchar_t fn[260]; /* name of current image file */ - wchar_t prev_fn[260]; /* name of previous image file */ -} hard_disk_t; - - -extern hard_disk_t hdd[HDD_NUM]; -extern unsigned int hdd_table[128][3]; - - -extern int hdd_init(void); -extern int hdd_string_to_bus(char *str, int cdrom); -extern char *hdd_bus_to_string(int bus, int cdrom); -extern int hdd_is_valid(int c); - -extern void hdd_image_init(void); -extern int hdd_image_load(int id); -extern void hdd_image_seek(uint8_t id, uint32_t sector); -extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count); -extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count); -extern uint32_t hdd_image_get_last_sector(uint8_t id); -extern uint32_t hdd_image_get_pos(uint8_t id); -extern uint8_t hdd_image_get_type(uint8_t id); -extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt); -extern void hdd_image_unload(uint8_t id, int fn_preserve); -extern void hdd_image_close(uint8_t id); - -extern int image_is_hdi(const wchar_t *s); -extern int image_is_hdx(const wchar_t *s, int check_signature); - - -#endif /*EMU_HDD_H*/ diff --git a/src - Cópia/disk/hdd_image.c b/src - Cópia/disk/hdd_image.c deleted file mode 100644 index 7f1563626..000000000 --- a/src - Cópia/disk/hdd_image.c +++ /dev/null @@ -1,525 +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 hard disk image files. - * - * Version: @(#)hdd_image.c 1.0.15 2018/04/29 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "hdd.h" - - -typedef struct -{ - FILE *file; - uint32_t base; - uint32_t pos, last_sector; - uint8_t type; - uint8_t loaded; -} hdd_image_t; - - -hdd_image_t hdd_images[HDD_NUM]; - -static char empty_sector[512]; -static char *empty_sector_1mb; - - -#ifdef ENABLE_HDD_IMAGE_LOG -int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG; -#endif - - -static void -hdd_image_log(const char *fmt, ...) -{ -#ifdef ENABLE_HDD_IMAGE_LOG - va_list ap; - - if (hdd_image_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -int -image_is_hdi(const wchar_t *s) -{ - int len; - wchar_t ext[5] = { 0, 0, 0, 0, 0 }; - char *ws = (char *) s; - len = wcslen(s); - if ((len < 4) || (s[0] == L'.')) - return 0; - memcpy(ext, ws + ((len - 4) << 1), 8); - if (! wcscasecmp(ext, L".HDI")) - return 1; - else - return 0; -} - - -int -image_is_hdx(const wchar_t *s, int check_signature) -{ - int len; - FILE *f; - uint64_t filelen; - uint64_t signature; - char *ws = (char *) s; - wchar_t ext[5] = { 0, 0, 0, 0, 0 }; - len = wcslen(s); - if ((len < 4) || (s[0] == L'.')) - return 0; - memcpy(ext, ws + ((len - 4) << 1), 8); - if (wcscasecmp(ext, L".HDX") == 0) { - if (check_signature) { - f = plat_fopen((wchar_t *)s, L"rb"); - if (!f) - return 0; - fseeko64(f, 0, SEEK_END); - filelen = ftello64(f); - fseeko64(f, 0, SEEK_SET); - if (filelen < 44) - return 0; - fread(&signature, 1, 8, f); - fclose(f); - if (signature == 0xD778A82044445459ll) - return 1; - else - return 0; - } else - return 1; - } else - return 0; -} - - -static int -prepare_new_hard_disk(uint8_t id, uint64_t full_size) -{ - uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); - - uint32_t size; - uint32_t t, i; - - t = (uint32_t) (target_size >> 20); /* Amount of 1 MB blocks. */ - size = (uint32_t) (target_size & 0xfffff); /* 1 MB mask. */ - - empty_sector_1mb = (char *) malloc(1048576); - memset(empty_sector_1mb, 0, 1048576); - - /* Temporarily switch off suppression of seen messages so that the - progress gets displayed. */ - pclog_toggle_suppr(); - pclog("Writing image sectors: ["); - - /* First, write all the 1 MB blocks. */ - if (t > 0) { - for (i = 0; i < t; i++) { - fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file); - pclog("#"); - } - } - - /* Then, write the remainder. */ - fwrite(empty_sector_1mb, 1, size, hdd_images[id].file); - pclog("#]\n"); - /* Switch the suppression of seen messages back on. */ - pclog_toggle_suppr(); - - free(empty_sector_1mb); - - hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; - - hdd_images[id].loaded = 1; - - return 1; -} - - -void -hdd_image_init(void) -{ - int i; - - for (i = 0; i < HDD_NUM; i++) - memset(&hdd_images[i], 0, sizeof(hdd_image_t)); -} - - -int -hdd_image_load(int id) -{ - uint32_t sector_size = 512; - uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459ll; - uint64_t full_size = 0; - uint64_t spt = 0, hpc = 0, tracks = 0; - int c; - uint64_t s = 0; - wchar_t *fn = hdd[id].fn; - int is_hdx[2] = { 0, 0 }; - - memset(empty_sector, 0, sizeof(empty_sector)); - - hdd_images[id].base = 0; - - if (hdd_images[id].loaded) { - if (hdd_images[id].file) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } - hdd_images[id].loaded = 0; - } - - is_hdx[0] = image_is_hdx(fn, 0); - is_hdx[1] = image_is_hdx(fn, 1); - - hdd_images[id].pos = 0; - - /* Try to open existing hard disk image */ - if (fn[0] == '.') { - hdd_image_log("File name starts with .\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - hdd_images[id].file = plat_fopen(fn, L"rb+"); - if (hdd_images[id].file == NULL) { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) { - /* Failed because it does not exist, - so try to create new file */ - if (hdd[id].wp) { - hdd_image_log("A write-protected image must exist\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - - hdd_images[id].file = plat_fopen(fn, L"wb+"); - if (hdd_images[id].file == NULL) { - hdd_image_log("Unable to open image\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } else { - if (image_is_hdi(fn)) { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].base = 0x1000; - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file); - fwrite(&full_size, 1, 4, hdd_images[id].file); - fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); - for (c = 0; c < 0x3f8; c++) - fwrite(&zero, 1, 4, hdd_images[id].file); - hdd_images[id].type = 1; - } else if (is_hdx[0]) { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].base = 0x28; - fwrite(&signature, 1, 8, hdd_images[id].file); - fwrite(&full_size, 1, 8, hdd_images[id].file); - fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - hdd_images[id].type = 2; - } - else - hdd_images[id].type = 0; - hdd_images[id].last_sector = 0; - } - - s = full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - - return prepare_new_hard_disk(id, full_size); - } else { - /* Failed for another reason */ - hdd_image_log("Failed for another reason\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - } else { - if (image_is_hdi(fn)) { - fseeko64(hdd_images[id].file, 0x8, SEEK_SET); - fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file); - fseeko64(hdd_images[id].file, 0xC, SEEK_SET); - full_size = 0LL; - fread(&full_size, 1, 4, hdd_images[id].file); - fseeko64(hdd_images[id].file, 0x10, SEEK_SET); - fread(§or_size, 1, 4, hdd_images[id].file); - if (sector_size != 512) { - /* Sector size is not 512 */ - hdd_image_log("HDI: Sector size is not 512\n"); - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - fread(&spt, 1, 4, hdd_images[id].file); - fread(&hpc, 1, 4, hdd_images[id].file); - fread(&tracks, 1, 4, hdd_images[id].file); - hdd[id].spt = spt; - hdd[id].hpc = hpc; - hdd[id].tracks = tracks; - hdd_images[id].type = 1; - } else if (is_hdx[1]) { - hdd_images[id].base = 0x28; - fseeko64(hdd_images[id].file, 8, SEEK_SET); - fread(&full_size, 1, 8, hdd_images[id].file); - fseeko64(hdd_images[id].file, 0x10, SEEK_SET); - fread(§or_size, 1, 4, hdd_images[id].file); - if (sector_size != 512) { - /* Sector size is not 512 */ - hdd_image_log("HDX: Sector size is not 512\n"); - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - fread(&spt, 1, 4, hdd_images[id].file); - fread(&hpc, 1, 4, hdd_images[id].file); - fread(&tracks, 1, 4, hdd_images[id].file); - hdd[id].spt = spt; - hdd[id].hpc = hpc; - hdd[id].tracks = tracks; - fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file); - fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file); - hdd_images[id].type = 2; - } else { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].type = 0; - } - } - - fseeko64(hdd_images[id].file, 0, SEEK_END); - s = ftello64(hdd_images[id].file); - if (s < (full_size + hdd_images[id].base)) - return prepare_new_hard_disk(id, full_size); - else { - hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; - hdd_images[id].loaded = 1; - return 1; - } -} - - -void -hdd_image_seek(uint8_t id, uint32_t sector) -{ - off64_t addr = sector; - addr = (uint64_t)sector << 9LL; - - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET); -} - - -void -hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) -{ - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - fread(buffer, 1, count << 9, hdd_images[id].file); -} - - -uint32_t -hdd_sectors(uint8_t id) -{ - fseeko64(hdd_images[id].file, 0, SEEK_END); - return (uint32_t) ((ftello64(hdd_images[id].file) - hdd_images[id].base) >> 9); -} - - -int -hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) -{ - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); - - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; - - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - fread(buffer, 1, transfer_sectors << 9, hdd_images[id].file); - - if (count != transfer_sectors) - return 1; - return 0; -} - - -void -hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) -{ - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - fwrite(buffer, count << 9, 1, hdd_images[id].file); -} - - -int -hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) -{ - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); - - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; - - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - fwrite(buffer, transfer_sectors << 9, 1, hdd_images[id].file); - - if (count != transfer_sectors) - return 1; - return 0; -} - - -void -hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count) -{ - uint32_t i = 0; - - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - for (i = 0; i < count; i++) - fwrite(empty_sector, 512, 1, hdd_images[id].file); -} - - -int -hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count) -{ - uint32_t i = 0; - - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); - - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; - - hdd_images[id].pos = sector; - fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET); - for (i = 0; i < transfer_sectors; i++) - fwrite(empty_sector, 1, 512, hdd_images[id].file); - - if (count != transfer_sectors) - return 1; - return 0; -} - - -uint32_t -hdd_image_get_last_sector(uint8_t id) -{ - return hdd_images[id].last_sector; -} - - -uint32_t -hdd_image_get_pos(uint8_t id) -{ - return hdd_images[id].pos; -} - - -uint8_t -hdd_image_get_type(uint8_t id) -{ - return hdd_images[id].type; -} - - -void -hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt) -{ - if (hdd_images[id].type == 2) { - hdd[id].at_hpc = hpc; - hdd[id].at_spt = spt; - fseeko64(hdd_images[id].file, 0x20, SEEK_SET); - fwrite(&(hdd[id].at_spt), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file); - } -} - - -void -hdd_image_unload(uint8_t id, int fn_preserve) -{ - if (wcslen(hdd[id].fn) == 0) - return; - - if (hdd_images[id].loaded) { - if (hdd_images[id].file != NULL) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } - hdd_images[id].loaded = 0; - } - - hdd_images[id].last_sector = -1; - - memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn)); - if (fn_preserve) - wcscpy(hdd[id].prev_fn, hdd[id].fn); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); -} - - -void -hdd_image_close(uint8_t id) -{ - hdd_image_log("hdd_image_close(%i)\n", id); - - if (!hdd_images[id].loaded) - return; - - if (hdd_images[id].file != NULL) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } - memset(&hdd_images[id], 0, sizeof(hdd_image_t)); - hdd_images[id].loaded = 0; -} diff --git a/src - Cópia/disk/hdd_table.c b/src - Cópia/disk/hdd_table.c deleted file mode 100644 index 0ef0829e1..000000000 --- a/src - Cópia/disk/hdd_table.c +++ /dev/null @@ -1,173 +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. - * - * Implementation of the IDE emulation for hard disks and ATAPI - * CD-ROM devices. - * - * Version: @(#)hdd_table.c 1.0.5 2018/04/08 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "hdd.h" - - -unsigned int hdd_table[128][3] = { - { 306, 4, 17 }, /* 0 - 7 */ - { 615, 2, 17 }, - { 306, 4, 26 }, - { 1024, 2, 17 }, - { 697, 3, 17 }, - { 306, 8, 17 }, - { 614, 4, 17 }, - { 615, 4, 17 }, - - { 670, 4, 17 }, /* 8 - 15 */ - { 697, 4, 17 }, - { 987, 3, 17 }, - { 820, 4, 17 }, - { 670, 5, 17 }, - { 697, 5, 17 }, - { 733, 5, 17 }, - { 615, 6, 17 }, - - { 462, 8, 17 }, /* 016-023 */ - { 306, 8, 26 }, - { 615, 4, 26 }, - { 1024, 4, 17 }, - { 855, 5, 17 }, - { 925, 5, 17 }, - { 932, 5, 17 }, - { 1024, 2, 40 }, - - { 809, 6, 17 }, /* 024-031 */ - { 976, 5, 17 }, - { 977, 5, 17 }, - { 698, 7, 17 }, - { 699, 7, 17 }, - { 981, 5, 17 }, - { 615, 8, 17 }, - { 989, 5, 17 }, - - { 820, 4, 26 }, /* 032-039 */ - { 1024, 5, 17 }, - { 733, 7, 17 }, - { 754, 7, 17 }, - { 733, 5, 26 }, - { 940, 6, 17 }, - { 615, 6, 26 }, - { 462, 8, 26 }, - - { 830, 7, 17 }, /* 040-047 */ - { 855, 7, 17 }, - { 751, 8, 17 }, - { 1024, 4, 26 }, - { 918, 7, 17 }, - { 925, 7, 17 }, - { 855, 5, 26 }, - { 977, 7, 17 }, - - { 987, 7, 17 }, /* 048-055 */ - { 1024, 7, 17 }, - { 823, 4, 38 }, - { 925, 8, 17 }, - { 809, 6, 26 }, - { 976, 5, 26 }, - { 977, 5, 26 }, - { 698, 7, 26 }, - - { 699, 7, 26 }, /* 056-063 */ - { 940, 8, 17 }, - { 615, 8, 26 }, - { 1024, 5, 26 }, - { 733, 7, 26 }, - { 1024, 8, 17 }, - { 823, 10, 17 }, - { 754, 11, 17 }, - - { 830, 10, 17 }, /* 064-071 */ - { 925, 9, 17 }, - { 1224, 7, 17 }, - { 940, 6, 26 }, - { 855, 7, 26 }, - { 751, 8, 26 }, - { 1024, 9, 17 }, - { 965, 10, 17 }, - - { 969, 5, 34 }, /* 072-079 */ - { 980, 10, 17 }, - { 960, 5, 35 }, - { 918, 11, 17 }, - { 1024, 10, 17 }, - { 977, 7, 26 }, - { 1024, 7, 26 }, - { 1024, 11, 17 }, - - { 940, 8, 26 }, /* 080-087 */ - { 776, 8, 33 }, - { 755, 16, 17 }, - { 1024, 12, 17 }, - { 1024, 8, 26 }, - { 823, 10, 26 }, - { 830, 10, 26 }, - { 925, 9, 26 }, - - { 960, 9, 26 }, /* 088-095 */ - { 1024, 13, 17 }, - { 1224, 11, 17 }, - { 900, 15, 17 }, - { 969, 7, 34 }, - { 917, 15, 17 }, - { 918, 15, 17 }, - { 1524, 4, 39 }, - - { 1024, 9, 26 }, /* 096-103 */ - { 1024, 14, 17 }, - { 965, 10, 26 }, - { 980, 10, 26 }, - { 1020, 15, 17 }, - { 1023, 15, 17 }, - { 1024, 15, 17 }, - { 1024, 16, 17 }, - - { 1224, 15, 17 }, /* 104-111 */ - { 755, 16, 26 }, - { 903, 8, 46 }, - { 984, 10, 34 }, - { 900, 15, 26 }, - { 917, 15, 26 }, - { 1023, 15, 26 }, - { 684, 16, 38 }, - - { 1930, 4, 62 }, /* 112-119 */ - { 967, 16, 31 }, - { 1013, 10, 63 }, - { 1218, 15, 36 }, - { 654, 16, 63 }, - { 659, 16, 63 }, - { 702, 16, 63 }, - { 1002, 13, 63 }, - - { 854, 16, 63 }, /* 119-127 */ - { 987, 16, 63 }, - { 995, 16, 63 }, - { 1024, 16, 63 }, - { 1036, 16, 63 }, - { 1120, 16, 59 }, - { 1054, 16, 63 }, - { 0, 0, 0 } -}; diff --git a/src - Cópia/disk/zip.c b/src - Cópia/disk/zip.c deleted file mode 100644 index b16ee915a..000000000 --- a/src - Cópia/disk/zip.c +++ /dev/null @@ -1,2787 +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. - * - * Implementation of the Iomega ZIP drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * Version: @(#)zip.c 1.0.21 2018/05/28 - * - * Author: Miran Grca, - * - * Copyright 2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi.h" -#include "../nvr.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdc_ide.h" -#include "zip.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define zipbufferb dev->buffer - - -zip_t *zip[ZIP_NUM]; -zip_drive_t zip_drives[ZIP_NUM]; -uint8_t atapi_zip_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_zip_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; - - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t zip_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, - IMPLEMENTED, /* 0x06 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - IMPLEMENTED, /* 0x0C */ - IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ - 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, - IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static uint64_t zip_mode_sense_page_flags = (1LL << GPMODE_R_W_ERROR_PAGE) | - (1LL << 0x02LL) | (1LL << 0x2FLL) | - (1LL << GPMODE_ALL_PAGES); -static uint64_t zip_250_mode_sense_page_flags = (1LL << GPMODE_R_W_ERROR_PAGE) | - (1LL << 0x05LL) | (1LL << 0x08LL) | - (1LL << 0x2FLL) | - (1LL << GPMODE_ALL_PAGES); - - -static const mode_sense_pages_t zip_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - -static const mode_sense_pages_t zip_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - -static const mode_sense_pages_t zip_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - - -static void zip_command_complete(zip_t *dev); -static void zip_init(zip_t *dev); - -void zip_phase_callback(zip_t *dev); - - -#ifdef ENABLE_ZIP_LOG -int zip_do_log = ENABLE_ZIP_LOG; -#endif - - -static void -zip_log(const char *format, ...) -{ -#ifdef ENABLE_ZIP_LOG - va_list ap; - - if (zip_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -int -find_zip_for_channel(uint8_t channel) -{ - uint8_t i = 0; - - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel == channel)) - return i; - } - return 0xff; -} - - -int -zip_load(zip_t *dev, wchar_t *fn) -{ - int read_only = dev->drv->ui_writeprot; - int size = 0; - - dev->drv->f = plat_fopen(fn, dev->drv->ui_writeprot ? L"rb" : L"rb+"); - if (!dev->drv->ui_writeprot && !dev->drv->f) { - dev->drv->f = plat_fopen(fn, L"rb"); - read_only = 1; - } - if (dev->drv->f) { - fseek(dev->drv->f, 0, SEEK_END); - size = ftell(dev->drv->f); - - if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { - /* This is a ZDI image. */ - size -= 0x1000; - dev->drv->base = 0x1000; - } else - dev->drv->base = 0; - - if (dev->drv->is_250) { - if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", - ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - fclose(dev->drv->f); - dev->drv->f = NULL; - dev->drv->medium_size = 0; - zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ - return 0; - } - } else { - if (size != (ZIP_SECTORS << 9)) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", - ZIP_SECTORS << 9); - fclose(dev->drv->f); - dev->drv->f = NULL; - dev->drv->medium_size = 0; - zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ - return 0; - } - } - - dev->drv->medium_size = size >> 9; - - fseek(dev->drv->f, dev->drv->base, SEEK_SET); - - memcpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path)); - - dev->drv->read_only = read_only; - - return 1; - } - - return 0; -} - - -void -zip_disk_reload(zip_t *dev) -{ - int ret = 0; - - if (wcslen(dev->drv->prev_image_path) == 0) - return; - else - ret = zip_load(dev, dev->drv->prev_image_path); - - if (ret) - dev->unit_attention = 1; -} - - -void -zip_disk_close(zip_t *dev) -{ - if (dev->drv->f) { - fclose(dev->drv->f); - dev->drv->f = NULL; - - memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); - memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); - - dev->drv->medium_size = 0; - } -} - - -void -build_atapi_zip_map() -{ - uint8_t i = 0; - - memset(atapi_zip_drives, 0xff, 8); - - for (i = 0; i < 8; i++) - atapi_zip_drives[i] = find_zip_for_channel(i); -} - - -int -find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t i = 0; - - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (zip_drives[i].scsi_device_id == scsi_id) && - (zip_drives[i].scsi_device_lun == scsi_lun)) - return i; - } - return 0xff; -} - - -void -build_scsi_zip_map() -{ - uint8_t i = 0; - uint8_t j = 0; - - for (i = 0; i < 16; i++) - memset(scsi_zip_drives[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_zip_drives[i][j] = find_zip_for_scsi_id(i, j); - } -} - - -static void -zip_set_callback(zip_t *dev) -{ - if (dev->drv->bus_type != ZIP_BUS_SCSI) - ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); -} - - -void -zip_set_signature(zip_t *dev) -{ - if (dev->id >= ZIP_NUM) - return; - dev->phase = 1; - dev->request_length = 0xEB14; -} - - -static void -zip_init(zip_t *dev) -{ - if (dev->id >= ZIP_NUM) - return; - - memset(dev, 0, sizeof(zip_t)); - dev->requested_blocks = 1; - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= ZIP_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < ZIP_BUS_SCSI) - dev->drv->bus_mode |= 1; - zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - if (dev->drv->bus_type < ZIP_BUS_SCSI) - zip_set_signature(dev); - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; - dev->packet_status = 0xff; - zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; -} - - -static int -zip_supports_pio(zip_t *dev) -{ - return (dev->drv->bus_mode & 1); -} - - -static int -zip_supports_dma(zip_t *dev) -{ - return (dev->drv->bus_mode & 2); -} - - -/* Returns: 0 for none, 1 for PIO, 2 for DMA. */ -static int -zip_current_mode(zip_t *dev) -{ - if (!zip_supports_pio(dev) && !zip_supports_dma(dev)) - return 0; - if (zip_supports_pio(dev) && !zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", dev->id); - return 1; - } - if (!zip_supports_pio(dev) && zip_supports_dma(dev)) - return 2; - if (zip_supports_pio(dev) && zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -zip_ZIP_PHASE_to_scsi(zip_t *dev) -{ - if (dev->status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -zip_atapi_phase_to_scsi(zip_t *dev) -{ - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; - } - - return 0; -} - - -static void -zip_mode_sense_load(zip_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - int i; - - memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - for (i = 0; i < 0x3f; i++) { - if (dev->drv->is_250) { - if (zip_250_mode_sense_pages_default.pages[i][1] != 0) { - if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) { - memcpy(dev->ms_pages_saved.pages[i], - zip_250_mode_sense_pages_default_scsi.pages[i], - zip_250_mode_sense_pages_default_scsi.pages[i][1] + 2); - } else { - memcpy(dev->ms_pages_saved.pages[i], - zip_250_mode_sense_pages_default.pages[i], - zip_250_mode_sense_pages_default.pages[i][1] + 2); - } - } - } else { - if (zip_mode_sense_pages_default.pages[i][1] != 0) { - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - memcpy(dev->ms_pages_saved.pages[i], - zip_mode_sense_pages_default_scsi.pages[i], - zip_mode_sense_pages_default_scsi.pages[i][1] + 2); - } else { - memcpy(dev->ms_pages_saved.pages[i], - zip_mode_sense_pages_default.pages[i], - zip_mode_sense_pages_default.pages[i][1] + 2); - } - } - } - } - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (dev->drv->bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", dev->id); - else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), L"rb"); - if (f) - fclose(f); -} - - -static void -zip_mode_sense_save(zip_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (dev->drv->bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", dev->id); - else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), L"wb"); - if (f) - fclose(f); -} - - -int -zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - int size = 0; - - if (dev->drv->is_250) - size = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ - else - size = ZIP_SECTORS - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(buffer, 0, 8); - buffer[0] = (size >> 24) & 0xff; - buffer[1] = (size >> 16) & 0xff; - buffer[2] = (size >> 8) & 0xff; - buffer[3] = size & 0xff; - buffer[6] = 2; /* 512 = 0x0200 */ - *len = 8; - - return 1; -} - - -/*SCSI Mode Sense 6/10*/ -static uint8_t -zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) -{ - switch (page_control) { - case 0: - case 3: - if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) - return 0x60; - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - if (dev->drv->is_250) - return zip_250_mode_sense_pages_changeable.pages[page][pos]; - else - return zip_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->is_250) { - if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) - return 0x60; - if (dev->drv->bus_type == ZIP_BUS_SCSI) - return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_250_mode_sense_pages_default.pages[page][pos]; - } else { - if (dev->drv->bus_type == ZIP_BUS_SCSI) - return zip_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_mode_sense_pages_default.pages[page][pos]; - } - break; - } - - return 0; -} - - -static uint32_t -zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) -{ - uint64_t page_flags; - uint8_t page_control = (type >> 6) & 3; - - if (dev->drv->is_250) - page_flags = zip_250_mode_sense_page_flags; - else - page_flags = zip_mode_sense_page_flags; - - int i = 0; - int j = 0; - - uint8_t msplen; - - type &= 0x3f; - - if (block_descriptor_len) { - if (dev->drv->is_250) { - buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); - buf[pos++] = ( dev->drv->medium_size & 0xff); - } else { - buf[pos++] = ((ZIP_SECTORS >> 24) & 0xff); - buf[pos++] = ((ZIP_SECTORS >> 16) & 0xff); - buf[pos++] = ((ZIP_SECTORS >> 8) & 0xff); - buf[pos++] = ( ZIP_SECTORS & 0xff); - } - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; - } - - for (i = 0; i < 0x40; i++) { - if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (page_flags & (1LL << dev->current_page_code)) { - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0); - msplen = zip_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 2 + j); - } - } - } - - return pos; -} - - -static void -zip_update_request_length(zip_t *dev, int len, int block_len) -{ - uint32_t bt, min_len = 0; - - dev->max_transfer_len = dev->request_length; - - /* For media access commands, make sure the requested DRQ length matches the block length. */ - switch (dev->current_cdb[0]) { - case 0x08: - case 0x28: - case 0xa8: - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; - - min_len = block_len; - - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - default: - dev->packet_len = len; - break; - } - /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; - - if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; - else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; - - return; -} - - -static void -zip_command_bus(zip_t *dev) -{ - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - dev->callback = 1LL * ZIP_TIME; - zip_set_callback(dev); -} - - -static void -zip_command_common(zip_t *dev) -{ - double bytes_per_second, period; - double dusec; - - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - if (dev->packet_status == ZIP_PHASE_COMPLETE) { - zip_phase_callback(dev); - dev->callback = 0LL; - } else { - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - dev->callback = -1LL; /* Speed depends on SCSI controller */ - return; - } else { - if (zip_current_mode(dev) == 2) - bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } - - period = 1000000.0 / bytes_per_second; - dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (dev->packet_len); - dev->callback = ((int64_t) dusec); - } - - zip_set_callback(dev); -} - - -static void -zip_command_complete(zip_t *dev) -{ - dev->packet_status = ZIP_PHASE_COMPLETE; - zip_command_common(dev); -} - - -static void -zip_command_read(zip_t *dev) -{ - dev->packet_status = ZIP_PHASE_DATA_IN; - zip_command_common(dev); - dev->total_read = 0; -} - - -static void -zip_command_read_dma(zip_t *dev) -{ - dev->packet_status = ZIP_PHASE_DATA_IN_DMA; - zip_command_common(dev); - dev->total_read = 0; -} - - -static void -zip_command_write(zip_t *dev) -{ - dev->packet_status = ZIP_PHASE_DATA_OUT; - zip_command_common(dev); -} - - -static void -zip_command_write_dma(zip_t *dev) -{ - dev->packet_status = ZIP_PHASE_DATA_OUT_DMA; - zip_command_common(dev); -} - - -/* id = Current ZIP device ID; - len = Total transfer length; - block_len = Length of a single block (why does it matter?!); - alloc_len = Allocated transfer length; - direction = Transfer direction (0 = read from host, 1 = write to host). */ -static void -zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction) -{ - zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos = 0; - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if ((len == 0) || (zip_current_mode(dev) == 0)) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) - dev->packet_len = 0; - - zip_command_complete(dev); - } else { - if (zip_current_mode(dev) == 2) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) - dev->packet_len = alloc_len; - - if (direction == 0) - zip_command_read_dma(dev); - else - zip_command_write_dma(dev); - } else { - zip_update_request_length(dev, len, block_len); - if (direction == 0) - zip_command_read(dev); - else - zip_command_write(dev); - } - } - - zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); -} - - -static void -zip_sense_clear(zip_t *dev, int command) -{ - dev->previous_command = command; - zip_sense_key = zip_asc = zip_ascq = 0; -} - - -static void -zip_set_phase(zip_t *dev, uint8_t phase) -{ - uint8_t scsi_id = dev->drv->scsi_device_id; - uint8_t scsi_lun = dev->drv->scsi_device_lun; - - if (dev->drv->bus_type != ZIP_BUS_SCSI) - return; - - SCSIDevices[scsi_id][scsi_lun].Phase = phase; -} - - -static void -zip_cmd_error(zip_t *dev) -{ - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * ZIP_TIME; - zip_set_callback(dev); - zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq); -} - - -static void -zip_unit_attention(zip_t *dev) -{ - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * ZIP_TIME; - zip_set_callback(dev); - zip_log("ZIP %i: UNIT ATTENTION\n", dev->id); -} - - -static void -zip_bus_master_error(zip_t *dev) -{ - zip_sense_key = zip_asc = zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_not_ready(zip_t *dev) -{ - zip_sense_key = SENSE_NOT_READY; - zip_asc = ASC_MEDIUM_NOT_PRESENT; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_write_protected(zip_t *dev) -{ - zip_sense_key = SENSE_UNIT_ATTENTION; - zip_asc = ASC_WRITE_PROTECTED; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_invalid_lun(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_LUN; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_illegal_opcode(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_ILLEGAL_OPCODE; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_lba_out_of_range(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_LBA_OUT_OF_RANGE; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static void -zip_invalid_field(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; - zip_ascq = 0; - zip_cmd_error(dev); - dev->status = 0x53; -} - - -static void -zip_invalid_field_pl(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - zip_ascq = 0; - zip_cmd_error(dev); - dev->status = 0x53; -} - - -static void -zip_data_phase_error(zip_t *dev) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_DATA_PHASE_ERROR; - zip_ascq = 0; - zip_cmd_error(dev); -} - - -static int -zip_blocks(zip_t *dev, uint32_t *len, int first_batch, int out) -{ - dev->data_pos = 0; - - *len = 0; - - if (!dev->sector_len) { - zip_command_complete(dev); - return -1; - } - - zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); - - if (dev->sector_pos >= dev->drv->medium_size) { - zip_log("ZIP %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); - zip_lba_out_of_range(dev); - return 0; - } - - *len = dev->requested_blocks << 9; - - fseek(dev->drv->f, dev->drv->base + (dev->sector_pos << 9), SEEK_SET); - if (out) - fwrite(zipbufferb, 1, *len, dev->drv->f); - else - fread(zipbufferb, 1, *len, dev->drv->f); - - zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - - dev->sector_pos += dev->requested_blocks; - dev->sector_len -= dev->requested_blocks; - - return 1; -} - - -void -zip_insert(zip_t *dev) -{ - dev->unit_attention = 1; -} - - -/*SCSI Sense Initialization*/ -void -zip_sense_code_ok(zip_t *dev) -{ - zip_sense_key = SENSE_NONE; - zip_asc = 0; - zip_ascq = 0; -} - - -static int -zip_pre_execution_check(zip_t *dev, uint8_t *cdb) -{ - int ready = 0; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if (((dev->request_length >> 5) & 7) != dev->drv->scsi_device_lun) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); - zip_invalid_lun(dev); - return 0; - } - } - - if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); - - zip_illegal_opcode(dev); - return 0; - } - - if ((dev->drv->bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); - return 0; - } - - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); - return 0; - } - - ready = (dev->drv->f != NULL); - - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - if (!ready && dev->unit_attention) - dev->unit_attention = 0; - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - /* zip_log("ZIP %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention = 2; - zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); - zip_unit_attention(dev); - return 0; - } - } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* zip_log("ZIP %i: Unit attention now 0\n", dev->id); */ - dev->unit_attention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (cdb[0] != GPCMD_REQUEST_SENSE) - zip_sense_clear(dev, cdb[0]); - - /* Next it's time for NOT READY. */ - if (!ready) - dev->media_status = MEC_MEDIA_REMOVAL; - else - dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; - - if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) { - zip_log("ZIP %i: Not ready (%02X)\n", dev->id, cdb[0]); - zip_not_ready(dev); - return 0; - } - - zip_log("ZIP %i: Continuing with command %02X\n", dev->id, cdb[0]); - - return 1; -} - - -static void -zip_seek(zip_t *dev, uint32_t pos) -{ - /* zip_log("ZIP %i: Seek %08X\n", dev->id, pos); */ - dev->sector_pos = pos; -} - - -static void -zip_rezero(zip_t *dev) -{ - dev->sector_pos = dev->sector_len = 0; - zip_seek(dev, 0); -} - - -void -zip_reset(zip_t *dev) -{ - zip_rezero(dev); - dev->status = 0; - dev->callback = 0LL; - zip_set_callback(dev); - dev->packet_status = 0xff; - dev->unit_attention = 0; -} - - -static void -zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) -{ - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = zip_sense_key; - buffer[2] = zip_asc; - buffer[3] = zip_ascq; - } - } - - buffer[0] = desc ? 0x72 : 0x70; - - if (dev->unit_attention && (zip_sense_key == 0)) { - buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; - buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[desc ? 3 : 13] = 0; - } - - zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); - - if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; - } - - /* Clear the sense stuff as per the spec. */ - zip_sense_clear(dev, GPCMD_REQUEST_SENSE); -} - - -void -zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length) -{ - int ready = 0; - - ready = (dev->drv->f != NULL); - - if (!ready && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; - } - - /* Do *NOT* advance the unit attention phase. */ - - zip_request_sense(dev, buffer, alloc_length, 0); -} - - -static void -zip_set_buf_len(zip_t *dev, int32_t *BufLen, uint32_t *src_len) -{ - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - zip_log("ZIP %i: Actual transfer length: %i\n", dev->id, *BufLen); - } -} - - -static void -zip_buf_alloc(zip_t *dev, uint32_t len) -{ - zip_log("ZIP %i: Allocated buffer length: %i\n", dev->id, len); - zipbufferb = (uint8_t *) malloc(len); -} - - -static void -zip_buf_free(zip_t *dev) -{ - if (zipbufferb) { - zip_log("ZIP %i: Freeing buffer...\n", dev->id); - free(zipbufferb); - zipbufferb = NULL; - } -} - - -void -zip_command(zip_t *dev, uint8_t *cdb) -{ - int pos = 0, block_desc = 0; - int ret; - uint32_t len, max_len; - uint32_t alloc_length, i = 0; - unsigned size_idx, idx = 0; - unsigned preamble_len; - int32_t blen = 0; - int32_t *BufLen; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - dev->status &= ~ERR_STAT; - } else { - BufLen = &blen; - dev->error = 0; - } - - dev->packet_len = 0; - dev->request_pos = 0; - - dev->data_pos = 0; - - memcpy(dev->current_cdb, cdb, 12); - - if (cdb[0] != 0) { - zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length); - - zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); - } - - dev->sector_len = 0; - - zip_set_phase(dev, SCSI_PHASE_STATUS); - - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (zip_pre_execution_check(dev, cdb) == 0) - return; - - switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(dev); - return; - } - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - - case GPCMD_FORMAT_UNIT: - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - - case GPCMD_IOMEGA_SENSE: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); - memset(zipbufferb, 0, 256); - if (cdb[2] == 1) { - /* This page is related to disk health status - setting - this page to 0 makes disk health read as "marginal". */ - zipbufferb[0] = 0x58; - zipbufferb[1] = 0x00; - for (i = 0x00; i < 0x58; i++) - zipbufferb[i + 0x02] = 0xff; - } else if (cdb[2] == 2) { - zipbufferb[0] = 0x3d; - zipbufferb[1] = 0x00; - for (i = 0x00; i < 0x13; i++) - zipbufferb[i + 0x02] = 0x00; - zipbufferb[0x15] = 0x00; - if (dev->drv->read_only) - zipbufferb[0x15] |= 0x02; - for (i = 0x00; i < 0x27; i++) - zipbufferb[i + 0x16] = 0x00; - } else { - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - zip_data_command_finish(dev, 18, 18, cdb[4], 0); - break; - - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - zip_seek(dev, 0); - zip_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); - len = (cdb[1] & 1) ? 8 : 18; - zip_request_sense(dev, zipbufferb, max_len, cdb[1] & 1); - zip_data_command_finish(dev, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - zip_buf_alloc(dev, 8); - - zip_set_buf_len(dev, BufLen, &len); - - memset(zipbufferb, 0, 8); - zipbufferb[5] = 1; - - zip_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = 512; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - ret = zip_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - zip_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(dev, BufLen, &dev->packet_len); - - zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = 512; - - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - switch(cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if (dev->drv->is_250) { - if ((dev->sector_pos >= dev->drv->medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)) { - zip_lba_out_of_range(dev); - return; - } - } else { - if ((dev->sector_pos >= ZIP_SECTORS) || - ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(dev); - return; - } - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - zip_set_buf_len(dev, BufLen, &dev->packet_len); - - zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_WRITE_SAME_10: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = 512; - - if ((cdb[1] & 6) == 6) { - zip_invalid_field(dev); - return; - } - - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - if (dev->drv->is_250) { - if ((dev->sector_pos >= dev->drv->medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)) { - zip_lba_out_of_range(dev); - return; - } - } else { - if ((dev->sector_pos >= ZIP_SECTORS) || - ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(dev); - return; - } - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(dev, BufLen, &dev->packet_len); - - zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - zip_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - zip_buf_alloc(dev, 65536); - } - - dev->current_page_code = cdb[2] & 0x3F; - zip_log("Mode sense page: %02X\n", dev->current_page_code); - - if (!(zip_mode_sense_page_flags & (1LL << dev->current_page_code))) { - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - - memset(zipbufferb, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_mode_sense(dev, zipbufferb, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - zipbufferb[0] = len - 1; - zipbufferb[1] = 0; - if (block_desc) - zipbufferb[3] = 8; - } else { - len = zip_mode_sense(dev, zipbufferb, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - zipbufferb[0]=(len - 2) >> 8; - zipbufferb[1]=(len - 2) & 255; - zipbufferb[2] = 0; - if (block_desc) { - zipbufferb[6] = 0; - zipbufferb[7] = 8; - } - } - - zip_set_buf_len(dev, BufLen, &len); - - zip_log("ZIP %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - zip_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - zip_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(dev, 65536); - } - - zip_set_buf_len(dev, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - dev->current_page_pos = 0; - - zip_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_START_STOP_UNIT: - zip_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disc. */ - zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ - break; - case 1: /* Start the disc and read the TOC. */ - break; - case 2: /* Eject the disc if possible. */ - /* zip_eject(dev->id); */ - break; - case 3: /* Load the disc (close tray). */ - zip_reload(dev->id); - break; - } - - zip_command_complete(dev); - break; - - case GPCMD_INQUIRY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - zip_buf_alloc(dev, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - zipbufferb[idx++] = 05; - zipbufferb[idx++] = cdb[2]; - zipbufferb[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - zip_data_phase_error(dev); - zip_buf_free(dev); - return; - } - - zipbufferb[idx++] = 0x02; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 20; - ide_padstr8(zipbufferb + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - zipbufferb[idx++] = 0x02; - zipbufferb[idx++] = 0x01; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 68; - ide_padstr8(zipbufferb + idx, 8, "IOMEGA "); /* Vendor */ - idx += 8; - if (dev->drv->is_250) - ide_padstr8(zipbufferb + idx, 40, "ZIP 250 "); /* Product */ - else - ide_padstr8(zipbufferb + idx, 40, "ZIP 100 "); /* Product */ - idx += 40; - ide_padstr8(zipbufferb + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(zipbufferb, 0, 8); - if (cdb[1] & 0xe0) - zipbufferb[0] = 0x60; /*No physical device on this LUN*/ - else - zipbufferb[0] = 0x00; /*Hard disk*/ - zipbufferb[1] = 0x80; /*Removable*/ - if (dev->drv->is_250) { - zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - } else { - zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - } - zipbufferb[4] = 31; - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - zipbufferb[6] = 1; /* 16-bit transfers supported */ - zipbufferb[7] = 0x20; /* Wide bus supported */ - } - - ide_padstr8(zipbufferb + 8, 8, "IOMEGA "); /* Vendor */ - if (dev->drv->is_250) { - ide_padstr8(zipbufferb + 16, 16, "ZIP 250 "); /* Product */ - ide_padstr8(zipbufferb + 32, 4, "42.S"); /* Revision */ - if (max_len >= 44) - ide_padstr8(zipbufferb + 36, 8, "08/08/01"); /* Date? */ - if (max_len >= 122) - ide_padstr8(zipbufferb + 96, 26, "(c) Copyright IOMEGA 2000 "); /* Copyright string */ - } else { - ide_padstr8(zipbufferb + 16, 16, "ZIP 100 "); /* Product */ - ide_padstr8(zipbufferb + 32, 4, "E.08"); /* Revision */ - } - idx = 36; - - if (max_len == 96) { - zipbufferb[4] = 91; - idx = 96; - } else if (max_len == 128) { - zipbufferb[4] = 0x75; - idx = 128; - } - } - -atapi_out: - zipbufferb[size_idx] = idx - preamble_len; - len=idx; - - len = MIN(len, max_len); - zip_set_buf_len(dev, BufLen, &len); - - zip_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - zip_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - } - zip_seek(dev, pos); - zip_command_complete(dev); - break; - - case GPCMD_READ_CDROM_CAPACITY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - - zip_buf_alloc(dev, 8); - - if (zip_read_capacity(dev, dev->current_cdb, zipbufferb, &len) == 0) { - zip_buf_free(dev); - return; - } - - zip_set_buf_len(dev, BufLen, &len); - - zip_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_IOMEGA_EJECT: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_eject(dev->id); - zip_command_complete(dev); - break; - - case GPCMD_READ_FORMAT_CAPACITIES: - len = (cdb[7] << 8) | cdb[8]; - - zip_buf_alloc(dev, len); - memset(zipbufferb, 0, len); - - pos = 0; - - /* List header */ - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 0; - if (dev->drv->f != NULL) - zipbufferb[pos++] = 16; - else - zipbufferb[pos++] = 8; - - /* Current/Maximum capacity header */ - if (dev->drv->is_250) { - if (dev->drv->f != NULL) { - zipbufferb[pos++] = (dev->drv->medium_size >> 24) & 0xff; - zipbufferb[pos++] = (dev->drv->medium_size >> 16) & 0xff; - zipbufferb[pos++] = (dev->drv->medium_size >> 8) & 0xff; - zipbufferb[pos++] = dev->drv->medium_size & 0xff; - zipbufferb[pos++] = 2; /* Current medium capacity */ - } else { - zipbufferb[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; - zipbufferb[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; - zipbufferb[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; - zipbufferb[pos++] = ZIP_250_SECTORS & 0xff; - zipbufferb[pos++] = 3; /* Maximum medium capacity */ - } - } else { - zipbufferb[pos++] = (ZIP_SECTORS >> 24) & 0xff; - zipbufferb[pos++] = (ZIP_SECTORS >> 16) & 0xff; - zipbufferb[pos++] = (ZIP_SECTORS >> 8) & 0xff; - zipbufferb[pos++] = ZIP_SECTORS & 0xff; - if (dev->drv->f != NULL) - zipbufferb[pos++] = 2; - else - zipbufferb[pos++] = 3; - } - - zipbufferb[pos++] = 512 >> 16; - zipbufferb[pos++] = 512 >> 8; - zipbufferb[pos++] = 512 & 0xff; - - if (dev->drv->f != NULL) { - /* Formattable capacity descriptor */ - zipbufferb[pos++] = (dev->drv->medium_size >> 24) & 0xff; - zipbufferb[pos++] = (dev->drv->medium_size >> 16) & 0xff; - zipbufferb[pos++] = (dev->drv->medium_size >> 8) & 0xff; - zipbufferb[pos++] = dev->drv->medium_size & 0xff; - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 512 >> 16; - zipbufferb[pos++] = 512 >> 8; - zipbufferb[pos++] = 512 & 0xff; - } - - zip_set_buf_len(dev, BufLen, &len); - - zip_data_command_finish(dev, len, len, len, 0); - break; - - default: - zip_illegal_opcode(dev); - break; - } - - /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ - - if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - zip_buf_free(dev); -} - - -/* The command second phase function, needed for Mode Select. */ -static uint8_t -zip_phase_data_out(zip_t *dev) -{ - uint16_t block_desc_len; - uint16_t pos; - - uint8_t error = 0; - uint8_t page, page_len; - - uint16_t i = 0; - - uint8_t hdr_len, val, old_val, ch; - - uint32_t last_to_write = 0, len = 0; - uint32_t c, h, s; - - switch(dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if (dev->requested_blocks > 0) - zip_blocks(dev, &len, 1, 1); - break; - case GPCMD_WRITE_SAME_10: - if (!dev->current_cdb[7] && !dev->current_cdb[8]) { - if (dev->drv->is_250) - last_to_write = (dev->drv->medium_size - 1); - else - last_to_write = (ZIP_SECTORS - 1); - } else - last_to_write = dev->sector_pos + dev->sector_len - 1; - - for (i = dev->sector_pos; i <= last_to_write; i++) { - if (dev->current_cdb[1] & 2) { - zipbufferb[0] = (i >> 24) & 0xff; - zipbufferb[1] = (i >> 16) & 0xff; - zipbufferb[2] = (i >> 8) & 0xff; - zipbufferb[3] = i & 0xff; - } else if (dev->current_cdb[1] & 4) { - /* CHS are 96,1,2048 (ZIP 100) and 239,1,2048 (ZIP 250) */ - s = (i % 2048); - h = ((i - s) / 2048) % 1; - c = ((i - s) / 2048) / 1; - zipbufferb[0] = (c >> 16) & 0xff; - zipbufferb[1] = (c >> 8) & 0xff; - zipbufferb[2] = c & 0xff; - zipbufferb[3] = h & 0xff; - zipbufferb[4] = (s >> 24) & 0xff; - zipbufferb[5] = (s >> 16) & 0xff; - zipbufferb[6] = (s >> 8) & 0xff; - zipbufferb[7] = s & 0xff; - } - fseek(dev->drv->f, dev->drv->base + (i << 9), SEEK_SET); - fwrite(zipbufferb, 1, 512, dev->drv->f); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) - hdr_len = 8; - else - hdr_len = 4; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = zipbufferb[2]; - block_desc_len <<= 8; - block_desc_len |= zipbufferb[3]; - } else { - block_desc_len = zipbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= zipbufferb[7]; - } - } else - block_desc_len = 0; - - pos = hdr_len + block_desc_len; - - while(1) { - page = zipbufferb[pos] & 0x3F; - page_len = zipbufferb[pos + 1]; - - pos += 2; - - if (!(zip_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; - val = zipbufferb[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; - } - } - } - - pos += page_len; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = zip_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - zip_mode_sense_save(dev); - - if (pos >= dev->total_length) - break; - } - - if (error) { - zip_invalid_field_pl(dev); - return 0; - } - break; - } - - return 1; -} - - -/* This is the general ATAPI PIO request function. */ -static void -zip_pio_request(zip_t *dev, uint8_t out) -{ - int ret = 0; - - if (dev->drv->bus_type < ZIP_BUS_SCSI) { - zip_log("ZIP %i: Lowering IDE IRQ\n", dev->id); - ide_irq_lower(ide_drives[dev->drv->ide_channel]); - } - - dev->status = BUSY_STAT; - - if (dev->pos >= dev->packet_len) { - zip_log("ZIP %i: %i bytes %s, command done\n", dev->id, dev->pos, out ? "written" : "read"); - - dev->pos = dev->request_pos = 0; - if (out) { - ret = zip_phase_data_out(dev); - /* If ret = 0 (phase 1 error), then we do not do anything else other than - free the buffer, as the phase and callback have already been set by the - error function. */ - if (ret) - zip_command_complete(dev); - } else - zip_command_complete(dev); - zip_buf_free(dev); - } else { - zip_log("ZIP %i: %i bytes %s, %i bytes are still left\n", dev->id, dev->pos, - out ? "written" : "read", dev->packet_len - dev->pos); - - /* If less than (packet length) bytes are remaining, update packet length - accordingly. */ - if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) - dev->max_transfer_len = dev->packet_len - dev->pos; - zip_log("ZIP %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, - dev->max_transfer_len); - - dev->packet_status = out ? ZIP_PHASE_DATA_OUT : ZIP_PHASE_DATA_IN; - - dev->status = BUSY_STAT; - dev->phase = 1; - zip_phase_callback(dev); - dev->callback = 0LL; - zip_set_callback(dev); - - dev->request_pos = 0; - } -} - - -static int -zip_read_from_ide_dma(uint8_t channel) -{ - zip_t *dev; - - uint8_t id = atapi_zip_drives[channel]; - int ret; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - if (ide_bus_master_write) { - ret = ide_bus_master_write(channel >> 1, - zipbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(dev); - return 0; - } else - return 1; - } else - return 0; -} - - -static int -zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - zip_t *dev; - - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zip_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(zipbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); - return 1; -} - - -static void -zip_irq_raise(zip_t *dev) -{ - if (dev->drv->bus_type < ZIP_BUS_SCSI) - ide_irq_raise(ide_drives[dev->drv->ide_channel]); -} - - -static int -zip_read_from_dma(zip_t *dev) -{ - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - int ret = 0; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - ret = zip_read_from_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - else - ret = zip_read_from_ide_dma(dev->drv->ide_channel); - - if (ret != 1) - return ret; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - zip_log("ZIP %i: SCSI Input data length: %i\n", dev->id, *BufLen); - else - zip_log("ZIP %i: ATAPI Input data length: %i\n", dev->id, dev->packet_len); - - ret = zip_phase_data_out(dev); - - if (ret) - return 1; - else - return 0; -} - - -static int -zip_write_to_ide_dma(uint8_t channel) -{ - zip_t *dev; - - uint8_t id = atapi_zip_drives[channel]; - int ret; - - if (id > ZIP_NUM) { - zip_log("ZIP %i: Drive not found\n", id); - return 0; - } - - dev = zip[id]; - - if (ide_bus_master_read) { - ret = ide_bus_master_read(channel >> 1, - zipbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(dev); - return 0; - } else - return 1; - } else - return 0; -} - - -static int -zip_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - zip_t *dev; - - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zip_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, zipbufferb, *BufLen); - zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - zipbufferb[0], zipbufferb[1], zipbufferb[2], zipbufferb[3], zipbufferb[4], zipbufferb[5], - zipbufferb[6], zipbufferb[7]); - zip_log("ZIP %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); - return 1; -} - - -static int -zip_write_to_dma(zip_t *dev) -{ - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; - int ret = 0; - - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - zip_log("Write to SCSI DMA: (%02X:%02X)\n", dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - ret = zip_write_to_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - } else - ret = zip_write_to_ide_dma(dev->drv->ide_channel); - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - zip_log("ZIP %i: SCSI Output data length: %i\n", dev->id, *BufLen); - else - zip_log("ZIP %i: ATAPI Output data length: %i\n", dev->id, dev->packet_len); - - return ret; -} - - -void -zip_phase_callback(zip_t *dev) -{ - int ret; - - switch(dev->packet_status) { - case ZIP_PHASE_IDLE: - zip_log("ZIP %i: ZIP_PHASE_IDLE\n", dev->id); - dev->pos = 0; - dev->phase = 1; - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - return; - case ZIP_PHASE_COMMAND: - zip_log("ZIP %i: ZIP_PHASE_COMMAND\n", dev->id); - dev->status = BUSY_STAT | (dev->status & ERR_STAT); - memcpy(dev->atapi_cdb, zipbufferb, 12); - zip_command(dev, dev->atapi_cdb); - return; - case ZIP_PHASE_COMPLETE: - zip_log("ZIP %i: ZIP_PHASE_COMPLETE\n", dev->id); - dev->status = READY_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - ui_sb_update_icon(SB_ZIP | dev->id, 0); - zip_irq_raise(dev); - return; - case ZIP_PHASE_DATA_OUT: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT\n", dev->id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 0; - zip_irq_raise(dev); - return; - case ZIP_PHASE_DATA_OUT_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", dev->id); - ret = zip_read_from_dma(dev); - - if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP %i: DMA data out phase done\n"); - zip_buf_free(dev); - zip_command_complete(dev); - } else if (ret == 2) { - zip_log("ZIP %i: DMA out not enabled, wait\n"); - zip_command_bus(dev); - } else { - zip_log("ZIP %i: DMA data out phase failure\n"); - zip_buf_free(dev); - } - return; - case ZIP_PHASE_DATA_IN: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", dev->id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 2; - zip_irq_raise(dev); - return; - case ZIP_PHASE_DATA_IN_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", dev->id); - ret = zip_write_to_dma(dev); - - if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP %i: DMA data in phase done\n", dev->id); - zip_buf_free(dev); - zip_command_complete(dev); - } else if (ret == 2) { - zip_log("ZIP %i: DMA in not enabled, wait\n", dev->id); - zip_command_bus(dev); - } else { - zip_log("ZIP %i: DMA data in phase failure\n", dev->id); - zip_buf_free(dev); - } - return; - case ZIP_PHASE_ERROR: - zip_log("ZIP %i: ZIP_PHASE_ERROR\n", dev->id); - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - zip_irq_raise(dev); - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - } -} - - -uint32_t -zip_read(uint8_t channel, int length) -{ - zip_t *dev; - - uint16_t *zipbufferw; - uint32_t *zipbufferl; - - uint8_t id = atapi_zip_drives[channel]; - - uint32_t temp = 0; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zipbufferw = (uint16_t *) zipbufferb; - zipbufferl = (uint32_t *) zipbufferb; - - if (!zipbufferb) - return 0; - - /* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it, - which can happen when issuing media access commands with an allocated length below minimum request length - (which is 1 sector = 512 bytes). */ - switch(length) { - case 1: - temp = (dev->pos < dev->packet_len) ? zipbufferb[dev->pos] : 0; - dev->pos++; - dev->request_pos++; - break; - case 2: - temp = (dev->pos < dev->packet_len) ? zipbufferw[dev->pos >> 1] : 0; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - temp = (dev->pos < dev->packet_len) ? zipbufferl[dev->pos >> 2] : 0; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return 0; - } - - if (dev->packet_status == ZIP_PHASE_DATA_IN) { - zip_log("ZIP %i: Returning: %04X (buffer position: %05i, request position: %05i)\n", - id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - zip_log("ZIP %i: Issuing read callback\n", id); - zip_pio_request(dev, 0); - } - return temp; - } else { - zip_log("ZIP %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n", - id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - return 0; - } -} - - -void -zip_write(uint8_t channel, uint32_t val, int length) -{ - zip_t *dev; - - uint16_t *zipbufferw; - uint32_t *zipbufferl; - - uint8_t id = atapi_zip_drives[channel]; - - if (id > ZIP_NUM) - return; - - dev = zip[id]; - - if (dev->packet_status == ZIP_PHASE_IDLE) { - if (!zipbufferb) - zip_buf_alloc(dev, 12); - } - - zipbufferw = (uint16_t *) zipbufferb; - zipbufferl = (uint32_t *) zipbufferb; - - if (!zipbufferb) - return; - - switch(length) { - case 1: - zipbufferb[dev->pos] = val & 0xff; - dev->pos++; - dev->request_pos++; - break; - case 2: - zipbufferw[dev->pos >> 1] = val & 0xffff; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - zipbufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; - } - - if (dev->packet_status == ZIP_PHASE_DATA_OUT) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - zip_pio_request(dev, 1); - } - return; - } else if (dev->packet_status == ZIP_PHASE_IDLE) { - if (dev->pos >= 12) { - dev->pos = 0; - dev->status = BUSY_STAT; - dev->packet_status = ZIP_PHASE_COMMAND; - timer_process(); - zip_phase_callback(dev); - timer_update_outstanding(); - } - return; - } -} - - -/* Peform a master init on the entire module. */ -void -zip_global_init(void) -{ - /* Clear the global data. */ - memset(zip, 0x00, sizeof(zip)); - memset(zip_drives, 0x00, sizeof(zip_drives)); -} - - -void -zip_hard_reset(void) -{ - int c; - - for (c = 0; c < ZIP_NUM; c++) { - if (zip_drives[c].bus_type) { - zip_log("ZIP hard_reset drive=%d\n", c); - - if (!zip[c]) { - zip[c] = (zip_t *) malloc(sizeof(zip_t)); - memset(zip[c], 0, sizeof(zip_t)); - } - - zip[c]->id = c; - zip[c]->drv = &zip_drives[c]; - - zip_init(zip[c]); - - if (wcslen(zip_drives[c].image_path)) - zip_load(zip[c], zip_drives[c].image_path); - - zip_mode_sense_load(zip[c]); - } - } - - build_atapi_zip_map(); -} - - -void -zip_close(void) -{ - zip_t *dev; - int c; - - for (c = 0; c < ZIP_NUM; c++) { - dev = zip[c]; - - if (dev) { - zip_disk_close(dev); - - free(zip[c]); - zip[c] = NULL; - } - } -} diff --git a/src - Cópia/disk/zip.h b/src - Cópia/disk/zip.h deleted file mode 100644 index f57e2ba3b..000000000 --- a/src - Cópia/disk/zip.h +++ /dev/null @@ -1,156 +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. - * - * Implementation of the Iomega ZIP drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * Version: @(#)zip.h 1.0.6 2018/04/30 - * - * Author: Miran Grca, - * - * Copyright 2018 Miran Grca. - */ -#ifndef EMU_ZIP_H -#define EMU_ZIP_H - - -#define ZIP_NUM 4 - -#define ZIP_PHASE_IDLE 0x00 -#define ZIP_PHASE_COMMAND 0x01 -#define ZIP_PHASE_COMPLETE 0x02 -#define ZIP_PHASE_DATA_IN 0x03 -#define ZIP_PHASE_DATA_IN_DMA 0x04 -#define ZIP_PHASE_DATA_OUT 0x05 -#define ZIP_PHASE_DATA_OUT_DMA 0x06 -#define ZIP_PHASE_ERROR 0x80 - -#define BUF_SIZE 32768 - -#define ZIP_TIME (5LL * 100LL * (1LL << TIMER_SHIFT)) - -#define ZIP_SECTORS (96*2048) - -#define ZIP_250_SECTORS (489532) - - -enum { - ZIP_BUS_DISABLED = 0, - ZIP_BUS_ATAPI = 4, - ZIP_BUS_SCSI, - ZIP_BUS_USB -}; - - -typedef struct { - unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ - uint8_t ide_channel, - bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - - unsigned int scsi_device_id, scsi_device_lun, - is_250; - - wchar_t image_path[1024], - prev_image_path[1024]; - - int read_only, ui_writeprot; - - uint32_t medium_size, base; - - FILE *f; -} zip_drive_t; - -typedef struct { - mode_sense_pages_t ms_pages_saved; - - zip_drive_t *drv; - - uint8_t previous_command, - error, features, - status, phase, - id, *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; - - uint16_t request_length, max_transfer_len; - - int toctimes, media_status, - is_dma, requested_blocks, - current_page_len, current_page_pos, - total_length, written_length, - mode_select_phase, do_page_save, - callback, data_pos, - packet_status, unit_attention, - cdb_len_setting, cdb_len, - request_pos, total_read, - block_total, all_blocks_total, - old_len, block_descriptor_len, - init_length; - - uint32_t sector_pos, sector_len, - packet_len, pos, - seek_pos; - - uint64_t current_page_code; -} zip_t; - - -extern zip_t *zip[ZIP_NUM]; -extern zip_drive_t zip_drives[ZIP_NUM]; -extern uint8_t atapi_zip_drives[8]; -extern uint8_t scsi_zip_drives[16][8]; - -#define zip_sense_error dev->sense[0] -#define zip_sense_key dev->sense[2] -#define zip_asc dev->sense[12] -#define zip_ascq dev->sense[13] - - -#ifdef __cplusplus -extern "C" { -#endif - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; - -extern void build_atapi_zip_map(void); -extern void build_scsi_zip_map(void); -extern int zip_ZIP_PHASE_to_scsi(zip_t *dev); -extern int zip_atapi_phase_to_scsi(zip_t *dev); -extern void zip_command(zip_t *dev, uint8_t *cdb); -extern void zip_phase_callback(zip_t *dev); -extern uint32_t zip_read(uint8_t channel, int length); -extern void zip_write(uint8_t channel, uint32_t val, int length); - -extern void zip_disk_close(zip_t *dev); -extern void zip_disk_reload(zip_t *dev); -extern void zip_reset(zip_t *dev); -extern void zip_set_signature(zip_t *dev); -extern void zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length); -extern void zip_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); -extern void zip_insert(zip_t *dev); - -extern int find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern int zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); - -extern void zip_global_init(void); -extern void zip_hard_reset(void); - -extern int zip_load(zip_t *dev, wchar_t *fn); -extern void zip_close(); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_ZIP_H*/ diff --git a/src - Cópia/dma.c b/src - Cópia/dma.c deleted file mode 100644 index ef07c6137..000000000 --- a/src - Cópia/dma.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * 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. - * - * Implementation of the Intel DMA controllers. - * - * Version: @(#)dma.c 1.0.3 2018/03/13 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "cpu/x86.h" -#include "machine/machine.h" -#include "mca.h" -#include "mem.h" -#include "io.h" -#include "dma.h" - - -dma_t dma[8]; - - -static uint8_t dmaregs[16]; -static uint8_t dma16regs[16]; -static uint8_t dmapages[16]; -static int dma_wp, - dma16_wp; -static uint8_t dma_m; -static uint8_t dma_stat; -static uint8_t dma_stat_rq; -static uint8_t dma_command, - dma16_command; -static struct { - int xfr_command, - xfr_channel; - int byte_ptr; - - int is_ps2; -} dma_ps2; - - -#define DMA_PS2_IOA (1 << 0) -#define DMA_PS2_XFER_MEM_TO_IO (1 << 2) -#define DMA_PS2_XFER_IO_TO_MEM (3 << 2) -#define DMA_PS2_XFER_MASK (3 << 2) -#define DMA_PS2_DEC2 (1 << 4) -#define DMA_PS2_SIZE16 (1 << 6) - - -static void dma_ps2_run(int channel); - - -static uint8_t -dma_read(uint16_t addr, void *priv) -{ - int channel = (addr >> 1) & 3; - uint8_t temp; - - switch (addr & 0xf) { - case 0: - case 2: - case 4: - case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) - return(dma[channel].ac & 0xff); - return((dma[channel].ac >> 8) & 0xff); - - case 1: - case 3: - case 5: - case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) - temp = dma[channel].cc & 0xff; - else - temp = dma[channel].cc >> 8; - return(temp); - - case 8: /*Status register*/ - temp = dma_stat & 0xf; - dma_stat &= ~0xf; - return(temp); - - case 0xd: - return(0); - } - - return(dmaregs[addr & 0xf]); -} - - -static void -dma_write(uint16_t addr, uint8_t val, void *priv) -{ - int channel = (addr >> 1) & 3; - - dmaregs[addr & 0xf] = val; - switch (addr & 0xf) { - case 0: - case 2: - case 4: - case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; - else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); - dma[channel].ac = dma[channel].ab; - return; - - case 1: - case 3: - case 5: - case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) - dma[channel].cb = (dma[channel].cb & 0xff00) | val; - else - dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); - dma[channel].cc = dma[channel].cb; - return; - - case 8: /*Control register*/ - dma_command = val; - return; - - case 0xa: /*Mask*/ - if (val & 4) - dma_m |= (1 << (val & 3)); - else - dma_m &= ~(1 << (val & 3)); - return; - - case 0xb: /*Mode*/ - channel = (val & 3); - dma[channel].mode = val; - if (dma_ps2.is_ps2) { - dma[channel].ps2_mode &= ~0x1c; - if (val & 0x20) - dma[channel].ps2_mode |= 0x10; - if ((val & 0xc) == 8) - dma[channel].ps2_mode |= 4; - else if ((val & 0xc) == 4) - dma[channel].ps2_mode |= 0xc; - } - return; - - case 0xc: /*Clear FF*/ - dma_wp = 0; - return; - - case 0xd: /*Master clear*/ - dma_wp = 0; - dma_m |= 0xf; - return; - - case 0xf: /*Mask write*/ - dma_m = (dma_m & 0xf0) | (val & 0xf); - return; - } -} - - -static uint8_t -dma_ps2_read(uint16_t addr, void *priv) -{ - dma_t *dma_c = &dma[dma_ps2.xfr_channel]; - uint8_t temp = 0xff; - - switch (addr) { - case 0x1a: - switch (dma_ps2.xfr_command) { - case 2: /*Address*/ - case 3: - switch (dma_ps2.byte_ptr) { - case 0: - temp = dma_c->ac & 0xff; - dma_ps2.byte_ptr = 1; - break; - case 1: - temp = (dma_c->ac >> 8) & 0xff; - dma_ps2.byte_ptr = 2; - break; - case 2: - temp = (dma_c->ac >> 16) & 0xff; - dma_ps2.byte_ptr = 0; - break; - } - break; - - case 4: /*Count*/ - case 5: - if (dma_ps2.byte_ptr) - temp = dma_c->cc >> 8; - else - temp = dma_c->cc & 0xff; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - - case 6: /*Read DMA status*/ - if (dma_ps2.byte_ptr) { - temp = ((dma_stat_rq & 0xf0) >> 4) | (dma_stat & 0xf0); - dma_stat &= ~0xf0; - dma_stat_rq &= ~0xf0; - } else { - temp = (dma_stat_rq & 0xf) | ((dma_stat & 0xf) << 4); - dma_stat &= ~0xf; - dma_stat_rq &= ~0xf; - } - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - - case 7: /*Mode*/ - temp = dma_c->ps2_mode; - break; - - case 8: /*Arbitration Level*/ - temp = dma_c->arb_level; - break; - - default: - fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); - } - break; - } - - return(temp); -} - - -static void -dma_ps2_write(uint16_t addr, uint8_t val, void *priv) -{ - dma_t *dma_c = &dma[dma_ps2.xfr_channel]; - uint8_t mode; - - switch (addr) { - case 0x18: - dma_ps2.xfr_channel = val & 0x7; - dma_ps2.xfr_command = val >> 4; - dma_ps2.byte_ptr = 0; - switch (dma_ps2.xfr_command) { - case 9: /*Set DMA mask*/ - dma_m |= (1 << dma_ps2.xfr_channel); - break; - - case 0xa: /*Reset DMA mask*/ - dma_m &= ~(1 << dma_ps2.xfr_channel); - break; - - case 0xb: - if (!(dma_m & (1 << dma_ps2.xfr_channel))) - dma_ps2_run(dma_ps2.xfr_channel); - break; - } - break; - - case 0x1a: - switch (dma_ps2.xfr_command) { - case 0: /*I/O address*/ - if (dma_ps2.byte_ptr) - dma_c->io_addr = (dma_c->io_addr & 0x00ff) | (val << 8); - else - dma_c->io_addr = (dma_c->io_addr & 0xff00) | val; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - - case 2: /*Address*/ - switch (dma_ps2.byte_ptr) { - case 0: - dma_c->ac = (dma_c->ac & 0xffff00) | val; - dma_ps2.byte_ptr = 1; - break; - - case 1: - dma_c->ac = (dma_c->ac & 0xff00ff) | (val << 8); - dma_ps2.byte_ptr = 2; - break; - - case 2: - dma_c->ac = (dma_c->ac & 0x00ffff) | (val << 16); - dma_ps2.byte_ptr = 0; - break; - } - dma_c->ab = dma_c->ac; - break; - - case 4: /*Count*/ - if (dma_ps2.byte_ptr) - dma_c->cc = (dma_c->cc & 0xff) | (val << 8); - else - dma_c->cc = (dma_c->cc & 0xff00) | val; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - dma_c->cb = dma_c->cc; - break; - - case 7: /*Mode register*/ - mode = 0; - if (val & DMA_PS2_DEC2) - mode |= 0x20; - if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_MEM_TO_IO) - mode |= 8; - else if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_IO_TO_MEM) - mode |= 4; - dma_c->mode = (dma_c->mode & ~0x2c) | mode; - dma_c->ps2_mode = val; - dma_c->size = val & DMA_PS2_SIZE16; - break; - - case 8: /*Arbitration Level*/ - dma_c->arb_level = val; - break; - - default: - fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); - } - break; - } -} - - -static uint8_t -dma16_read(uint16_t addr, void *priv) -{ - int channel = ((addr >> 2) & 3) + 4; - uint8_t temp; - - addr >>= 1; - switch (addr & 0xf) { - case 0: - case 2: - case 4: - case 6: /*Address registers*/ - dma16_wp ^= 1; - if (dma_ps2.is_ps2) { - if (dma16_wp) - return(dma[channel].ac); - return((dma[channel].ac >> 8) & 0xff); - } - if (dma16_wp) - return((dma[channel].ac >> 1) & 0xff); - return((dma[channel].ac >> 9) & 0xff); - - case 1: - case 3: - case 5: - case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) - temp = dma[channel].cc & 0xff; - else - temp = dma[channel].cc >> 8; - return(temp); - - case 8: /*Status register*/ - temp = dma_stat >> 4; - dma_stat &= ~0xf0; - return(temp); - } - - return(dma16regs[addr & 0xf]); -} - - -static void -dma16_write(uint16_t addr, uint8_t val, void *priv) -{ - int channel = ((addr >> 2) & 3) + 4; - addr >>= 1; - - dma16regs[addr & 0xf] = val; - switch (addr & 0xf) { - case 0: - case 2: - case 4: - case 6: /*Address registers*/ - dma16_wp ^= 1; - if (dma_ps2.is_ps2) { - if (dma16_wp) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; - else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); - } else { - if (dma16_wp) - dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1); - else - dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9); - } - dma[channel].ac = dma[channel].ab; - return; - - case 1: - case 3: - case 5: - case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) - dma[channel].cb = (dma[channel].cb & 0xff00) | val; - else - dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); - dma[channel].cc = dma[channel].cb; - return; - - case 8: /*Control register*/ - return; - - case 0xa: /*Mask*/ - if (val & 4) - dma_m |= (0x10 << (val & 3)); - else - dma_m &= ~(0x10 << (val & 3)); - return; - - case 0xb: /*Mode*/ - channel = (val & 3) + 4; - dma[channel].mode = val; - if (dma_ps2.is_ps2) { - dma[channel].ps2_mode &= ~0x1c; - if (val & 0x20) - dma[channel].ps2_mode |= 0x10; - if ((val & 0xc) == 8) - dma[channel].ps2_mode |= 4; - else if ((val & 0xc) == 4) - dma[channel].ps2_mode |= 0xc; - } - return; - - case 0xc: /*Clear FF*/ - dma16_wp = 0; - return; - - case 0xd: /*Master clear*/ - dma16_wp = 0; - dma_m |= 0xf0; - return; - - case 0xf: /*Mask write*/ - dma_m = (dma_m & 0x0f) | ((val & 0xf) << 4); - return; - } -} - - -static void -dma_page_write(uint16_t addr, uint8_t val, void *priv) -{ - dmapages[addr & 0xf] = val; - - switch (addr & 0xf) { - case 1: - dma[2].page = (AT) ? val : val & 0xf; - dma[2].ab = (dma[2].ab & 0xffff) | (dma[2].page << 16); - dma[2].ac = (dma[2].ac & 0xffff) | (dma[2].page << 16); - break; - - case 2: - dma[3].page = (AT) ? val : val & 0xf; - dma[3].ab = (dma[3].ab & 0xffff) | (dma[3].page << 16); - dma[3].ac = (dma[3].ac & 0xffff) | (dma[3].page << 16); - break; - - case 3: - dma[1].page = (AT) ? val : val & 0xf; - dma[1].ab = (dma[1].ab & 0xffff) | (dma[1].page << 16); - dma[1].ac = (dma[1].ac & 0xffff) | (dma[1].page << 16); - break; - - case 7: - dma[0].page = (AT) ? val : val & 0xf; - dma[0].ab = (dma[0].ab & 0xffff) | (dma[0].page << 16); - dma[0].ac = (dma[0].ac & 0xffff) | (dma[0].page << 16); - break; - - case 0x9: - dma[6].page = val & 0xfe; - dma[6].ab = (dma[6].ab & 0x1ffff) | (dma[6].page << 16); - dma[6].ac = (dma[6].ac & 0x1ffff) | (dma[6].page << 16); - break; - - case 0xa: - dma[7].page = val & 0xfe; - dma[7].ab = (dma[7].ab & 0x1ffff) | (dma[7].page << 16); - dma[7].ac = (dma[7].ac & 0x1ffff) | (dma[7].page << 16); - break; - - case 0xb: - dma[5].page = val & 0xfe; - dma[5].ab = (dma[5].ab & 0x1ffff) | (dma[5].page << 16); - dma[5].ac = (dma[5].ac & 0x1ffff) | (dma[5].page << 16); - break; - - case 0xf: - dma[4].page = val & 0xfe; - dma[4].ab = (dma[4].ab & 0x1ffff) | (dma[4].page << 16); - dma[4].ac = (dma[4].ac & 0x1ffff) | (dma[4].page << 16); - break; - } -} - - -static uint8_t -dma_page_read(uint16_t addr, void *priv) -{ - return(dmapages[addr & 0xf]); -} - - -void -dma_reset(void) -{ - int c; - - dma_wp = dma16_wp = 0; - dma_m = 0; - - for (c = 0; c < 16; c++) - dmaregs[c] = 0; - for (c = 0; c < 8; c++) { - dma[c].mode = 0; - dma[c].ac = 0; - dma[c].cc = 0; - dma[c].ab = 0; - dma[c].cb = 0; - dma[c].size = (c & 4) ? 1 : 0; - } -} - - -void -dma_init(void) -{ - io_sethandler(0x0000, 16, - dma_read,NULL,NULL, dma_write,NULL,NULL, NULL); - io_sethandler(0x0080, 8, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); - dma_ps2.is_ps2 = 0; -} - - -void -dma16_init(void) -{ - io_sethandler(0x00C0, 32, - dma16_read,NULL,NULL, dma16_write,NULL,NULL, NULL); - io_sethandler(0x0088, 8, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); -} - - -void -dma_alias_set(void) -{ - io_sethandler(0x0090, 16, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); -} - - -void -dma_alias_remove(void) -{ - io_removehandler(0x0090, 16, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); -} - - -void -dma_alias_remove_piix(void) -{ - io_removehandler(0x0090, 1, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); - io_removehandler(0x0094, 3, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); - io_removehandler(0x0098, 1, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); - io_removehandler(0x009C, 3, - dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); -} - - -void -ps2_dma_init(void) -{ - io_sethandler(0x0018, 1, - dma_ps2_read,NULL,NULL, dma_ps2_write,NULL,NULL, NULL); - io_sethandler(0x001a, 1, - dma_ps2_read,NULL,NULL, dma_ps2_write,NULL,NULL, NULL); - dma_ps2.is_ps2 = 1; -} - - -uint8_t -_dma_read(uint32_t addr) -{ - uint8_t temp = mem_readb_phys_dma(addr); - - return(temp); -} - - -void -_dma_write(uint32_t addr, uint8_t val) -{ - mem_writeb_phys_dma(addr, val); - mem_invalidate_range(addr, addr); -} - - -int -dma_channel_read(int channel) -{ - dma_t *dma_c = &dma[channel]; - uint16_t temp; - int tc = 0; - - if (channel < 4) { - if (dma_command & 0x04) - return(DMA_NODATA); - } else { - if (dma16_command & 0x04) - return(DMA_NODATA); - } - - if (! AT) - refreshread(); - - if (dma_m & (1 << channel)) - return(DMA_NODATA); - if ((dma_c->mode & 0xC) != 8) - return(DMA_NODATA); - - if (! dma_c->size) { - temp = _dma_read(dma_c->ac); - - if (dma_c->mode & 0x20) { - if (dma_ps2.is_ps2) - dma_c->ac--; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); - } else { - if (dma_ps2.is_ps2) - dma_c->ac++; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); - } - } else { - temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); - - if (dma_c->mode & 0x20) { - if (dma_ps2.is_ps2) - dma_c->ac -= 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - } else { - if (dma_ps2.is_ps2) - dma_c->ac += 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); - } - } - - dma_stat_rq |= (1 << channel); - - dma_c->cc--; - if (dma_c->cc < 0) { - tc = 1; - if (dma_c->mode & 0x10) { /*Auto-init*/ - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); - } - - if (tc) - return(temp | DMA_OVER); - - return(temp); -} - - -int -dma_channel_write(int channel, uint16_t val) -{ - dma_t *dma_c = &dma[channel]; - - if (channel < 4) { - if (dma_command & 0x04) - return(DMA_NODATA); - } else { - if (dma16_command & 0x04) - return(DMA_NODATA); - } - - if (! AT) - refreshread(); - - if (dma_m & (1 << channel)) - return(DMA_NODATA); - if ((dma_c->mode & 0xC) != 4) - return(DMA_NODATA); - - if (! dma_c->size) { - _dma_write(dma_c->ac, val & 0xff); - - if (dma_c->mode & 0x20) { - if (dma_ps2.is_ps2) - dma_c->ac--; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); - } else { - if (dma_ps2.is_ps2) - dma_c->ac++; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); - } - } else { - _dma_write(dma_c->ac, val & 0xff); - _dma_write(dma_c->ac + 1, val >> 8); - - if (dma_c->mode & 0x20) { - if (dma_ps2.is_ps2) - dma_c->ac -= 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - } else { - if (dma_ps2.is_ps2) - dma_c->ac += 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); - } - } - - dma_stat_rq |= (1 << channel); - - dma_c->cc--; - if (dma_c->cc < 0) { - if (dma_c->mode & 0x10) { /*Auto-init*/ - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); - } - - if (dma_m & (1 << channel)) - return(DMA_OVER); - - return(0); -} - - -static void -dma_ps2_run(int channel) -{ - dma_t *dma_c = &dma[channel]; - - switch (dma_c->ps2_mode & DMA_PS2_XFER_MASK) { - case DMA_PS2_XFER_MEM_TO_IO: - do { - if (! dma_c->size) { - uint8_t temp = _dma_read(dma_c->ac); - - outb(dma_c->io_addr, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } else { - uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); - - outw(dma_c->io_addr, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma_c->cc--; - } while (dma_c->cc > 0); - - dma_stat |= (1 << channel); - break; - - case DMA_PS2_XFER_IO_TO_MEM: - do { - if (! dma_c->size) { - uint8_t temp = inb(dma_c->io_addr); - - _dma_write(dma_c->ac, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } else { - uint16_t temp = inw(dma_c->io_addr); - - _dma_write(dma_c->ac, temp & 0xff); - _dma_write(dma_c->ac + 1, temp >> 8); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma_c->cc--; - } while (dma_c->cc > 0); - - ps2_cache_clean(); - dma_stat |= (1 << channel); - break; - - default: /*Memory verify*/ - do { - if (! dma_c->size) { - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } else { - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma->cc--; - } while (dma->cc > 0); - - dma_stat |= (1 << channel); - break; - - } -} - - -int -dma_mode(int channel) -{ - if (channel < 4) - return(dma[channel].mode); - else - return(dma[channel & 3].mode); -} - - -/* DMA Bus Master Page Read/Write */ -void -DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize) -{ - uint32_t i = 0; - -#if 0 - memcpy(DataRead, &ram[PhysAddress], TotalSize); -#else - for (i = 0; i < TotalSize; i++) - DataRead[i] = mem_readb_phys_dma(PhysAddress + i); -#endif -} - - -void -DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize) -{ - uint32_t i = 0; - -#if 0 - mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); - memcpy(&ram[PhysAddress], DataWrite, TotalSize); -#else - for (i = 0; i < TotalSize; i++) - mem_writeb_phys_dma(PhysAddress + i, DataWrite[i]); - - mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); -#endif -} diff --git a/src - Cópia/dma.h b/src - Cópia/dma.h deleted file mode 100644 index 32f90c4e7..000000000 --- a/src - Cópia/dma.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 Intel DMA controller. - * - * Version: @(#)dma.h 1.0.2 2018/03/12 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_DMA_H -# define EMU_DMA_H - - -#define DMA_NODATA -1 -#define DMA_OVER 0x10000 -#define DMA_VERIFY 0x20000 - - -typedef struct { - uint32_t ab, ac; - uint16_t cb; - int cc; - int wp; - uint8_t m, mode; - uint8_t page; - uint8_t stat, stat_rq; - uint8_t command; - int size; - - uint8_t ps2_mode; - uint8_t arb_level; - uint16_t io_addr; -} dma_t; - - -extern dma_t dma[8]; - - -extern void dma_init(void); -extern void dma16_init(void); -extern void ps2_dma_init(void); -extern void dma_reset(void); -extern int dma_mode(int channel); - -extern void readdma0(void); -extern int readdma1(void); -extern uint8_t readdma2(void); -extern int readdma3(void); - -extern void writedma2(uint8_t temp); - -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_remove(void); -extern void dma_alias_remove_piix(void); - -extern void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, - uint32_t TotalSize); -extern void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, - uint32_t TotalSize); - - -#endif /*EMU_DMA_H*/ diff --git a/src - Cópia/floppy/fdc.c b/src - Cópia/floppy/fdc.c deleted file mode 100644 index 37962cd3a..000000000 --- a/src - Cópia/floppy/fdc.c +++ /dev/null @@ -1,2258 +0,0 @@ -/* - * 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. - * - * Implementation of the NEC uPD-765 and compatible floppy disk - * controller. - * - * Version: @(#)fdc.c 1.0.8 2018/05/09 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#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 "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "../ui.h" -#include "fdd.h" -#include "fdc.h" - - -extern int64_t motoron[FDD_NUM]; - - -const int command_has_drivesel[256] = { - 0, 0, - 1, /* READ TRACK */ - 0, - 1, /* SENSE DRIVE STATUS */ - 1, /* WRITE DATA */ - 1, /* READ DATA */ - 1, /* RECALIBRATE */ - 0, - 1, /* WRITE DELETED DATA */ - 1, /* READ ID */ - 0, - 1, /* READ DELETED DATA */ - 1, /* FORMAT TRACK */ - 0, - 1, /* SEEK, RELATIVE SEEK */ - 0, - 1, /* SCAN EQUAL */ - 0, 0, 0, 0, - 1, /* VERIFY */ - 0, 0, 0, - 1, /* SCAN LOW OR EQUAL */ - 0, 0, 0, - 1, /* SCAN HIGH OR EQUAL */ - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -uint8_t current_drive = 0; - -static void fdc_callback(void *priv); -int timetolive; -int lastbyte=0; - -int floppymodified[4]; -int floppyrate[4]; - -#ifdef ENABLE_FDC_LOG -int fdc_do_log = ENABLE_FDC_LOG; -#endif - - -static void -fdc_log(const char *fmt, ...) -{ -#ifdef ENABLE_FDC_LOG - va_list ap; - - if (fdc_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -uint8_t -fdc_ps1_525(void) -{ - switch (romset) { - case ROM_IBMPS1_2011: - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2121_ISA: - return fdd_is_525(current_drive) ? 0x40 : 0x00; - default: - return 0x00; - } -} - - -void -fdc_ctrl_reset(void *p) -{ - fdc_t *fdc = (fdc_t *) p; - - fdc->stat = 0x80; - fdc->pnum = fdc->ptot=0; - fdc->st0 = 0; - fdc->lock = 0; - fdc->head = 0; - fdc->abort = 0; - fdc->step = 0; - if (!(fdc->flags & FDC_FLAG_AT)) - fdc->rate = 2; -} - - -sector_id_t -fdc_get_read_track_sector(fdc_t *fdc) -{ - return fdc->read_track_sector; -} - - -int -fdc_get_compare_condition(fdc_t *fdc) -{ - switch (fdc->interrupt) { - case 0x11: - default: - return 0; - case 0x19: - return 1; - case 0x1D: - return 2; - } -} - - -int -fdc_is_deleted(fdc_t *fdc) -{ - return fdc->deleted & 1; -} - - -int -fdc_is_sk(fdc_t *fdc) -{ - return (fdc->deleted & 0x20) ? 1 : 0; -} - - -void -fdc_set_wrong_am(fdc_t *fdc) -{ - fdc->wrong_am = 1; -} - - -int -fdc_get_drive(fdc_t *fdc) -{ - return fdc->drive; -} - - -int fdc_get_bitcell_period(fdc_t *fdc); -int fdc_get_bit_rate(fdc_t *fdc); -static void fdc_rate(fdc_t *fdc, int drive); - - -int -fdc_get_perp(fdc_t *fdc) -{ - if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR)) - return 0; - - return fdc->perp; -} - - -int -fdc_get_gap2(fdc_t *fdc, int drive) -{ - int auto_gap2 = 22; - - if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR)) - return 22; - - if (fdc->perp & 3) - return ((fdc->perp & 3) == 3) ? 41 : 22; - else { - auto_gap2 = (fdc_get_bit_rate(fdc) >= 3) ? 41 : 22; - return (fdc->perp & (4 << drive)) ? auto_gap2 : 22; - } -} - - -int -fdc_get_format_n(fdc_t *fdc) -{ - return fdc->format_n; -} - - -int -fdc_is_mfm(fdc_t *fdc) -{ - return fdc->mfm ? 1 : 0; -} - - -void -fdc_request_next_sector_id(fdc_t *fdc) -{ - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0xf0; - else - fdc->stat = 0xd0; -} - - -void -fdc_stop_id_request(fdc_t *fdc) -{ - fdc->stat &= 0x7f; -} - - -int -fdc_get_gap(fdc_t *fdc) -{ - return fdc->gap; -} - - -int -fdc_get_dtl(fdc_t *fdc) -{ - return fdc->dtl; -} - - -int -fdc_get_format_sectors(fdc_t *fdc) -{ - return fdc->format_sectors; -} - - -static void -fdc_reset_fifo_buf(fdc_t *fdc) -{ - memset(fdc->fifobuf, 0, 16); - fdc->fifobufpos = 0; -} - - -static void -fdc_fifo_buf_advance(fdc_t *fdc) -{ - if (fdc->fifobufpos == fdc->tfifo) - fdc->fifobufpos = 0; - else - fdc->fifobufpos++; -} - - -static void -fdc_fifo_buf_write(fdc_t *fdc, uint8_t val) -{ - fdc->fifobuf[fdc->fifobufpos] = val; - fdc_fifo_buf_advance(fdc); -} - - -static int -fdc_fifo_buf_read(fdc_t *fdc) -{ - int temp = fdc->fifobuf[fdc->fifobufpos]; - fdc_fifo_buf_advance(fdc); - if (!fdc->fifobufpos) - fdc->data_ready = 0; - return temp; -} - - -static -void fdc_int(fdc_t *fdc) -{ - int ienable = 0; - - if (!(fdc->flags & FDC_FLAG_PCJR)) - ienable = !!(fdc->dor & 8); - - if (ienable) - picint(1 << fdc->irq); - - fdc->fintr = 1; -} - - -static void -fdc_watchdog_poll(void *priv) -{ - fdc_t *fdc = (fdc_t *) priv; - - fdc->watchdog_count--; - if (fdc->watchdog_count) - fdc->watchdog_timer += 1000LL * TIMER_USEC; - else { - fdc->watchdog_timer = 0LL; - if (fdc->dor & 0x20) - picint(1 << fdc->irq); - } -} - - -/* fdc->rwc per Winbond W83877F datasheet: - 0 = normal; - 1 = 500 kbps, 360 rpm; - 2 = 500 kbps, 300 rpm; - 3 = 250 kbps - - Drive is only aware of selected rate and densel, so on real hardware, the rate expected by fdc_t and the rate actually being - processed by drive can mismatch, in which case the fdc_t won't receive the correct data. -*/ - -void -fdc_update_rates(fdc_t *fdc) -{ - fdc_rate(fdc, 0); - fdc_rate(fdc, 1); - fdc_rate(fdc, 2); - fdc_rate(fdc, 3); -} - - -void -fdc_update_is_nsc(fdc_t *fdc, int is_nsc) -{ - int old_is_nsc = fdc->flags & FDC_FLAG_NSC; - if (is_nsc) - fdc->flags |= FDC_FLAG_NSC; - else - fdc->flags &= ~FDC_FLAG_NSC; - if ((old_is_nsc ^ fdc->flags) & FDC_FLAG_NSC) - fdc->densel_force = fdc->densel_force ^ 3; - fdc_update_rates(fdc); -} - - -void -fdc_update_max_track(fdc_t *fdc, int max_track) -{ - fdc->max_track = max_track; -} - - -void -fdc_update_enh_mode(fdc_t *fdc, int enh_mode) -{ - fdc->enh_mode = enh_mode; - fdc_update_rates(fdc); -} - - -int -fdc_get_rwc(fdc_t *fdc, int drive) -{ - return fdc->rwc[drive]; -} - - -void -fdc_update_rwc(fdc_t *fdc, int drive, int rwc) -{ - fdc_log("FDD %c: New RWC is %i\n", 0x41 + drive, rwc); - fdc->rwc[drive] = rwc; - fdc_rate(fdc, drive); -} - - -int -fdc_get_boot_drive(fdc_t *fdc) -{ - return fdc->boot_drive; -} - - -void -fdc_update_boot_drive(fdc_t *fdc, int boot_drive) -{ - fdc->boot_drive = boot_drive; -} - - -void -fdc_update_densel_polarity(fdc_t *fdc, int densel_polarity) -{ - fdc_log("FDC: New DENSEL polarity is %i\n", densel_polarity); - fdc->densel_polarity = densel_polarity; - fdc_update_rates(fdc); -} - - -uint8_t -fdc_get_densel_polarity(fdc_t *fdc) -{ - return fdc->densel_polarity; -} - - -void -fdc_update_densel_force(fdc_t *fdc, int densel_force) -{ - fdc_log("FDC: New DENSEL force is %i\n", densel_force); - fdc->densel_force = densel_force; - fdc_update_rates(fdc); -} - - -void -fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate) -{ - fdc_log("FDD %c: New drive rate is %i\n", 0x41 + drive, drvrate); - fdc->drvrate[drive] = drvrate; - fdc_rate(fdc, drive); -} - - -void -fdc_update_drv2en(fdc_t *fdc, int drv2en) -{ - fdc->drv2en = drv2en; -} - - -void -fdc_update_rate(fdc_t *fdc, int drive) -{ - if (((fdc->rwc[drive] == 1) || (fdc->rwc[drive] == 2)) && fdc->enh_mode) - fdc->bit_rate = 500; - else if ((fdc->rwc[drive] == 3) && fdc->enh_mode) - fdc->bit_rate = 250; - else switch (fdc->rate) { - case 0: /*High density*/ - fdc->bit_rate = 500; - break; - case 1: /*Double density (360 rpm)*/ - switch(fdc->drvrate[drive]) { - case 0: - fdc->bit_rate = 300; - break; - case 1: - fdc->bit_rate = 500; - break; - case 2: - fdc->bit_rate = 2000; - break; - } - break; - case 2: /*Double density*/ - fdc->bit_rate = 250; - break; - case 3: /*Extended density*/ - fdc->bit_rate = 1000; - break; - } - - fdc->bitcell_period = 1000000 / fdc->bit_rate * 2; /*Bitcell period in ns*/ -} - - -int -fdc_get_bit_rate(fdc_t *fdc) -{ - switch(fdc->bit_rate) { - case 500: - return 0; - case 300: - return 1; - case 2000: - return 1 | 4; - case 250: - return 2; - case 1000: - return 3; - default: - return 2; - } - return 2; -} - - -int -fdc_get_bitcell_period(fdc_t *fdc) -{ - return fdc->bitcell_period; -} - - -static int -fdc_get_densel(fdc_t *fdc, int drive) -{ - if (fdc->enh_mode) { - switch (fdc->rwc[drive]) { - case 1: - case 3: - return 0; - case 2: - return 1; - } - } - - if (!(fdc->flags & FDC_FLAG_NSC)) { - switch (fdc->densel_force) { - case 2: - return 1; - case 3: - return 0; - } - } else { - switch (fdc->densel_force) { - case 0: - return 0; - case 1: - return 1; - } - } - - switch (fdc->rate) { - case 0: - case 3: - return fdc->densel_polarity ? 1 : 0; - case 1: - case 2: - return fdc->densel_polarity ? 0 : 1; - } - - return 0; -} - - -static void -fdc_rate(fdc_t *fdc, int drive) -{ - fdc_update_rate(fdc, drive); - fdd_set_rate(drive, fdc->drvrate[drive], fdc->rate); - fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force); - fdd_set_densel(fdc_get_densel(fdc, drive)); -} - - -int -real_drive(fdc_t *fdc, int drive) -{ - if (drive < 2) - return drive ^ fdc->swap; - else - return drive; -} - - -void -fdc_seek(fdc_t *fdc, int drive, int params) -{ - fdd_seek(real_drive(fdc, drive), params); - fdc->time = 5000LL * (1 << TIMER_SHIFT); - - fdc->stat |= (1 << fdc->drive); -} - - -void -fdc_implied_seek(fdc_t *fdc) -{ - if (fdc->config & 0x40) { - if (fdc->params[1] != fdc->pcn[fdc->params[0] & 3]) { - fdc_seek(fdc, fdc->drive, ((int) fdc->params[1]) - ((int) fdc->pcn[fdc->params[0] & 3])); - fdc->pcn[fdc->params[0] & 3] = fdc->params[1]; - } - } -} - - -static void -fdc_bad_command(fdc_t *fdc) -{ - fdc->stat = 0x10; - fdc->interrupt = 0xfc; - timer_clock(); - fdc->time = 200LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); -} - - -static void -fdc_io_command_phase1(fdc_t *fdc, int out) -{ - fdc_reset_fifo_buf(fdc); - fdc_rate(fdc, fdc->drive); - fdc->head = fdc->params[2]; - fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); - fdc->sector=fdc->params[3]; - fdc->eot[fdc->drive] = fdc->params[5]; - fdc->gap = fdc->params[6]; - fdc->dtl = fdc->params[7]; - fdc_implied_seek(fdc); - fdc->rw_track = fdc->params[1]; - fdc->time = 0LL; - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 1); - fdc->stat = out ? 0x90 : 0x50; - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat |= 0x20; - if (out) { - fdc->written = 0; - fdc->pos = 0; - } else - fdc->inread = 1; -} - - -static void -fdc_sis(fdc_t *fdc) -{ - int drive_num; - - fdc->stat = (fdc->stat & 0xf) | 0xd0; - - if (fdc->reset_stat) { - drive_num = real_drive(fdc, 4 - fdc->reset_stat); - if ((!fdd_get_flags(drive_num)) || (drive_num >= FDD_NUM)) { - fdd_stop(drive_num); - fdd_set_head(drive_num, 0); - fdc->res[9] = 0xc0 | (4 - fdc->reset_stat) | (fdd_get_head(drive_num) ? 4 : 0); - } else - fdc->res[9] = 0xc0 | (4 - fdc->reset_stat); - - fdc->reset_stat--; - } else { - if (fdc->fintr) { - fdc->res[9] = (fdc->st0 & ~0x04) | (fdd_get_head(fdc->drive & 0x03) ? 4 : 0); - fdc->fintr = 0; - } else { - fdc->res[10] = 0x80; - fdc->paramstogo = 1; - return; - } - } - - fdc->res[10] = fdc->pcn[fdc->res[9] & 3]; - - fdc_log("Sense interrupt status: 2 parameters to go\n"); - fdc->paramstogo = 2; -} - - -static void -fdc_write(uint16_t addr, uint8_t val, void *priv) -{ - fdc_t *fdc = (fdc_t *) priv; - - int drive, i, drive_num; - - fdc_log("Write FDC %04X %02X\n", addr, val); - - cycles -= ISA_CYCLES(8); - - switch (addr&7) { - case 0: - return; - case 1: - return; - case 2: /*DOR*/ - if (fdc->flags & FDC_FLAG_PCJR) { - if ((fdc->dor & 0x40) && !(val & 0x40)) { - fdc->watchdog_timer = 1000LL * TIMER_USEC; - fdc->watchdog_count = 1000LL; - picintc(1 << fdc->irq); - } - if ((val & 0x80) && !(fdc->dor & 0x80)) { - timer_clock(); - fdc->time = 128LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - fdc->interrupt = -1; - ui_sb_update_icon(SB_FLOPPY | 0, 0); - fdc_ctrl_reset(fdc); - fdd_changed[0] = 1; - fdd_changed[1] = 1; - fdd_changed[2] = 1; - fdd_changed[3] = 1; - } - if (!fdd_get_flags(0)) - val &= 0xfe; - motoron[0] = val & 0x01; - fdc->st0 &= ~0x07; - fdc->st0 |= (fdd_get_head(0) ? 4 : 0); - } else { - if (!(val & 8) && (fdc->dor & 8)) { - fdc->tc = 1; - fdc_int(fdc); - } - if (!(val&4)) { - fdd_stop(real_drive(fdc, val & 3)); - fdc->stat = 0x00; - fdc->pnum = fdc->ptot = 0; - } - if (val&4) { - fdc->stat = 0x80; - fdc->pnum = fdc->ptot = 0; - } - if ((val&4) && !(fdc->dor&4)) { - timer_clock(); - fdc->time = 128LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - fdc->interrupt = -1; - fdc->perp &= 0xfc; - - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); - - fdc_ctrl_reset(fdc); - } - timer_clock(); - timer_update_outstanding(); - /* We can now simplify this since each motor now spins separately. */ - for (i = 0; i < FDD_NUM; i++) { - drive_num = real_drive(fdc, i); - if ((!fdd_get_flags(drive_num)) || (drive_num >= FDD_NUM)) - val &= ~(0x10 << drive_num); - else - motoron[i] = (val & (0x10 << drive_num)); - } - drive_num = real_drive(fdc, val & 0x03); - current_drive = real_drive(fdc, val & 0x03); - fdc->st0 &= ~0x07; - fdc->st0 |= real_drive(fdc, drive_num); - fdc->st0 |= (fdd_get_head(drive_num) ? 4 : 0); - } - fdc->dor=val; - return; - case 3: /* TDR */ - if (fdc->enh_mode) { - drive = real_drive(fdc, fdc->dor & 3); - fdc_update_rwc(fdc, drive, (val & 0x30) >> 4); - } - return; - case 4: - if (val & 0x80) { - timer_clock(); - fdc->time = 128LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - fdc->interrupt = -1; - fdc->perp &= 0xfc; - fdc_ctrl_reset(fdc); - } - /* if (fdc->flags & FDC_FLAG_PS1) - fdc->rate = val & 0x03; */ - return; - case 5: /*Command register*/ - if ((fdc->stat & 0xf0) == 0xb0) { - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) { - fdc->dat = val; - fdc->stat &= ~0x80; - } else { - fdc_fifo_buf_write(fdc, val); - if (fdc->fifobufpos == 0) - fdc->stat &= ~0x80; - } - break; - } - if (fdc->pnum==fdc->ptot) { - if ((fdc->stat & 0xf0) != 0x80) { - /* If bit 4 of the MSR is set, or the MSR is 0x00, - the fdc_t is NOT in the command phase, therefore - do NOT accept commands. */ - return; - } - - fdc->stat &= 0xf; - - fdc->tc = 0; - fdc->data_ready = 0; - - fdc->command = val; - fdc->stat |= 0x10; - fdc_log("Starting FDC command %02X\n",fdc->command); - - switch (fdc->command & 0x1f) { - case 0x01: /*Mode*/ - if (fdc->flags & FDC_FLAG_NSC) { - fdc->pnum = 0; - fdc->ptot = 4; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->format_state = 0; - } else - fdc_bad_command(fdc); - break; - case 0x02: /*Read track*/ - fdc->satisfying_sectors = 0; - fdc->sc = 0; - fdc->wrong_am = 0; - fdc->pnum = 0; - fdc->ptot = 8; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->mfm = (fdc->command & 0x40) ? 1:0; - break; - case 0x03: /*Specify*/ - fdc->pnum = 0; - fdc->ptot = 2; - fdc->stat |= 0x90; - break; - case 0x04: /*Sense drive status*/ - fdc->pnum = 0; - fdc->ptot = 1; - fdc->stat |= 0x90; - break; - case 0x05: /*Write data*/ - case 0x09: /*Write deleted data*/ - fdc->satisfying_sectors = 0; - fdc->sc = 0; - fdc->wrong_am = 0; - fdc->deleted = ((fdc->command&0x1F) == 9) ? 1 : 0; - fdc->pnum = 0; - fdc->ptot = 8; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->mfm = (fdc->command & 0x40) ? 1 : 0; - break; - case 0x06: /*Read data*/ - case 0x0c: /*Read deleted data*/ - case 0x11: /*Scan equal*/ - case 0x19: /*Scan low or equal*/ - case 0x16: /*Verify*/ - case 0x1d: /*Scan high or equal*/ - fdc->satisfying_sectors = 0; - fdc->sc = 0; - fdc->wrong_am = 0; - fdc->deleted = ((fdc->command&0x1F) == 0xC) ? 1 : 0; - if ((fdc->command&0x1F) == 0x16) fdc->deleted = 2; - fdc->deleted |= (fdc->command & 0x20); - fdc->pnum = 0; - fdc->ptot = 8; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->mfm = (fdc->command&0x40)?1:0; - break; - case 0x07: /*Recalibrate*/ - fdc->pnum=0; - fdc->ptot=1; - fdc->stat |= 0x90; - break; - case 0x08: /*Sense interrupt status*/ - fdc_log("fdc->fintr = %i, fdc->reset_stat = %i\n", fdc->fintr, fdc->reset_stat); - fdc->lastdrive = fdc->drive; - fdc->pos = 0; - fdc_sis(fdc); - break; - case 0x0a: /*Read sector ID*/ - fdc->pnum = 0; - fdc->ptot = 1; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->mfm = (fdc->command & 0x40) ? 1 : 0; - break; - case 0x0d: /*Format track*/ - fdc->pnum = 0; - fdc->ptot = 5; - fdc->stat |= 0x90; - fdc->pos = 0; - fdc->mfm = (fdc->command & 0x40) ? 1:0; - fdc->format_state = 0; - break; - case 0x0e: /*Dump registers*/ - fdc->lastdrive = fdc->drive; - fdc->interrupt = 0x0e; - fdc->pos = 0; - fdc_callback(fdc); - break; - case 0x0f: /*Seek*/ - fdc->pnum = 0; - fdc->ptot = 2; - fdc->stat |= 0x90; - break; - case 0x18: /*NSC*/ - if (!(fdc->flags & FDC_FLAG_NSC)) { - fdc_bad_command(fdc); - break; - } - case 0x10: /*Get version*/ - case 0x14: /*Unlock*/ - case 0x94: /*Lock*/ - fdc->lastdrive = fdc->drive; - fdc->interrupt = fdc->command; - fdc->pos = 0; - fdc_callback(fdc); - break; - case 0x12: /*Set perpendicular mode*/ - if ((fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_PCJR)) { - fdc->pnum=0; - fdc->ptot=1; - fdc->stat |= 0x90; - fdc->pos=0; - } else - fdc_bad_command(fdc); - break; - case 0x13: /*Configure*/ - fdc->pnum=0; - fdc->ptot=3; - fdc->stat |= 0x90; - fdc->pos=0; - break; - default: - fdc_bad_command(fdc); - break; - } - } else { - fdc->stat = 0x10 | (fdc->stat & 0xf); - fdc->params[fdc->pnum++]=val; - if (fdc->pnum == 1) { - if (command_has_drivesel[fdc->command & 0x1F]) { - if (fdc->flags & FDC_FLAG_PCJR) - fdc->drive = 0; - else - fdc->drive = fdc->dor & 3; - fdc->rw_drive = fdc->params[0] & 3; - if (((fdc->command & 0x1F) == 7) || ((fdc->command & 0x1F) == 15)) - fdc->stat |= (1 << real_drive(fdc, fdc->drive)); - } - } - if (fdc->pnum==fdc->ptot) { - fdc_log("Got all params %02X\n", fdc->command); - fdc->interrupt = fdc->command & 0x1F; - timer_clock(); - fdc->time = 1024LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - fdc->reset_stat = 0; - switch (fdc->interrupt & 0x1F) { - case 2: /*Read a track*/ - fdc_io_command_phase1(fdc, 0); - fdc->read_track_sector.id.c = fdc->params[1]; - fdc->read_track_sector.id.h = fdc->params[2]; - fdc->read_track_sector.id.r = 1; - fdc->read_track_sector.id.n = fdc->params[4]; - if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - fdc_noidam(fdc); - return; - } - fdd_readsector(real_drive(fdc, fdc->drive), SECTOR_FIRST, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]); - break; - case 3: /*Specify*/ - fdc->stat=0x80; - fdc->specify[0] = fdc->params[0]; - fdc->specify[1] = fdc->params[1]; - fdc->dma = (fdc->specify[1] & 1) ^ 1; - fdc->time = 0LL; - break; - case 0x12: - fdc->stat=0x80; - if (fdc->params[0] & 0x80) - fdc->perp = fdc->params[0] & 0x3f; - else { - fdc->perp &= 0xfc; - fdc->perp |= (fdc->params[0] & 0x03); - } - fdc->time = 0LL; - return; - case 4: - fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); - break; - case 5: /*Write data*/ - case 9: /*Write deleted data*/ - fdc_io_command_phase1(fdc, 1); - if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - fdc_noidam(fdc); - return; - } - fdd_writesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]); - break; - case 0x11: /*Scan equal*/ - case 0x19: /*Scan low or equal*/ - case 0x1D: /*Scan high or equal*/ - fdc_io_command_phase1(fdc, 1); - if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - fdc_noidam(fdc); - return; - } - fdd_comparesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]); - break; - case 0x16: /*Verify*/ - if (fdc->params[0] & 0x80) - fdc->sc = fdc->params[7]; - case 6: /*Read data*/ - case 0xC: /*Read deleted data*/ - fdc_io_command_phase1(fdc, 0); - fdc_log("Reading sector (drive %i) (%i) (%i %i %i %i) (%i %i %i)\n", fdc->drive, fdc->params[0], fdc->params[1], fdc->params[2], fdc->params[3], fdc->params[4], fdc->params[5], fdc->params[6], fdc->params[7]); - if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - fdc_noidam(fdc); - return; - } - if (((dma_mode(2) & 0x0C) == 0x00) && !(fdc->flags & FDC_FLAG_PCJR) && fdc->dma) { - /* DMA is in verify mode, treat this like a VERIFY command. */ - fdc_log("Verify-mode read!\n"); - fdc->tc = 1; - fdc->deleted |= 2; - } - fdd_readsector(real_drive(fdc, fdc->drive), fdc->sector, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]); - break; - - case 7: /*Recalibrate*/ - fdc->stat = (1 << real_drive(fdc, fdc->drive)) | 0x80; - fdc->st0 = fdc->drive & 0x03; - fdc->st0 |= fdd_get_head(real_drive(fdc, fdc->drive)) ? 0x04 : 0x00; - fdc->st0 |= 0x80; - fdc->time = 0LL; - drive_num = real_drive(fdc, fdc->drive); - /* Three conditions under which the command should fail. */ - if (!fdd_get_flags(drive_num) || (drive_num >= FDD_NUM) || !motoron[drive_num] || fdd_track0(drive_num)) { - fdc_log("Failed recalibrate\n"); - if (!fdd_get_flags(drive_num) || (drive_num >= FDD_NUM) || !motoron[drive_num]) - fdc->st0 = 0x70 | (fdc->params[0] & 3); - else - fdc->st0 = 0x20 | (fdc->params[0] & 3); - fdc->pcn[fdc->params[0] & 3] = 0; - fdc->interrupt = -3; - timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - break; - } - if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en) - fdc_seek(fdc, fdc->drive, -fdc->max_track); - fdc_log("Recalibrating...\n"); - fdc->time = 5000LL * (1 << TIMER_SHIFT); - fdc->step = fdc->seek_dir = 1; - break; - case 0x0d: /*Format*/ - fdc_rate(fdc, fdc->drive); - fdc->head = (fdc->params[0] & 4) ? 1 : 0; - fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); - fdc->gap = fdc->params[3]; - fdc->dtl = 4000000; - fdc->format_sectors = fdc->params[2]; - fdc->format_n = fdc->params[1]; - fdc->format_state = 1; - fdc->pos = 0; - fdc->stat = 0x10; - break; - case 0xf: /*Seek*/ - fdc->stat = (1 << fdc->drive) | 0x80; - fdc->head = (fdc->params[0] & 4) ? 1 : 0; - fdc->st0 = fdc->drive & 0x03; - fdc->st0 |= (fdc->params[0] & 4); - fdc->st0 |= 0x80; - fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); - fdc->time = 0LL; - drive_num = real_drive(fdc, fdc->drive); - /* Three conditions under which the command should fail. */ - if (!fdd_get_flags(drive_num) || (drive_num >= FDD_NUM) || !motoron[drive_num]) { - /* Yes, failed SEEK's still report success, unlike failed RECALIBRATE's. */ - fdc->st0 = 0x20 | (fdc->params[0] & 7); - if (fdc->command & 0x80) { - if (fdc->command & 0x40) - fdc->pcn[fdc->params[0] & 3] += fdc->params[1]; - else - fdc->pcn[fdc->params[0] & 3] -= fdc->params[1]; - } else - fdc->pcn[fdc->params[0] & 3] = fdc->params[1]; - fdc->interrupt = -3; - timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - break; - } - if (fdc->command & 0x80) { - if (fdc->params[1]) { - if (fdc->command & 0x40) { - /* Relative seek inwards. */ - fdc->seek_dir = 0; - fdc_seek(fdc, fdc->drive, fdc->params[1]); - fdc->pcn[fdc->params[0] & 3] += fdc->params[1]; - } else { - /* Relative seek outwards. */ - fdc->seek_dir = 1; - fdc_seek(fdc, fdc->drive, -fdc->params[1]); - fdc->pcn[fdc->params[0] & 3] -= fdc->params[1]; - } - fdc->time = 5000LL * (1 << TIMER_SHIFT); - fdc->step = 1; - } else { - fdc->st0 = 0x20 | (fdc->params[0] & 7); - fdc->interrupt = -3; - timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - break; - } - } else { - fdc_log("Seeking to track %i (PCN = %i)...\n", fdc->params[1], fdc->pcn[fdc->params[0] & 3]); - if ((fdc->params[1] - fdc->pcn[fdc->params[0] & 3]) == 0) { - fdc_log("Failed seek\n"); - fdc->st0 = 0x20 | (fdc->params[0] & 7); - fdc->interrupt = -3; - timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - break; - } - if (fdc->params[1] > fdc->pcn[fdc->params[0] & 3]) - fdc->seek_dir = 0; - else - fdc->seek_dir = 1; - fdc_seek(fdc, fdc->drive, fdc->params[1] - fdc->pcn[fdc->params[0] & 3]); - fdc->pcn[fdc->params[0] & 3] = fdc->params[1]; - fdc->time = 5000LL * (1 << TIMER_SHIFT); - fdc->step = 1; - fdc_log("fdc->time = %i\n", fdc->time); - } - break; - case 10: /*Read sector ID*/ - fdc_rate(fdc, fdc->drive); - fdc->time = 0LL; - fdc->head = (fdc->params[0] & 4) ? 1 : 0; - fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); - if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en) { - fdd_readaddress(real_drive(fdc, fdc->drive), fdc->head, fdc->rate); - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0x70; - else - fdc->stat = 0x50; - } - else - fdc_noidam(fdc); - break; - } - } else - fdc->stat = 0x90 | (fdc->stat & 0xf); - } - return; - case 7: - if (!(fdc->flags & FDC_FLAG_AT)) - return; - fdc->rate = val & 0x03; - if (fdc->flags & FDC_FLAG_PS1) - fdc->noprec = !!(val & 0x04); - return; - } -} - - -uint8_t -fdc_read(uint16_t addr, void *priv) -{ - fdc_t *fdc = (fdc_t *) priv; - uint8_t ret; - int drive; - - cycles -= ISA_CYCLES(8); - - switch (addr&7) { - case 0: /* STA */ - if (fdc->flags & FDC_FLAG_PS1) { - drive = real_drive(fdc, fdc->dor & 3); - ret = 0x00; - /* TODO: - Bit 2: INDEX (best return always 0 as it goes by very fast) - Bit 6: DRQ - */ - if (writeprot[drive]) /* WRITEPROT */ - ret |= 0x01; - if (fdc->seek_dir) /* nDIRECTION */ - ret |= 0x02; - if (!fdd_get_head(drive)) /* nHDSEL */ - ret |= 0x08; - if (fdd_track0(drive)) /* TRK0 */ - ret |= 0x10; - if (fdc->step) /* STEP */ - ret |= 0x20; - if (fdc->fintr || fdc->reset_stat) /* INTR */ - ret |= 0x80; - } else - ret = 0xff; - break; - case 1: /* STB */ - if (fdc->flags & FDC_FLAG_PS1) { - drive = real_drive(fdc, fdc->dor & 3); - ret = 0x00; - /* -Drive 2 Installed */ - if (!fdd_get_type(1)) - ret |= 80; - /* -Drive Select 1,0 */ - if (drive) - ret |= 0x20; - else - ret |= 0x40; - } else { - if (is486) - return 0xff; - drive = real_drive(fdc, fdc->dor & 3); - if (!fdc->enable_3f1) - ret = 0xff; - - ret = 0x70; - if (drive) - ret &= ~0x40; - else - ret &= ~0x20; - - if (fdc->dor & 0x10) - ret |= 1; - if (fdc->dor & 0x20) - ret |= 2; - } - break; - case 2: - ret = fdc->dor; - break; - case 3: - drive = real_drive(fdc, fdc->dor & 3); - if (fdc->flags & FDC_FLAG_PS1) { - /* PS/1 Model 2121 seems return drive type in port - * 0x3f3, despite the 82077AA fdc_t not implementing - * this. This is presumably implemented outside the - * fdc_t on one of the motherboard's support chips. - * - * Confirmed: 00=1.44M 3.5 - * 10=2.88M 3.5 - * 20=1.2M 5.25 - * 30=1.2M 5.25 - * - * as reported by Configur.exe. - */ - if (fdd_is_525(drive)) - ret = 0x20; - else if (fdd_is_ed(drive)) - ret = 0x10; - else - ret = 0x00; - } else if (!fdc->enh_mode) - ret = 0x20; - else - ret = fdc->rwc[drive] << 4; - break; - case 4: /*Status*/ - ret = fdc->stat; - break; - case 5: /*Data*/ - if ((fdc->stat & 0xf0) == 0xf0) { - fdc->stat &= ~0x80; - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) { - fdc->data_ready = 0; - ret = fdc->dat; - } else - ret = fdc_fifo_buf_read(fdc); - break; - } - fdc->stat &= ~0x80; - if (fdc->paramstogo) { - fdc_log("%i parameters to go\n", fdc->paramstogo); - fdc->paramstogo--; - ret = fdc->res[10 - fdc->paramstogo]; - if (!fdc->paramstogo) - fdc->stat = 0x80; - else - fdc->stat |= 0xC0; - } else { - if (lastbyte) - fdc->stat = 0x80; - lastbyte = 0; - ret = fdc->dat; - fdc->data_ready = 0; - } - fdc->stat &= 0xf0; - break; - case 7: /*Disk change*/ - drive = real_drive(fdc, fdc->dor & 3); - - if (fdc->flags & FDC_FLAG_PS1) { - if (fdc->dor & (0x10 << drive)) { - ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x00 : 0x80; - ret |= (fdc->dor & 0x08); - ret |= (fdc->noprec << 2); - ret |= (fdc->rate & 0x03); - } else - ret = 0x00; - } else { - if (fdc->dor & (0x10 << drive)) - ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00; - else - ret = 0x00; - if (fdc->flags & FDC_FLAG_DISKCHG_ACTLOW) /*PC2086/3086 seem to reverse this bit*/ - ret ^= 0x80; - - ret |= 0x01; - } - - fdc->step = 0; - break; - default: - ret = 0xFF; - } - fdc_log("Read FDC %04X %02X\n", addr, ret); - return ret; -} - -static void -fdc_poll_common_finish(fdc_t *fdc, int compare, int st5) -{ - fdc_int(fdc); - if (!(fdc->flags & FDC_FLAG_PS1)) - fdc->fintr = 0; - fdc->stat = 0xD0; - fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; - fdc->res[5] = st5; - fdc->res[6] = 0; - if (fdc->wrong_am) { - fdc->res[6] |= 0x40; - fdc->wrong_am = 0; - } - if (compare == 1) { - if (!fdc->satisfying_sectors) - fdc->res[6] |= 4; - else if (fdc->satisfying_sectors == (fdc->params[5] << ((fdc->command & 80) ? 1 : 0))) - fdc->res[6] |= 8; - } else if (compare == 2) { - if (fdc->satisfying_sectors & 1) - fdc->res[5] |= 0x20; - if (fdc->satisfying_sectors & 2) { - fdc->res[5] |= 0x20; - fdc->res[6] |= 0x20; - } - if (fdc->satisfying_sectors & 4) - fdc->res[5] |= 0x04; - if (fdc->satisfying_sectors & 8) { - fdc->res[5] |= 0x04; - fdc->res[6] |= 0x02; - } - if (fdc->satisfying_sectors & 0x10) { - fdc->res[5] |= 0x04; - fdc->res[6] |= 0x10; - } - } - fdc->res[7]=fdc->rw_track; - fdc->res[8]=fdc->head; - fdc->res[9]=fdc->sector; - fdc->res[10]=fdc->params[4]; - fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n" , fdc->res[4], fdc->res[5], fdc->res[6], fdc->res[7], fdc->res[8], fdc->res[9], fdc->res[10]); - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 0); - fdc->paramstogo = 7; -} - - -static void -fdc_poll_readwrite_finish(fdc_t *fdc, int compare) -{ - fdc->inread = 0; - fdc->interrupt = -2; - - fdc_poll_common_finish(fdc, compare, 0); -} - - -static void -fdc_no_dma_end(fdc_t *fdc, int compare) -{ - fdc->time = 0LL; - - fdc_poll_common_finish(fdc, compare, 0x80); -} - - -static void -fdc_callback(void *priv) -{ - fdc_t *fdc = (fdc_t *) priv; - int compare = 0; - int drive_num = 0; - int old_sector = 0; - fdc->time = 0LL; - fdc_log("fdc_callback(): %i\n", fdc->interrupt); - switch (fdc->interrupt) { - case -3: /*End of command with interrupt*/ - fdc_int(fdc); - fdc->stat = (fdc->stat & 0xf) | 0x80; - return; - case -2: /*End of command*/ - fdc->stat = (fdc->stat & 0xf) | 0x80; - return; - case -1: /*Reset*/ - fdc_int(fdc); - fdc->fintr = 0; - memset(fdc->pcn, 0, 4 * sizeof(int)); - fdc->reset_stat = 4; - return; - case 1: /*Mode*/ - fdc->stat=0x80; - fdc->densel_force = (fdc->params[2] & 0xC0) >> 6; - return; - case 2: /*Read track*/ - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 1); - fdc->eot[fdc->drive]--; - fdc->read_track_sector.id.r++; - if (!fdc->eot[fdc->drive] || fdc->tc) { - fdc_poll_readwrite_finish(fdc, 2); - return; - } else { - fdd_readsector(real_drive(fdc, fdc->drive), SECTOR_NEXT, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0x70; - else - fdc->stat = 0x50; - } - fdc->inread = 1; - return; - case 4: /*Sense drive status*/ - fdc->res[10] = (fdc->params[0] & 7) | 0x20; - if (fdd_is_double_sided(real_drive(fdc, fdc->drive))) - fdc->res[10] |= 0x08; - if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en) { - if (fdd_track0(real_drive(fdc, fdc->drive))) - fdc->res[10] |= 0x10; - } - if (writeprot[fdc->drive]) - fdc->res[10] |= 0x40; - - fdc->stat = (fdc->stat & 0xf) | 0xd0; - fdc->paramstogo = 1; - fdc->interrupt = 0; - fdc->time = 0LL; - return; - case 5: /*Write data*/ - case 9: /*Write deleted data*/ - case 6: /*Read data*/ - case 0xC: /*Read deleted data*/ - case 0x11: /*Scan equal*/ - case 0x19: /*Scan low or equal*/ - case 0x1C: /*Verify*/ - case 0x1D: /*Scan high or equal*/ - if ((fdc->interrupt == 0x11) || (fdc->interrupt == 0x19) || (fdc->interrupt == 0x1D)) - compare = 1; - else - compare = 0; - if ((fdc->interrupt == 6) || (fdc->interrupt == 0xC)) { - if (fdc->wrong_am && !(fdc->deleted & 0x20)) { - /* Mismatching data address mark and no skip, set TC. */ - fdc->tc = 1; - } - } - old_sector = fdc->sector; - if (fdc->tc) { - /* This is needed so that the correct results are returned - in case of TC. */ - if (fdc->sector == fdc->params[5]) { - if (!(fdc->command & 0x80)) { - fdc->rw_track++; - fdc->sector = 1; - } else { - if (fdc->head) - fdc->rw_track++; - - fdc->head ^= 1; - fdd_set_head(real_drive(fdc, fdc->drive), fdc->head); - fdc->sector = 1; - } - } else - fdc->sector++; - fdc_poll_readwrite_finish(fdc, compare); - return; - } - if ((fdc->interrupt == 0x16) && (fdc->params[0] & 0x80)) { - /* VERIFY command, EC set */ - fdc->sc--; - if (!fdc->sc) { - fdc->sector++; - fdc_poll_readwrite_finish(fdc, 0); - return; - } - /* The rest is processed normally per MT flag and EOT. */ - } else if ((fdc->interrupt == 0x16) && !(fdc->params[0] & 0x80)) { - /* VERIFY command, EC clear */ - if ((fdc->sector == old_sector) && (fdc->head == (fdc->command & 0x80) ? 1 : 0)) { - fdc->sector++; - fdc_poll_readwrite_finish(fdc, 0); - return; - } - } - if (fdc->sector == fdc->params[5]) { - /* Reached end of track, MT bit is clear */ - if (!(fdc->command & 0x80)) { - fdc->rw_track++; - fdc->sector = 1; - if (!(fdc->flags & FDC_FLAG_PCJR) && fdc->dma && (old_sector == 255)) - fdc_no_dma_end(fdc, compare); - else - fdc_poll_readwrite_finish(fdc, compare); - return; - } - /* Reached end of track, MT bit is set, head is 1 */ - if (fdd_get_head(real_drive(fdc, fdc->drive)) == 1) { - fdc->rw_track++; - fdc->sector = 1; - fdc->head &= 0xFE; - fdd_set_head(real_drive(fdc, fdc->drive), 0); - if (!(fdc->flags & FDC_FLAG_PCJR) && fdc->dma && (old_sector == 255)) - fdc_no_dma_end(fdc, compare); - else - fdc_poll_readwrite_finish(fdc, compare); - return; - } - if ((fdd_get_head(real_drive(fdc, fdc->drive)) == 0)) { - fdc->sector = 1; - fdc->head |= 1; - fdd_set_head(real_drive(fdc, fdc->drive), 1); - if (!fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - fdc_noidam(fdc); - return; - } - } - } else if (fdc->sector < fdc->params[5]) - fdc->sector++; - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 1); - switch (fdc->interrupt) { - case 5: - case 9: - fdd_writesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0xb0; - else - fdc->stat = 0x90; - break; - case 6: - case 0xC: - case 0x16: - fdd_readsector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0x70; - else - fdc->stat = 0x50; - break; - case 0x11: - case 0x19: - case 0x1D: - fdd_comparesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) - fdc->stat = 0xb0; - else - fdc->stat = 0x90; - break; - } - fdc->inread = 1; - return; - case 7: /*Recalibrate*/ - fdc->pcn[fdc->params[0] & 3] = 0; - drive_num = real_drive(fdc, fdc->rw_drive); - fdc->st0 = 0x20 | (fdc->params[0] & 3); - if (!fdd_track0(drive_num)) - fdc->st0 |= 0x50; - fdc->interrupt = -3; - timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - fdc->stat = 0x80 | (1 << fdc->drive); - return; - case 0x0d: /*Format track*/ - if (fdc->format_state == 1) { - fdc->format_state = 2; - timer_clock(); - fdc->time = 128LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); - } else if (fdc->format_state == 2) { - fdd_format(real_drive(fdc, fdc->drive), fdc->head, fdc->rate, fdc->params[4]); - fdc->format_state = 3; - } else { - fdc->interrupt = -2; - fdc_int(fdc); - if (!(fdc->flags & FDC_FLAG_PS1)) - fdc->fintr = 0; - fdc->stat = 0xD0; - fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->drive; - fdc->res[5] = fdc->res[6] = 0; - fdc->res[7] = fdc->pcn[fdc->params[0] & 3]; - fdc->res[8] = fdd_get_head(real_drive(fdc, fdc->drive)); - fdc->res[9] = fdc->format_dat[fdc->pos - 2] + 1; - fdc->res[10] = fdc->params[4]; - fdc->paramstogo = 7; - fdc->format_state = 0; - return; - } - return; - case 0x0e: /*Dump registers*/ - fdc->stat = (fdc->stat & 0xf) | 0xd0; - fdc->res[1] = fdc->pcn[0]; - fdc->res[2] = fdc->pcn[1]; - fdc->res[3] = fdc->pcn[2]; - fdc->res[4] = fdc->pcn[3]; - fdc->res[5] = fdc->specify[0]; - fdc->res[6] = fdc->specify[1]; - fdc->res[7] = fdc->eot[fdc->drive]; - fdc->res[8] = (fdc->perp & 0x7f) | ((fdc->lock) ? 0x80 : 0); - fdc->res[9] = fdc->config; - fdc->res[10] = fdc->pretrk; - fdc->paramstogo = 10; - fdc->interrupt = 0; - fdc->time = 0LL; - return; - case 0x0f: /*Seek*/ - drive_num = real_drive(fdc, fdc->rw_drive); - fdc->st0 = 0x20 | (fdc->params[0] & 7); - fdc->interrupt = -3; - /* timer_clock(); - fdc->time = 2048LL * (1LL << TIMER_SHIFT); - timer_update_outstanding(); */ - fdc->stat = 0x80 | (1 << fdc->drive); - fdc_callback(fdc); - return; - case 0x10: /*Version*/ - case 0x18: /*NSC*/ - fdc->stat = (fdc->stat & 0xf) | 0xd0; - fdc->res[10] = (fdc->interrupt & 0x08) ? 0x73 : 0x90; - fdc->paramstogo = 1; - fdc->interrupt = 0; - fdc->time = 0LL; - return; - case 0x13: /*Configure*/ - fdc->config = fdc->params[1]; - fdc->pretrk = fdc->params[2]; - fdc->fifo = (fdc->params[1] & 0x20) ? 0 : 1; - fdc->tfifo = (fdc->params[1] & 0xF); - fdc->stat = 0x80; - fdc->time = 0LL; - return; - case 0x14: /*Unlock*/ - case 0x94: /*Lock*/ - fdc->lock = (fdc->interrupt & 0x80) ? 1 : 0; - fdc->stat = (fdc->stat & 0xf) | 0xd0; - fdc->res[10] = (fdc->interrupt & 0x80) ? 0x10 : 0x00; - fdc->paramstogo = 1; - fdc->interrupt = 0; - fdc->time = 0LL; - return; - case 0xfc: /*Invalid*/ - fdc->dat = fdc->st0 = 0x80; - fdc->stat = (fdc->stat & 0xf) | 0xd0; - fdc->res[10] = fdc->st0; - fdc->paramstogo = 1; - fdc->interrupt = 0; - fdc->time = 0LL; - return; - } -} - - -void -fdc_error(fdc_t *fdc, int st5, int st6) -{ - fdc->time = 0LL; - - fdc_int(fdc); - if (!(fdc->flags & FDC_FLAG_PS1)) - fdc->fintr = 0; - fdc->stat = 0xD0; - fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; - if (fdc->head && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - pclog("Head 1 on 1-sided drive\n"); - fdc->st0 |= 0x08; - } - fdc->res[5] = st5; - fdc->res[6] = st6; - fdc_log("FDC Error: %02X %02X %02X\n", fdc->res[4], fdc->res[5], fdc->res[6]); - switch(fdc->interrupt) { - case 0x02: - case 0x05: - case 0x06: - case 0x09: - case 0x0C: - case 0x11: - case 0x16: - case 0x19: - case 0x1D: - fdc->res[7]=fdc->rw_track; - fdc->res[8]=fdc->head; - fdc->res[9]=fdc->sector; - fdc->res[10]=fdc->params[4]; - break; - default: - fdc->res[7]=0; - fdc->res[8]=0; - fdc->res[9]=0; - fdc->res[10]=0; - break; - } - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 0); - fdc->paramstogo = 7; -} - - -void -fdc_overrun(fdc_t *fdc) -{ - fdd_stop(fdc->drive); - - fdc_error(fdc, 0x10, 0); -} - - -int -fdc_is_verify(fdc_t *fdc) -{ - return (fdc->deleted & 2) ? 1 : 0; -} - - -int -fdc_data(fdc_t *fdc, uint8_t data) -{ - int result = 0; - - if (fdc->deleted & 2) { - /* We're in a VERIFY command, so return with 0. */ - return 0; - } - - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) { - if (fdc->tc) - return 0; - - if (fdc->data_ready) { - fdc_overrun(fdc); - return -1; - } - - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo || (fdc->tfifo < 1)) { - fdc->dat = data; - fdc->data_ready = 1; - fdc->stat = 0xf0; - } else { - /* FIFO enabled */ - fdc_fifo_buf_write(fdc, data); - if (fdc->fifobufpos == 0) { - /* We have wrapped around, means FIFO is over */ - fdc->data_ready = 1; - fdc->stat = 0xf0; - } - } - } else { - result = dma_channel_write(fdc->dma_ch, data); - - if (fdc->tc) - return -1; - - if (result & DMA_OVER) { - fdc->data_ready = 1; - fdc->stat = 0xd0; - fdc->tc = 1; - return -1; - } - - if (!fdc->fifo || (fdc->tfifo < 1)) { - fdc->data_ready = 1; - fdc->stat = 0xd0; - } else { - fdc_fifo_buf_advance(fdc); - if (fdc->fifobufpos == 0) { - /* We have wrapped around, means FIFO is over */ - fdc->data_ready = 1; - fdc->stat = 0xd0; - } - } - } - - return 0; -} - - -void -fdc_finishread(fdc_t *fdc) -{ - fdc->inread = 0; -} - - -void -fdc_track_finishread(fdc_t *fdc, int condition) -{ - fdc->stat = 0x10; - fdc->satisfying_sectors |= condition; - fdc->inread = 0; - fdc_callback(fdc); -} - - -void -fdc_sector_finishcompare(fdc_t *fdc, int satisfying) -{ - fdc->stat = 0x10; - fdc->satisfying_sectors++; - fdc->inread = 0; - fdc_callback(fdc); -} - - -void -fdc_sector_finishread(fdc_t *fdc) -{ - fdc->stat = 0x10; - fdc->inread = 0; - fdc_callback(fdc); -} - - -/* There is no sector ID. */ -void -fdc_noidam(fdc_t *fdc) -{ - fdc_error(fdc, 1, 0); -} - - -/* Sector ID's are there, but there is no sector. */ -void fdc_nosector(fdc_t *fdc) -{ - fdc_error(fdc, 4, 0); -} - - -/* There is no sector data. */ -void fdc_nodataam(fdc_t *fdc) -{ - fdc_error(fdc, 1, 1); -} - - -/* Abnormal termination with both status 1 and 2 set to 0, used when abnormally - terminating the fdc_t FORMAT TRACK command. */ -void fdc_cannotformat(fdc_t *fdc) -{ - fdc_error(fdc, 0, 0); -} - - -void -fdc_datacrcerror(fdc_t *fdc) -{ - fdc_error(fdc, 0x20, 0x20); -} - - -void -fdc_headercrcerror(fdc_t *fdc) -{ - fdc_error(fdc, 0x20, 0); -} - - -void -fdc_wrongcylinder(fdc_t *fdc) -{ - fdc_error(fdc, 4, 0x10); -} - - -void -fdc_badcylinder(fdc_t *fdc) -{ - fdc_error(fdc, 4, 0x02); -} - - -void -fdc_writeprotect(fdc_t *fdc) -{ - fdc_error(fdc, 0x02, 0); -} - - -int fdc_getdata(fdc_t *fdc, int last) -{ - int data; - - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) { - if (fdc->written) { - fdc_overrun(fdc); - return -1; - } - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) { - data = fdc->dat; - - if (!last) - fdc->stat = 0xb0; - } else { - data = fdc_fifo_buf_read(fdc); - - if (!last && (fdc->fifobufpos == 0)) - fdc->stat = 0xb0; - } - } else { - data = dma_channel_read(fdc->dma_ch); - - if (!fdc->fifo) { - if (!last) - fdc->stat = 0x90; - } else { - fdc_fifo_buf_advance(fdc); - - if (!last && (fdc->fifobufpos == 0)) - fdc->stat = 0x90; - } - - if (data & DMA_OVER) - fdc->tc = 1; - } - - fdc->written = 0; - return data & 0xff; -} - - -void -fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2) -{ - fdc_int(fdc); - fdc->stat = 0xD0; - fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->drive; - fdc->res[5] = 0; - fdc->res[6] = 0; - fdc->res[7] = track; - fdc->res[8] = side; - fdc->res[9] = sector; - fdc->res[10] = size; - ui_sb_update_icon(SB_FLOPPY | fdc->drive, 0); - fdc->paramstogo = 7; -} - - -uint8_t -fdc_get_swwp(fdc_t *fdc) -{ - return fdc->swwp; -} - - -void -fdc_set_swwp(fdc_t *fdc, uint8_t swwp) -{ - fdc->swwp = swwp; -} - - -uint8_t -fdc_get_diswr(fdc_t *fdc) -{ - if (!fdc) - return 0; - - return fdc->disable_write; -} - - -void -fdc_set_diswr(fdc_t *fdc, uint8_t diswr) -{ - fdc->disable_write = diswr; -} - - -uint8_t -fdc_get_swap(fdc_t *fdc) -{ - return fdc->swap; -} - - -void -fdc_set_swap(fdc_t *fdc, uint8_t swap) -{ - fdc->swap = swap; -} - - -void -fdc_set_base(fdc_t *fdc, int base) -{ - int super_io = (fdc->flags & FDC_FLAG_SUPERIO); - - if (fdc->flags & FDC_FLAG_AT) { - io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - } else { - io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); - io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - } - fdc->base_address = base; - fdc_log("fdc_t Base address set%s (%04X)\n", super_io ? " for Super I/O" : "", fdc->base_address); -} - - -void -fdc_remove(fdc_t *fdc) -{ - int super_io = (fdc->flags & FDC_FLAG_SUPERIO); - - fdc_log("fdc_t Removed (%04X)\n", fdc->base_address); - if (fdc->flags & FDC_FLAG_AT) { - io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - } else { - io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc); - io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - } -} - - -void -fdc_reset(void *priv) -{ - int i = 0; - uint8_t default_rwc; - - fdc_t *fdc = (fdc_t *) priv; - - default_rwc = (fdc->flags & FDC_FLAG_START_RWC_1) ? 1 : 0; - - fdc->enable_3f1 = 1; - - fdc_update_is_nsc(fdc, 0); - fdc_update_enh_mode(fdc, 0); - if (fdc->flags & FDC_FLAG_PS1) - fdc_update_densel_polarity(fdc, 0); - else - fdc_update_densel_polarity(fdc, 1); - fdc_update_densel_force(fdc, 0); - fdc_update_rwc(fdc, 0, default_rwc); - fdc_update_rwc(fdc, 1, default_rwc); - fdc_update_rwc(fdc, 2, default_rwc); - fdc_update_rwc(fdc, 3, default_rwc); - fdc_update_drvrate(fdc, 0, 0); - fdc_update_drvrate(fdc, 1, 0); - fdc_update_drvrate(fdc, 2, 0); - fdc_update_drvrate(fdc, 3, 0); - fdc_update_drv2en(fdc, 1); - - fdc->fifo = 0; - fdc->tfifo = 1; - - if (fdc->flags & FDC_FLAG_PCJR) { - fdc->dma = 0; - fdc->specify[1] = 1; - } else { - fdc->dma = 1; - fdc->specify[1] = 0; - } - fdc->config = 0x20; - fdc->pretrk = 0; - - fdc->swwp = 0; - fdc->disable_write = 0; - - fdc_ctrl_reset(fdc); - - fdc->max_track = (fdc->flags & FDC_FLAG_MORE_TRACKS) ? 85 : 79; - - fdc_remove(fdc); - fdc_set_base(fdc, (fdc->flags & FDC_FLAG_PCJR) ? 0x00f0 : 0x03f0); - - current_drive = 0; - - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); -} - - -static void -fdc_close(void *priv) -{ - fdc_t *fdc = (fdc_t *) priv; - - fdc_reset(fdc); - - /* Stop timers. */ - fdc->watchdog_timer = 0; - fdc->watchdog_count = 0; - - fdc->time = 0; - - free(fdc); -} - - -static void * -fdc_init(const device_t *info) -{ - fdc_t *fdc = (fdc_t *) malloc(sizeof(fdc_t)); - memset(fdc, 0, sizeof(fdc_t)); - - fdc->flags = info->local; - fdc_reset(fdc); - - fdc->irq = 6; - - if (fdc->flags & FDC_FLAG_PCJR) - timer_add(fdc_watchdog_poll, &fdc->watchdog_timer, &fdc->watchdog_timer, fdc); - else - fdc->dma_ch = 2; - - fdc_log("FDC added: %04X (flags: %08X)\n", fdc->base_address, fdc->flags); - - timer_add(fdc_callback, &fdc->time, &fdc->time, fdc); - - d86f_set_fdc(fdc); - fdi_set_fdc(fdc); - fdd_set_fdc(fdc); - imd_set_fdc(fdc); - img_set_fdc(fdc); - - fdc_reset(fdc); - - return fdc; -} - - -void -fdc_3f1_enable(fdc_t *fdc, int enable) -{ - fdc->enable_3f1 = enable; -} - - -const device_t fdc_xt_device = { - "PC/XT Floppy Drive Controller", - 0, - 0, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_pcjr_device = { - "PCjr Floppy Drive Controller", - 0, - FDC_FLAG_PCJR, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_device = { - "PC/AT Floppy Drive Controller", - 0, - FDC_FLAG_AT, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_actlow_device = { - "PC/AT Floppy Drive Controller (Active low)", - 0, - FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_ps1_device = { - "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", - 0, - FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_smc_device = { - "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)", - 0, - FDC_FLAG_AT | FDC_FLAG_SUPERIO, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_winbond_device = { - "PC/AT Floppy Drive Controller (Winbond W83x77F)", - 0, - FDC_FLAG_AT | FDC_FLAG_SUPERIO | FDC_FLAG_START_RWC_1 | FDC_FLAG_MORE_TRACKS, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; - -const device_t fdc_at_nsc_device = { - "PC/AT Floppy Drive Controller (NSC PC8730x)", - 0, - FDC_FLAG_AT | FDC_FLAG_MORE_TRACKS | FDC_FLAG_NSC, - fdc_init, - fdc_close, - fdc_reset, - NULL, NULL, NULL -}; diff --git a/src - Cópia/floppy/fdc.h b/src - Cópia/floppy/fdc.h deleted file mode 100644 index dbc3fdd0a..000000000 --- a/src - Cópia/floppy/fdc.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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. - * - * Implementation of the NEC uPD-765 and compatible floppy disk - * controller. - * - * Version: @(#)fdc.h 1.0.4 2018/04/12 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_FDC_H -# define EMU_FDC_H - - -#define FDC_FLAG_PCJR 0x01 /* PCjr */ -#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ -#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ -#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ - - -typedef struct { - uint8_t dor, stat, command, dat, st0, swap; - uint8_t swwp, disable_write; - uint8_t params[256], res[256]; - uint8_t specify[256], format_dat[256]; - uint8_t config, pretrk; - uint8_t fifobuf[16]; - - uint16_t base_address; - - int head, sector, drive, lastdrive; - int pcn[4], eot[256]; - int rw_track, pos; - int pnum, ptot; - int rate, reset_stat; - int lock, perp; - int abort; - int format_state, format_n; - int tc, written; - int step, seek_dir; - int noprec; - - int data_ready, inread; - int bitcell_period, enh_mode; - int rwc[4], drvrate[4]; - int boot_drive, dma; - int densel_polarity, densel_force; - int fifo, tfifo; - int fifobufpos, drv2en; - - int gap, dtl; - int enable_3f1, format_sectors; - int max_track, mfm; - int deleted, wrong_am; - int sc, satisfying_sectors; - int fintr, rw_drive; - - int flags, interrupt; - - int irq; /* Should be 6 by default. */ - int dma_ch; /* Should be 2 by default. */ - - int bit_rate; /* Should be 250 at start. */ - int paramstogo; - - sector_id_t read_track_sector; - - int64_t time; - int64_t watchdog_timer, watchdog_count; -} fdc_t; - - -extern void fdc_remove(fdc_t *fdc); -extern void fdc_poll(fdc_t *fdc); -extern void fdc_abort(fdc_t *fdc); -extern void fdc_set_dskchg_activelow(fdc_t *fdc); -extern void fdc_3f1_enable(fdc_t *fdc, int enable); -extern int fdc_get_bit_rate(fdc_t *fdc); -extern int fdc_get_bitcell_period(fdc_t *fdc); - -/* A few functions to communicate between Super I/O chips and the FDC. */ -extern void fdc_update_enh_mode(fdc_t *fdc, int enh_mode); -extern int fdc_get_rwc(fdc_t *fdc, int drive); -extern void fdc_update_rwc(fdc_t *fdc, int drive, int rwc); -extern int fdc_get_boot_drive(fdc_t *fdc); -extern void fdc_update_boot_drive(fdc_t *fdc, int boot_drive); -extern void fdc_update_densel_polarity(fdc_t *fdc, int densel_polarity); -extern uint8_t fdc_get_densel_polarity(fdc_t *fdc); -extern void fdc_update_densel_force(fdc_t *fdc, int densel_force); -extern void fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate); -extern void fdc_update_drv2en(fdc_t *fdc, int drv2en); - -extern void fdc_noidam(fdc_t *fdc); -extern void fdc_nosector(fdc_t *fdc); -extern void fdc_nodataam(fdc_t *fdc); -extern void fdc_cannotformat(fdc_t *fdc); -extern void fdc_wrongcylinder(fdc_t *fdc); -extern void fdc_badcylinder(fdc_t *fdc); -extern void fdc_writeprotect(fdc_t *fdc); -extern void fdc_datacrcerror(fdc_t *fdc); -extern void fdc_headercrcerror(fdc_t *fdc); -extern void fdc_nosector(fdc_t *fdc); - -extern int real_drive(fdc_t *fdc, int drive); - -extern sector_id_t fdc_get_read_track_sector(fdc_t *fdc); -extern int fdc_get_compare_condition(fdc_t *fdc); -extern int fdc_is_deleted(fdc_t *fdc); -extern int fdc_is_sk(fdc_t *fdc); -extern void fdc_set_wrong_am(fdc_t *fdc); -extern int fdc_get_drive(fdc_t *fdc); -extern int fdc_get_perp(fdc_t *fdc); -extern int fdc_get_format_n(fdc_t *fdc); -extern int fdc_is_mfm(fdc_t *fdc); -extern double fdc_get_hut(fdc_t *fdc); -extern double fdc_get_hlt(fdc_t *fdc); -extern void fdc_request_next_sector_id(fdc_t *fdc); -extern void fdc_stop_id_request(fdc_t *fdc); -extern int fdc_get_gap(fdc_t *fdc); -extern int fdc_get_gap2(fdc_t *fdc, int drive); -extern int fdc_get_dtl(fdc_t *fdc); -extern int fdc_get_format_sectors(fdc_t *fdc); -extern uint8_t fdc_get_swwp(fdc_t *fdc); -extern void fdc_set_swwp(fdc_t *fdc, uint8_t swwp); -extern uint8_t fdc_get_diswr(fdc_t *fdc); -extern void fdc_set_diswr(fdc_t *fdc, uint8_t diswr); -extern uint8_t fdc_get_swap(fdc_t *fdc); -extern void fdc_set_swap(fdc_t *fdc, uint8_t swap); - -extern void fdc_finishcompare(fdc_t *fdc, int satisfying); -extern void fdc_finishread(fdc_t *fdc); -extern void fdc_sector_finishcompare(fdc_t *fdc, int satisfying); -extern void fdc_sector_finishread(fdc_t *fdc); -extern void fdc_track_finishread(fdc_t *fdc, int condition); -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 int fdc_getdata(fdc_t *fdc, int last); -extern int fdc_data(fdc_t *fdc, uint8_t data); - -extern void fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, - uint8_t sector, uint8_t size, uint8_t crc1, - uint8_t crc2); - -extern uint8_t fdc_read(uint16_t addr, void *priv); -extern void fdc_reset(void *priv); - -extern uint8_t fdc_ps1_525(void); - -#ifdef EMU_DEVICE_H -extern const device_t fdc_xt_device; -extern const device_t fdc_pcjr_device; -extern const device_t fdc_at_device; -extern const device_t fdc_at_actlow_device; -extern const device_t fdc_at_ps1_device; -extern const device_t fdc_at_smc_device; -extern const device_t fdc_at_winbond_device; -extern const device_t fdc_at_nsc_device; -#endif - - -#endif /*EMU_FDC_H*/ diff --git a/src - Cópia/floppy/fdd.c b/src - Cópia/floppy/fdd.c deleted file mode 100644 index 0508d5343..000000000 --- a/src - Cópia/floppy/fdd.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * 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. - * - * Implementation of the floppy drive emulation. - * - * Version: @(#)fdd.c 1.0.9 2018/05/13 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../rom.h" -#include "../config.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" -#include "fdd.h" -#include "fdd_86f.h" -#include "fdd_fdi.h" -#include "fdd_imd.h" -#include "fdd_img.h" -#include "fdd_json.h" -#include "fdd_td0.h" -#include "fdc.h" - - -extern int driveempty[4]; - -wchar_t floppyfns[4][512]; - -int64_t fdd_poll_time[FDD_NUM] = { 16LL, 16LL, 16LL, 16LL }; - -int fdd_cur_track[FDD_NUM]; -int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; - -DRIVE drives[FDD_NUM]; -int drive_type[FDD_NUM]; - -int curdrive = 0; - -int defaultwriteprot = 0; - -int fdc_ready; - -int drive_empty[FDD_NUM] = {1, 1, 1, 1}; -int fdd_changed[FDD_NUM]; - -int motorspin; -int64_t motoron[FDD_NUM]; - -int fdc_indexcount = 52; - -fdc_t *fdd_fdc; - -d86f_handler_t d86f_handler[FDD_NUM]; - -static const struct -{ - wchar_t *ext; - void (*load)(int drive, wchar_t *fn); - void (*close)(int drive); - int size; -} loaders[]= -{ - {L"001", img_load, img_close, -1}, - {L"002", img_load, img_close, -1}, - {L"003", img_load, img_close, -1}, - {L"004", img_load, img_close, -1}, - {L"005", img_load, img_close, -1}, - {L"006", img_load, img_close, -1}, - {L"007", img_load, img_close, -1}, - {L"008", img_load, img_close, -1}, - {L"009", img_load, img_close, -1}, - {L"010", img_load, img_close, -1}, - {L"12", img_load, img_close, -1}, - {L"144", img_load, img_close, -1}, - {L"360", img_load, img_close, -1}, - {L"720", img_load, img_close, -1}, - {L"86F", d86f_load, d86f_close, -1}, - {L"BIN", img_load, img_close, -1}, - {L"CQ", img_load, img_close, -1}, - {L"CQM", img_load, img_close, -1}, - {L"DDI", img_load, img_close, -1}, - {L"DSK", img_load, img_close, -1}, - {L"FDI", fdi_load, fdi_close, -1}, - {L"FDF", img_load, img_close, -1}, - {L"FLP", img_load, img_close, -1}, - {L"HDM", img_load, img_close, -1}, - {L"IMA", img_load, img_close, -1}, - {L"IMD", imd_load, imd_close, -1}, - {L"IMG", img_load, img_close, -1}, - {L"JSON", json_load, json_close, -1}, - {L"TD0", td0_load, td0_close, -1}, - {L"VFD", img_load, img_close, -1}, - {L"XDF", img_load, img_close, -1}, - {0,0,0} -}; - -static int driveloaders[4]; - - -typedef struct { - int type; - int track; - int densel; - int head; - int turbo; - int check_bpb; -} fdd_t; - - -fdd_t fdd[FDD_NUM]; -int ui_writeprot[FDD_NUM] = {0, 0, 0, 0}; - - -/* Flags: - Bit 0: 300 rpm supported; - Bit 1: 360 rpm supported; - Bit 2: size (0 = 3.5", 1 = 5.25"); - Bit 3: sides (0 = 1, 1 = 2); - Bit 4: double density supported; - Bit 5: high density supported; - Bit 6: extended density supported; - Bit 7: double step for 40-track media; - Bit 8: invert DENSEL polarity; - Bit 9: ignore DENSEL; - Bit 10: drive is a PS/2 drive; -*/ -#define FLAG_RPM_300 1 -#define FLAG_RPM_360 2 -#define FLAG_525 4 -#define FLAG_DS 8 -#define FLAG_HOLE0 16 -#define FLAG_HOLE1 32 -#define FLAG_HOLE2 64 -#define FLAG_DOUBLE_STEP 128 -#define FLAG_INVERT_DENSEL 256 -#define FLAG_IGNORE_DENSEL 512 -#define FLAG_PS2 1024 - -static const struct -{ - int max_track; - int flags; - char name[64]; - char internal_name[24]; -} drive_types[] = -{ - { /*None*/ - 0, 0, "None", "none" - }, - { /*5.25" 1DD*/ - 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd" - }, - { /*5.25" DD*/ - 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" - }, - { /*5.25" QD*/ - 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" - }, - { /*5.25" HD PS/2*/ - 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" - }, - { /*5.25" HD*/ - 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" - }, - { /*5.25" HD Dual RPM*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" - }, - { /*3.5" 1DD*/ - 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" - }, - { /*3.5" DD*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" - }, - { /*3.5" HD PS/2*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" - }, - { /*3.5" HD*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" - }, - { /*3.5" HD PC-98*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" - }, - { /*3.5" HD 3-Mode*/ - 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" - }, - { /*3.5" ED*/ - 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" - }, - { /*End of list*/ - -1, -1, "", "" - } -}; - -#ifdef ENABLE_FDD_LOG -int fdd_do_log = ENABLE_FDD_LOG; -#endif - - -static void -fdd_log(const char *fmt, ...) -{ -#ifdef ENABLE_FDD_LOG - va_list ap; - - if (fdd_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -char *fdd_getname(int type) -{ - return (char *)drive_types[type].name; -} - -char *fdd_get_internal_name(int type) -{ - return (char *)drive_types[type].internal_name; -} - -int fdd_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(drive_types[c].internal_name)) - { - if (!strcmp((char *)drive_types[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -/* This is needed for the dump as 86F feature. */ -void fdd_do_seek(int drive, int track) -{ - if (drives[drive].seek) { - drives[drive].seek(drive, track); - } -} - -void fdd_forced_seek(int drive, int track_diff) -{ - fdd[drive].track += track_diff; - - if (fdd[drive].track < 0) - fdd[drive].track = 0; - - if (fdd[drive].track > drive_types[fdd[drive].type].max_track) - fdd[drive].track = drive_types[fdd[drive].type].max_track; - - fdd_do_seek(drive, fdd[drive].track); -} - -void fdd_seek(int drive, int track_diff) -{ - if (!track_diff) - return; - - fdd[drive].track += track_diff; - - if (fdd[drive].track < 0) - fdd[drive].track = 0; - - if (fdd[drive].track > drive_types[fdd[drive].type].max_track) - fdd[drive].track = drive_types[fdd[drive].type].max_track; - - fdd_changed[drive] = 0; - - fdd_do_seek(drive, fdd[drive].track); -} - -int fdd_track0(int drive) -{ - /* If drive is disabled, TRK0 never gets set. */ - if (!drive_types[fdd[drive].type].max_track) return 0; - - return !fdd[drive].track; -} - -int fdd_current_track(int drive) -{ - return fdd[drive].track; -} - -void fdd_set_densel(int densel) -{ - int i = 0; - - for (i = 0; i < 4; i++) - { - if (drive_types[fdd[i].type].flags & FLAG_INVERT_DENSEL) - { - fdd[i].densel = densel ^ 1; - } - else - { - fdd[i].densel = densel; - } - } -} - -int fdd_getrpm(int drive) -{ - int hole = fdd_hole(drive); - - int densel = 0; - - densel = fdd[drive].densel; - - if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL) - { - densel ^= 1; - } - - if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360)) return 300; - if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_300)) return 360; - - if (drive_types[fdd[drive].type].flags & FLAG_525) - { - return densel ? 360 : 300; - } - else - { - /* fdd_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */ - if (hole == 1) - { - return densel ? 300 : 360; - } - else - { - return 300; - } - } -} - -int fdd_can_read_medium(int drive) -{ - int hole = fdd_hole(drive); - - hole = 1 << (hole + 4); - - return (drive_types[fdd[drive].type].flags & hole) ? 1 : 0; -} - -int fdd_doublestep_40(int drive) -{ - return (drive_types[fdd[drive].type].flags & FLAG_DOUBLE_STEP) ? 1 : 0; -} - -void fdd_set_type(int drive, int type) -{ - int old_type = fdd[drive].type; - fdd[drive].type = type; - if ((drive_types[old_type].flags ^ drive_types[type].flags) & FLAG_INVERT_DENSEL) - { - fdd[drive].densel ^= 1; - } -} - -int fdd_get_type(int drive) -{ - return fdd[drive].type; -} - -int fdd_get_flags(int drive) -{ - return drive_types[fdd[drive].type].flags; -} - -int fdd_is_525(int drive) -{ - return drive_types[fdd[drive].type].flags & FLAG_525; -} - -int fdd_is_dd(int drive) -{ - return (drive_types[fdd[drive].type].flags & 0x70) == 0x10; -} - -int fdd_is_ed(int drive) -{ - return drive_types[fdd[drive].type].flags & FLAG_HOLE2; -} - -int fdd_is_double_sided(int drive) -{ - return drive_types[fdd[drive].type].flags & FLAG_DS; -} - -void fdd_set_head(int drive, int head) -{ - if (head && !fdd_is_double_sided(drive)) - fdd[drive].head = 0; - else - fdd[drive].head = head; -} - -int fdd_get_head(int drive) -{ - if (!fdd_is_double_sided(drive)) - return 0; - return fdd[drive].head; -} - -void fdd_set_turbo(int drive, int turbo) -{ - fdd[drive].turbo = turbo; -} - -int fdd_get_turbo(int drive) -{ - return fdd[drive].turbo; -} - -void fdd_set_check_bpb(int drive, int check_bpb) -{ - fdd[drive].check_bpb = check_bpb; -} - -int fdd_get_check_bpb(int drive) -{ - return fdd[drive].check_bpb; -} - -int fdd_get_densel(int drive) -{ - if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL) - { - return fdd[drive].densel ^ 1; - } - else - { - return fdd[drive].densel; - } -} - -void fdd_load(int drive, wchar_t *fn) -{ - int c = 0, size; - wchar_t *p; - FILE *f; - - fdd_log("FDD: loading drive %d with '%ls'\n", drive, fn); - - if (!fn) return; - p = plat_get_extension(fn); - if (!p) return; - f = plat_fopen(fn, L"rb"); - if (!f) return; - fseek(f, -1, SEEK_END); - size = ftell(f) + 1; - fclose(f); - while (loaders[c].ext) - { - if (!wcscasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) - { - driveloaders[drive] = c; - memcpy(floppyfns[drive], fn, (wcslen(fn) << 1) + 2); - d86f_setup(drive); - loaders[c].load(drive, floppyfns[drive]); - drive_empty[drive] = 0; - fdd_forced_seek(drive, 0); - fdd_changed[drive] = 1; - return; - } - c++; - } - fdd_log("FDD: could not load '%ls' %s\n",fn,p); - drive_empty[drive] = 1; - fdd_set_head(drive, 0); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - ui_sb_update_icon_state(drive, 1); -} - -void fdd_close(int drive) -{ - fdd_log("FDD: closing drive %d\n", drive); - - if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive); - drive_empty[drive] = 1; - fdd_set_head(drive, 0); - floppyfns[drive][0] = 0; - drives[drive].hole = NULL; - drives[drive].poll = NULL; - drives[drive].seek = NULL; - drives[drive].readsector = NULL; - drives[drive].writesector = NULL; - drives[drive].comparesector = NULL; - drives[drive].readaddress = NULL; - drives[drive].format = NULL; - drives[drive].byteperiod = NULL; - drives[drive].stop = NULL; - d86f_destroy(drive); - ui_sb_update_icon_state(drive, 1); -} - -int fdd_notfound = 0; -static int fdd_period = 32; - -int fdd_hole(int drive) -{ - if (drives[drive].hole) - { - return drives[drive].hole(drive); - } - else - { - return 0; - } -} - -double fdd_byteperiod(int drive) -{ - if (drives[drive].byteperiod) - { - return drives[drive].byteperiod(drive); - } - else - { - return 32.0; - } -} - -double fdd_real_period(int drive) -{ - double ddbp; - double dusec; - - ddbp = fdd_byteperiod(drive); - - dusec = (double) TIMER_USEC; - - /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ - if (fdd_get_turbo(drive)) - { - return (32.0 * dusec); - } - - return (ddbp * dusec); -} - -void fdd_poll(int drive) -{ - if (drive >= FDD_NUM) - { - fatal("Attempting to poll floppy drive %i that is not supposed to be there\n", drive); - } - - fdd_poll_time[drive] += (int64_t) fdd_real_period(drive); - - if (drives[drive].poll) - drives[drive].poll(drive); - - if (fdd_notfound) - { - fdd_notfound--; - if (!fdd_notfound) - fdc_noidam(fdd_fdc); - } -} - -void fdd_poll_0(void *priv) -{ - fdd_poll(0); -} - -void fdd_poll_1(void *priv) -{ - fdd_poll(1); -} - -void fdd_poll_2(void *priv) -{ - fdd_poll(2); -} - -void fdd_poll_3(void *priv) -{ - fdd_poll(3); -} - -int fdd_get_bitcell_period(int rate) -{ - int bit_rate = 250; - - switch (rate) - { - case 0: /*High density*/ - bit_rate = 500; - break; - case 1: /*Double density (360 rpm)*/ - bit_rate = 300; - break; - case 2: /*Double density*/ - bit_rate = 250; - break; - case 3: /*Extended density*/ - bit_rate = 1000; - break; - } - - return 1000000 / bit_rate*2; /*Bitcell period in ns*/ -} - - -void fdd_set_rate(int drive, int drvden, int rate) -{ - switch (rate) - { - case 0: /*High density*/ - fdd_period = 16; - break; - case 1: - switch(drvden) - { - case 0: /*Double density (360 rpm)*/ - fdd_period = 26; - break; - case 1: /*High density (360 rpm)*/ - fdd_period = 16; - break; - case 2: - fdd_period = 4; - break; - } - case 2: /*Double density*/ - fdd_period = 32; - break; - case 3: /*Extended density*/ - fdd_period = 8; - break; - } -} - -void fdd_reset() -{ - curdrive = 0; - fdd_period = 32; - timer_add(fdd_poll_0, &(fdd_poll_time[0]), &(motoron[0]), NULL); - timer_add(fdd_poll_1, &(fdd_poll_time[1]), &(motoron[1]), NULL); - timer_add(fdd_poll_2, &(fdd_poll_time[2]), &(motoron[2]), NULL); - timer_add(fdd_poll_3, &(fdd_poll_time[3]), &(motoron[3]), NULL); -} - -int oldtrack[FDD_NUM] = {0, 0, 0, 0}; - -void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size) -{ - if (drives[drive].readsector) - drives[drive].readsector(drive, sector, track, side, density, sector_size); - else - fdd_notfound = 1000; -} - -void fdd_writesector(int drive, int sector, int track, int side, int density, int sector_size) -{ - if (drives[drive].writesector) - drives[drive].writesector(drive, sector, track, side, density, sector_size); - else - fdd_notfound = 1000; -} - -void fdd_comparesector(int drive, int sector, int track, int side, int density, int sector_size) -{ - if (drives[drive].comparesector) - drives[drive].comparesector(drive, sector, track, side, density, sector_size); - else - fdd_notfound = 1000; -} - -void fdd_readaddress(int drive, int side, int density) -{ - if (drives[drive].readaddress) - drives[drive].readaddress(drive, side, density); -} - -void fdd_format(int drive, int side, int density, uint8_t fill) -{ - if (drives[drive].format) - drives[drive].format(drive, side, density, fill); - else - fdd_notfound = 1000; -} - -void fdd_stop(int drive) -{ - if (drives[drive].stop) - drives[drive].stop(drive); -} - -void fdd_set_fdc(void *fdc) -{ - fdd_fdc = (fdc_t *) fdc; -} - -void fdd_init(void) -{ - drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0; - drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0; - drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0; - fdd_reset(); - - img_init(); - d86f_init(); - td0_init(); - imd_init(); - json_init(); - - fdd_load(0, floppyfns[0]); - fdd_load(1, floppyfns[1]); - fdd_load(2, floppyfns[2]); - fdd_load(3, floppyfns[3]); -} diff --git a/src - Cópia/floppy/fdd.h b/src - Cópia/floppy/fdd.h deleted file mode 100644 index 70414804f..000000000 --- a/src - Cópia/floppy/fdd.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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 floppy drive emulation. - * - * Version: @(#)fdd.h 1.0.4 2018/04/12 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_FDD_H -# define EMU_FDD_H - - -#define FDD_NUM 4 -#define SEEK_RECALIBRATE -999 - - -#ifdef __cplusplus -extern "C" { -#endif - -extern int fdd_swap; - - -extern void fdd_do_seek(int drive, int track); -extern void fdd_forced_seek(int drive, int track_diff); -extern void fdd_seek(int drive, int track_diff); -extern int fdd_track0(int drive); -extern int fdd_getrpm(int drive); -extern void fdd_set_densel(int densel); -extern int fdd_can_read_medium(int drive); -extern int fdd_doublestep_40(int drive); -extern int fdd_is_525(int drive); -extern int fdd_is_dd(int drive); -extern int fdd_is_ed(int drive); -extern int fdd_is_double_sided(int drive); -extern void fdd_set_head(int drive, int head); -extern int fdd_get_head(int drive); -extern void fdd_set_turbo(int drive, int turbo); -extern int fdd_get_turbo(int drive); -extern void fdd_set_check_bpb(int drive, int check_bpb); -extern int fdd_get_check_bpb(int drive); - -extern void fdd_set_type(int drive, int type); -extern int fdd_get_type(int drive); - -extern int fdd_get_flags(int drive); -extern int fdd_get_densel(int drive); - -extern char *fdd_getname(int type); - -extern char *fdd_get_internal_name(int type); -extern int fdd_get_from_internal_name(char *s); - -extern int fdd_current_track(int drive); - - -typedef struct { - void (*seek)(int drive, int track); - void (*readsector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*writesector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*comparesector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*readaddress)(int drive, int side, int density); - void (*format)(int drive, int side, int density, uint8_t fill); - int (*hole)(int drive); - double (*byteperiod)(int drive); - void (*stop)(int drive); - void (*poll)(int drive); -} DRIVE; - - -extern DRIVE drives[FDD_NUM]; -extern wchar_t floppyfns[FDD_NUM][512]; -extern int driveempty[FDD_NUM]; -extern int64_t fdd_poll_time[FDD_NUM]; -extern int ui_writeprot[FDD_NUM]; - -extern int curdrive; - -extern int fdd_time; -extern int64_t floppytime; - - -extern void fdd_load(int drive, wchar_t *fn); -extern void fdd_new(int drive, char *fn); -extern void fdd_close(int drive); -extern void fdd_init(void); -extern void fdd_reset(void); -extern void fdd_poll(int drive); -extern void fdd_poll_0(void* priv); -extern void fdd_poll_1(void* priv); -extern void fdd_poll_2(void* priv); -extern void fdd_poll_3(void* priv); -extern void fdd_seek(int drive, int track); -extern void fdd_readsector(int drive, int sector, int track, - int side, int density, int sector_size); -extern void fdd_writesector(int drive, int sector, int track, - int side, int density, int sector_size); -extern void fdd_comparesector(int drive, int sector, int track, - int side, int density, int sector_size); -extern void fdd_readaddress(int drive, int side, int density); -extern void fdd_format(int drive, int side, int density, uint8_t fill); -extern int fdd_hole(int drive); -extern double fdd_byteperiod(int drive); -extern void fdd_stop(int drive); -extern void fdd_set_rate(int drive, int drvden, int rate); - -extern int motorspin; -extern int64_t motoron[FDD_NUM]; - -extern int swwp; -extern int disable_write; - -extern int defaultwriteprot; - -extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; -extern int fdd_cur_track[FDD_NUM]; -extern int fdd_changed[FDD_NUM]; -extern int drive_empty[FDD_NUM]; -extern int drive_type[FDD_NUM]; - -/*Used in the Read A Track command. Only valid for fdd_readsector(). */ -#define SECTOR_FIRST -2 -#define SECTOR_NEXT -1 - -typedef union { - uint16_t word; - uint8_t bytes[2]; -} crc_t; - -void fdd_calccrc(uint8_t byte, crc_t *crc_var); - -typedef struct { - uint16_t (*disk_flags)(int drive); - uint16_t (*side_flags)(int drive); - void (*writeback)(int drive); - void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, - uint8_t r, uint8_t n); - uint8_t (*read_data)(int drive, int side, uint16_t pos); - void (*write_data)(int drive, int side, uint16_t pos, - uint8_t data); - int (*format_conditions)(int drive); - int32_t (*extra_bit_cells)(int drive, int side); - uint16_t* (*encoded_data)(int drive, int side); - void (*read_revolution)(int drive); - uint32_t (*index_hole_pos)(int drive, int side); - uint32_t (*get_raw_size)(int drive, int side); - - uint8_t check_crc; -} d86f_handler_t; - -extern const int gap3_sizes[5][8][48]; -extern d86f_handler_t d86f_handler[FDD_NUM]; - -extern void d86f_setup(int drive); -extern void d86f_destroy(int drive); -extern int d86f_export(int drive, wchar_t *fn); -extern void d86f_unregister(int drive); -extern void d86f_common_handlers(int drive); -extern void d86f_set_version(int drive, uint16_t version); -extern int d86f_is_40_track(int drive); -extern void d86f_reset_index_hole_pos(int drive, int side); -extern uint16_t d86f_prepare_pretrack(int drive, int side, int iso); -extern uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, - uint8_t *id_buf, uint8_t *data_buf, - int data_len, int gap2, int gap3, - int deleted, int bad_crc); -extern void d86f_set_track_pos(int drive, uint32_t track_pos); -extern void d86f_set_cur_track(int drive, int track); -extern void d86f_zero_track(int drive); -extern void d86f_initialize_last_sector_id(int drive, int c, int h, - int r, int n); -extern void d86f_initialize_linked_lists(int drive); -extern void d86f_destroy_linked_lists(int drive, int side); -extern uint16_t *common_encoded_data(int drive, int side); -extern void common_read_revolution(int drive); -extern uint32_t common_get_raw_size(int drive, int side); -extern void null_writeback(int drive); -extern void null_write_data(int drive, int side, uint16_t pos, - uint8_t data); -extern int null_format_conditions(int drive); -extern int32_t null_extra_bit_cells(int drive, int side); -extern void null_set_sector(int drive, int side, uint8_t c, uint8_t h, - uint8_t r, uint8_t n); -extern uint32_t null_index_hole_pos(int drive, int side); - -extern const uint8_t dmf_r[21]; -extern const uint8_t xdf_physical_sectors[2][2]; -extern const uint8_t xdf_gap3_sizes[2][2]; -extern const uint16_t xdf_trackx_spos[2][8]; - -typedef struct { - uint8_t h; - uint8_t r; -} xdf_id_t; - -typedef union { - uint16_t word; - xdf_id_t id; -} xdf_sector_t; - -extern const xdf_sector_t xdf_img_layout[2][2][46]; -extern const xdf_sector_t xdf_disk_layout[2][2][38]; - - -typedef struct { - uint8_t c; - uint8_t h; - uint8_t r; - uint8_t n; -} sector_id_fields_t; - -typedef union { - uint32_t dword; - uint8_t byte_array[4]; - sector_id_fields_t id; -} sector_id_t; - - -void d86f_set_fdc(void *fdc); -void fdi_set_fdc(void *fdc); -void fdd_set_fdc(void *fdc); -void imd_set_fdc(void *fdc); -void img_set_fdc(void *fdc); - - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_FDD_H*/ diff --git a/src - Cópia/floppy/fdd_86f.c b/src - Cópia/floppy/fdd_86f.c deleted file mode 100644 index 8f822a3f7..000000000 --- a/src - Cópia/floppy/fdd_86f.c +++ /dev/null @@ -1,3884 +0,0 @@ -/* - * 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. - * - * Implementation of the 86F floppy image format (stores the - * data in the form of FM/MFM-encoded transitions) which also - * forms the core of the emulator's floppy disk emulation. - * - * Version: @(#)fdd_86f.c 1.0.9 2018/05/06 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../device.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" -#ifdef D86F_COMPRESS -#include "lzf/lzf.h" -#endif - - -/* - * Let's give this some more logic: - * - * Bits 4,3 = Read/write (0 = read, 1 = write, 2 = scan, 3 = verify) - * Bits 6,5 = Sector/track (0 = ID, 1 = sector, 2 = deleted sector, 3 = track) - * Bit 7 = State type (0 = idle states, 1 = active states) - */ -enum { - /* 0 ?? ?? ??? */ - STATE_IDLE = 0x00, - STATE_SECTOR_NOT_FOUND, - - /* 1 00 00 ??? */ - STATE_0A_FIND_ID = 0x80, /* READ SECTOR ID */ - STATE_0A_READ_ID, - - /* 1 01 00 ??? */ - STATE_06_FIND_ID = 0xA0, /* READ DATA */ - STATE_06_READ_ID, - STATE_06_FIND_DATA, - STATE_06_READ_DATA, - - /* 1 01 01 ??? */ - STATE_05_FIND_ID = 0xA8, /* WRITE DATA */ - STATE_05_READ_ID, - STATE_05_FIND_DATA, - STATE_05_WRITE_DATA, - - /* 1 01 10 ??? */ - STATE_11_FIND_ID = 0xB0, /* SCAN EQUAL,SCAN LOW/EQUAL,SCAN HIGH/EQUAL */ - STATE_11_READ_ID, - STATE_11_FIND_DATA, - STATE_11_SCAN_DATA, - - /* 1 01 11 ??? */ - STATE_16_FIND_ID = 0xB8, /* VERIFY */ - STATE_16_READ_ID, - STATE_16_FIND_DATA, - STATE_16_VERIFY_DATA, - - /* 1 10 00 ??? */ - STATE_0C_FIND_ID = 0xC0, /* READ DELETED DATA */ - STATE_0C_READ_ID, - STATE_0C_FIND_DATA, - STATE_0C_READ_DATA, - - /* 1 10 01 ??? */ - STATE_09_FIND_ID = 0xC8, /* WRITE DELETED DATA */ - STATE_09_READ_ID, - STATE_09_FIND_DATA, - STATE_09_WRITE_DATA, - - /* 1 11 00 ??? */ - STATE_02_SPIN_TO_INDEX = 0xE0, /* READ TRACK */ - STATE_02_FIND_ID, - STATE_02_READ_ID, - STATE_02_FIND_DATA, - STATE_02_READ_DATA, - - /* 1 11 01 ??? */ - STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */ - STATE_0D_FORMAT_TRACK, - - /* 1 11 11 ??? */ - STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */ - STATE_0D_NOP_FORMAT_TRACK -}; - -enum { - FMT_PRETRK_GAP0, - FMT_PRETRK_SYNC, - FMT_PRETRK_IAM, - FMT_PRETRK_GAP1, - - FMT_SECTOR_ID_SYNC, - FMT_SECTOR_IDAM, - FMT_SECTOR_ID, - FMT_SECTOR_ID_CRC, - FMT_SECTOR_GAP2, - FMT_SECTOR_DATA_SYNC, - FMT_SECTOR_DATAAM, - FMT_SECTOR_DATA, - FMT_SECTOR_DATA_CRC, - FMT_SECTOR_GAP3, - - FMT_POSTTRK_CHECK, - FMT_POSTTRK_GAP4 -}; - - -typedef struct { - uint8_t buffer[10]; - uint32_t pos; - uint32_t len; -} sliding_buffer_t; - -typedef struct { - uint32_t sync_marks; - uint32_t bits_obtained; - uint32_t bytes_obtained; - uint32_t sync_pos; -} find_t; - -typedef struct { - unsigned nibble0 :4; - unsigned nibble1 :4; -} split_byte_t; - -typedef union { - uint8_t byte; - split_byte_t nibbles; -} decoded_t; - -typedef struct { - uint8_t c, h, r, n; - void *prev; -} sector_t; - -/* Disk flags: - * Bit 0 Has surface data (1 = yes, 0 = no) - * Bits 2, 1 Hole (3 = ED + 2000 kbps, 2 = ED, 1 = HD, 0 = DD) - * Bit 3 Sides (1 = 2 sides, 0 = 1 side) - * Bit 4 Write protect (1 = yes, 0 = no) - * Bits 6, 5 RPM slowdown (3 = 2%, 2 = 1.5%, 1 = 1%, 0 = 0%) - * Bit 7 Bitcell mode (1 = Extra bitcells count specified after - * disk flags, 0 = No extra bitcells) - * The maximum number of extra bitcells is 1024 (which - * after decoding translates to 64 bytes) - * Bit 8 Disk type (1 = Zoned, 0 = Fixed RPM) - * Bits 10, 9 Zone type (3 = Commodore 64 zoned, 2 = Apple zoned, - * 1 = Pre-Apple zoned #2, 0 = Pre-Apple zoned #1) - * Bit 11 Data and surface bits are stored in reverse byte endianness - */ -typedef struct { - FILE *f; - uint16_t version; - uint16_t disk_flags; - int32_t extra_bit_cells[2]; - uint16_t track_encoded_data[2][53048]; - uint16_t *track_surface_data[2]; - uint16_t thin_track_encoded_data[2][2][53048]; - uint16_t *thin_track_surface_data[2][2]; - uint16_t side_flags[2]; - uint32_t index_hole_pos[2]; - uint32_t track_offset[512]; - uint32_t file_size; - sector_id_t format_sector_id; - sector_id_t last_sector; - sector_id_t req_sector; - uint32_t index_count; - uint8_t state; - uint8_t fill; - uint32_t track_pos; - uint32_t datac; - uint32_t id_pos; - uint16_t last_word[2]; - find_t id_find; - find_t data_find; - crc_t calc_crc; - crc_t track_crc; - uint8_t sector_count; - uint8_t format_state; - uint16_t satisfying_bytes; - uint16_t preceding_bit[2]; - uint16_t current_byte[2]; - uint16_t current_bit[2]; - int cur_track; - uint32_t error_condition; -#ifdef D86F_COMPRESS - int is_compressed; -#endif - int id_found; - wchar_t original_file_name[2048]; - uint8_t *filebuf; - uint8_t *outbuf; - uint32_t dma_over; - int turbo_pos; - sector_t *last_side_sector[2]; -} d86f_t; - - -#ifdef ENABLE_D86F_LOG -int d86f_do_log = ENABLE_D86F_LOG; -#endif - - -static const uint8_t encoded_fm[64] = { - 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, - 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, - 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, - 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, - 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, - 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, - 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, - 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff -}; -static const uint8_t encoded_mfm[64] = { - 0xaa, 0xa9, 0xa4, 0xa5, 0x92, 0x91, 0x94, 0x95, - 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, - 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0xaa, 0xa9, 0xa4, 0xa5, 0x92, 0x91, 0x94, 0x95, - 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, - 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55 -}; - -static d86f_t *d86f[FDD_NUM]; -static uint16_t CRCTable[256]; -static fdc_t *d86f_fdc; -uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */ -uint64_t table[256]; - - -uint16_t d86f_side_flags(int drive); -int d86f_is_mfm(int drive); -void d86f_writeback(int drive); -uint8_t d86f_poll_read_data(int drive, int side, uint16_t pos); -void d86f_poll_write_data(int drive, int side, uint16_t pos, uint8_t data); -int d86f_format_conditions(int drive); - - -static void -d86f_log(const char *format, ...) -{ -#ifdef ENABLE_D86F_LOG - va_list ap; - - if (d86f_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static void -setup_crc(uint16_t poly) -{ - int c = 256, bc; - uint16_t temp; - - while(c--) { - temp = c << 8; - bc = 8; - - while (bc--) { - if (temp & 0x8000) - temp = (temp << 1) ^ poly; - else - temp <<= 1; - - CRCTable[c] = temp; - } - } -} - - -void -d86f_destroy_linked_lists(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - sector_t *s, *t; - - if (dev == NULL) return; - - if (dev->last_side_sector[side]) { - s = dev->last_side_sector[side]; - while (s) { - t = s->prev; - free(s); - s = NULL; - if (! t) - break; - s = t; - } - dev->last_side_sector[side] = NULL; - } -} - - -static int -d86f_has_surface_desc(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 1); -} - - -int -d86f_get_sides(int drive) -{ - return ((d86f_handler[drive].disk_flags(drive) >> 3) & 1) + 1; -} - - -int -d86f_get_rpm_mode(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 0x60) >> 5; -} - -int -d86f_reverse_bytes(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 0x800) >> 11; -} - - -uint16_t -d86f_disk_flags(int drive) -{ - d86f_t *dev = d86f[drive]; - - return dev->disk_flags; -} - - -uint32_t -d86f_index_hole_pos(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - return dev->index_hole_pos[side]; -} - - -uint32_t -null_index_hole_pos(int drive, int side) -{ - return 0; -} - - -uint16_t -null_disk_flags(int drive) -{ - return 0x09; -} - - -uint16_t -null_side_flags(int drive) -{ - return 0x0A; -} - - -void -null_writeback(int drive) -{ - return; -} - - -void -null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - return; -} - - -void -null_write_data(int drive, int side, uint16_t pos, uint8_t data) -{ - return; -} - - -int -null_format_conditions(int drive) -{ - return 0; -} - - -int32_t -d86f_extra_bit_cells(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - return dev->extra_bit_cells[side]; -} - - -int32_t -null_extra_bit_cells(int drive, int side) -{ - return 0; -} - - -uint16_t* -common_encoded_data(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - return dev->track_encoded_data[side]; -} - - -void -common_read_revolution(int drive) -{ - return; -} - - -uint16_t -d86f_side_flags(int drive) -{ - d86f_t *dev = d86f[drive]; - int side; - - side = fdd_get_head(drive); - - return dev->side_flags[side]; -} - - -uint16_t -d86f_track_flags(int drive) -{ - uint16_t dr, rr, tf; - - tf = d86f_handler[drive].side_flags(drive); - rr = tf & 0x67; - dr = fdd_get_flags(drive) & 7; - tf &= ~0x67; - - switch (rr) { - case 0x02: - case 0x21: - /* 1 MB unformatted medium, treat these two as equivalent. */ - switch (dr) { - case 0x06: - /* 5.25" Single-RPM HD drive, treat as 300 kbps, 360 rpm. */ - tf |= 0x21; - break; - - default: - /* Any other drive, treat as 250 kbps, 300 rpm. */ - tf |= 0x02; - break; - } - break; - - default: - tf |= rr; - break; - } - - return tf; -} - - -uint32_t -common_get_raw_size(int drive, int side) -{ - double rate = 0.0; - double rpm, rpm_diff; - double size = 100000.0; - int mfm; - - mfm = d86f_is_mfm(drive); - rpm = ((d86f_track_flags(drive) & 0xE0) == 0x20) ? 360.0 : 300.0; - rpm_diff = 1.0; - - switch (d86f_get_rpm_mode(drive)) { - case 1: - rpm_diff = 1.01; - break; - - case 2: - rpm_diff = 1.015; - break; - - case 3: - rpm_diff = 1.02; - break; - - default: - rpm_diff = 1.0; - break; - } - - switch (d86f_track_flags(drive) & 7) { - case 0: - rate = 500.0; - break; - - case 1: - rate = 300.0; - break; - - case 2: - rate = 250.0; - break; - - case 3: - rate = 1000.0; - break; - - case 5: - rate = 2000.0; - break; - - default: - rate = 250.0; - break; - } - - if (! mfm) rate /= 2.0; - - size = (size / 250.0) * rate; - size = (size * 300.0) / rpm; - size *= rpm_diff; - - /* - * Round down to a multiple of 16 and add the extra bit cells, - * then return. - */ - return ((((uint32_t) size) >> 4) << 4) + d86f_handler[drive].extra_bit_cells(drive, side); -} - - -void -d86f_set_version(int drive, uint16_t version) -{ - d86f_t *dev = d86f[drive]; - - dev->version = version; -} - - -void -d86f_unregister(int drive) -{ - d86f_t *dev = d86f[drive]; - - if (dev == NULL) return; - - d86f_handler[drive].disk_flags = null_disk_flags; - d86f_handler[drive].side_flags = null_side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = null_set_sector; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 0; - - dev->version = 0x0063; /* Proxied formats report as version 0.99. */ -} - - -void -d86f_register_86f(int drive) -{ - d86f_handler[drive].disk_flags = d86f_disk_flags; - d86f_handler[drive].side_flags = d86f_side_flags; - d86f_handler[drive].writeback = d86f_writeback; - d86f_handler[drive].set_sector = null_set_sector; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = d86f_format_conditions; - d86f_handler[drive].extra_bit_cells = d86f_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = d86f_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; -} - - -int -d86f_get_array_size(int drive, int side) -{ - int array_size; - int hole, rm; - - rm = d86f_get_rpm_mode(drive); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; - switch (hole) { - case 0: - case 1: - default: - array_size = 12500; - switch (rm) { - case 1: - array_size = 12625; - break; - - case 2: - array_size = 12687; - break; - - case 3: - array_size = 12750; - break; - - default: - break; - } - break; - - case 2: - array_size = 25000; - switch (rm) { - case 1: - array_size = 25250; - break; - - case 2: - array_size = 25375; - break; - - case 3: - array_size = 25500; - break; - - default: - break; - } - break; - - case 3: - array_size = 50000; - switch (rm) { - case 1: - array_size = 50500; - break; - - case 2: - array_size = 50750; - break; - - case 3: - array_size = 51000; - break; - - default: - break; - } - break; - } - - array_size <<= 4; - array_size += d86f_handler[drive].extra_bit_cells(drive, side); - array_size >>= 4; - - if (d86f_handler[drive].extra_bit_cells(drive, side) & 15) - array_size++; - - return array_size; -} - - -int -d86f_valid_bit_rate(int drive) -{ - int hole, rate; - - rate = fdc_get_bit_rate(d86f_fdc); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; - switch (hole) { - case 0: /* DD */ - if (!rate && (fdd_get_flags(drive) & 0x10)) return 1; - if ((rate < 1) || (rate > 2)) return 0; - return 1; - - case 1: /* HD */ - if (rate != 0) return 0; - return 1; - - case 2: /* ED */ - if (rate != 3) return 0; - return 1; - - case 3: /* ED with 2000 kbps support */ - if (rate < 3) return 0; - return 1; - } - - return 1; //FIXME: should be 0 for error? -} - - -int -d86f_hole(int drive) -{ - if (((d86f_handler[drive].disk_flags(drive) >> 1) & 3) == 3) - return 2; - - return (d86f_handler[drive].disk_flags(drive) >> 1) & 3; -} - - -uint8_t -d86f_get_encoding(int drive) -{ - return (d86f_track_flags(drive) & 0x18) >> 3; -} - - -double -d86f_byteperiod(int drive) -{ - switch (d86f_track_flags(drive) & 0x0f) { - case 0x02: /* 125 kbps, FM */ - return 4.0; - - case 0x01: /* 150 kbps, FM */ - return 20.0 / 6.0; - - case 0x0a: /* 250 kbps, MFM */ - case 0x00: /* 250 kbps, FM */ - return 2.0; - - case 0x09: /* 300 kbps, MFM */ - return 10.0 / 6.0; - - case 0x08: /* 500 kbps, MFM */ - return 1.0; - - case 0x0b: /* 1000 kbps, MFM */ - return 0.5; - - case 0x0d: /* 2000 kbps, MFM */ - return 0.25; - - default: - break; - } - - return 2.0; -} - - -int -d86f_is_mfm(int drive) -{ - return (d86f_track_flags(drive) & 8) ? 1 : 0; -} - - -uint32_t -d86f_get_data_len(int drive) -{ - d86f_t *dev = d86f[drive]; - - if (dev->req_sector.id.n) { - if (dev->req_sector.id.n == 8) return 32768; - return (128 << ((uint32_t) dev->req_sector.id.n)); - } else { - if (fdc_get_dtl(d86f_fdc) < 128) - return fdc_get_dtl(d86f_fdc); - else - return (128 << ((uint32_t) dev->req_sector.id.n)); - } -} - - -uint32_t -d86f_has_extra_bit_cells(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) >> 7) & 1; -} - - -uint32_t -d86f_header_size(int drive) -{ - return 8; -} - - -static uint16_t -d86f_encode_get_data(uint8_t dat) -{ - uint16_t temp; - temp = 0; - - if (dat & 0x01) temp |= 1; - if (dat & 0x02) temp |= 4; - if (dat & 0x04) temp |= 16; - if (dat & 0x08) temp |= 64; - if (dat & 0x10) temp |= 256; - if (dat & 0x20) temp |= 1024; - if (dat & 0x40) temp |= 4096; - if (dat & 0x80) temp |= 16384; - - return temp; -} - - -static uint16_t -d86f_encode_get_clock(uint8_t dat) -{ - uint16_t temp; - temp = 0; - - if (dat & 0x01) temp |= 2; - if (dat & 0x02) temp |= 8; - if (dat & 0x40) temp |= 32; - if (dat & 0x08) temp |= 128; - if (dat & 0x10) temp |= 512; - if (dat & 0x20) temp |= 2048; - if (dat & 0x40) temp |= 8192; - if (dat & 0x80) temp |= 32768; - - return temp; -} - - -int -d86f_format_conditions(int drive) -{ - return d86f_valid_bit_rate(drive); -} - - -int -d86f_wrong_densel(int drive) -{ - int is_3mode = 0; - - if ((fdd_get_flags(drive) & 7) == 3) - is_3mode = 1; - - switch (d86f_hole(drive)) { - case 0: - default: - if (fdd_is_dd(drive)) - return 0; - if (fdd_get_densel(drive)) - return 1; - else - return 0; - break; - - case 1: - if (fdd_is_dd(drive)) - return 1; - if (fdd_get_densel(drive)) - return 0; - else { - if (is_3mode) - return 0; - else - return 1; - } - break; - - case 2: - if (fdd_is_dd(drive) || !fdd_is_ed(drive)) - return 1; - if (fdd_get_densel(drive)) - return 0; - else - return 1; - break; - } -} - - -int -d86f_can_format(int drive) -{ - int temp; - - temp = !writeprot[drive]; - temp = temp && !fdc_get_swwp(d86f_fdc); - temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); - temp = temp && d86f_handler[drive].format_conditions(drive); /* Allows proxied formats to add their own extra conditions to formatting. */ - temp = temp && !d86f_wrong_densel(drive); - - return temp; -} - - -uint16_t -d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) -{ - uint8_t encoding = d86f_get_encoding(drive); - uint8_t bits89AB = prev_b.nibbles.nibble0; - uint8_t bits7654 = b.nibbles.nibble1; - uint8_t bits3210 = b.nibbles.nibble0; - uint16_t encoded_7654, encoded_3210, result; - - if (encoding > 1) return 0xff; - - if (sync) { - result = d86f_encode_get_data(b.byte); - if (encoding) { - switch(b.byte) { - case 0xa1: - return result | d86f_encode_get_clock(0x0a); - - case 0xc2: - return result | d86f_encode_get_clock(0x14); - - case 0xf8: - return result | d86f_encode_get_clock(0x03); - - case 0xfb: - case 0xfe: - return result | d86f_encode_get_clock(0x00); - - case 0xfc: - return result | d86f_encode_get_clock(0x01); - } - } else { - switch(b.byte) { - case 0xf8: - case 0xfb: - case 0xfe: - return result | d86f_encode_get_clock(0xc7); - - case 0xfc: - return result | d86f_encode_get_clock(0xd7); - } - } - } - - bits3210 += ((bits7654 & 3) << 4); - bits7654 += ((bits89AB & 3) << 4); - encoded_3210 = (encoding == 1) ? encoded_mfm[bits3210] : encoded_fm[bits3210]; - encoded_7654 = (encoding == 1) ? encoded_mfm[bits7654] : encoded_fm[bits7654]; - result = (encoded_7654 << 8) | encoded_3210; - - return result; -} - - -static int -d86f_get_bitcell_period(int drive) -{ - double rate = 0.0; - int mfm = 0; - int tflags = 0; - double rpm = 0; - double size = 8000.0; - - tflags = d86f_track_flags(drive); - - mfm = (tflags & 8) ? 1 : 0; - rpm = ((tflags & 0xE0) == 0x20) ? 360.0 : 300.0; - - switch (tflags & 7) { - case 0: - rate = 500.0; - break; - - case 1: - rate = 300.0; - break; - - case 2: - rate = 250.0; - break; - - case 3: - rate = 1000.0; - break; - - case 5: - rate = 2000.0; - break; - } - - if (! mfm) - rate /= 2.0; - size = (size * 250.0) / rate; - size = (size * 300.0) / rpm; - size = (size * fdd_getrpm(real_drive(d86f_fdc, drive))) / 300.0; - - return (int)size; -} - - -int -d86f_can_read_address(int drive) -{ - int temp; - - temp = (fdc_get_bitcell_period(d86f_fdc) == d86f_get_bitcell_period(drive)); - temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); - temp = temp && (fdc_is_mfm(d86f_fdc) == d86f_is_mfm(drive)); - temp = temp && (d86f_get_encoding(drive) <= 1); - - return temp; -} - - -void -d86f_get_bit(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - uint32_t track_word; - uint32_t track_bit; - uint16_t encoded_data; - uint16_t surface_data = 0; - uint16_t current_bit; - uint16_t surface_bit; - - track_word = dev->track_pos >> 4; - - /* We need to make sure we read the bits from MSB to LSB. */ - track_bit = 15 - (dev->track_pos & 15); - - if (d86f_reverse_bytes(drive)) { - /* Image is in reverse endianness, read the data as is. */ - encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; - } else { - /* We store the words as big endian, so we need to convert them to little endian when reading. */ - encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; - encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); - } - - if (d86f_has_surface_desc(drive)) { - if (d86f_reverse_bytes(drive)) { - surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { - surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; - surface_data |= (dev->track_surface_data[side][track_word] >> 8); - } - } - - current_bit = (encoded_data >> track_bit) & 1; - dev->last_word[side] <<= 1; - - if (d86f_has_surface_desc(drive)) { - surface_bit = (surface_data >> track_bit) & 1; - if (! surface_bit) { - if (! current_bit) { - /* Bit is 0 and is not set to fuzzy, we add it as read. */ - dev->last_word[side] |= 1; - } else { - /* Bit is 1 and is not set to fuzzy, we add it as read. */ - dev->last_word[side] |= 1; - } - } else { - if (current_bit) { - /* Bit is 1 and is set to fuzzy, we randomly generate it. */ - dev->last_word[side] |= (random_generate() & 1); - } - } - } else { - dev->last_word[side] |= current_bit; - } -} - - -void -d86f_put_bit(int drive, int side, int bit) -{ - d86f_t *dev = d86f[drive]; - uint32_t track_word; - uint32_t track_bit; - uint16_t encoded_data; - uint16_t surface_data = 0; - uint16_t current_bit; - uint16_t surface_bit; - - if (fdc_get_diswr(d86f_fdc)) - return; - - track_word = dev->track_pos >> 4; - - /* We need to make sure we read the bits from MSB to LSB. */ - track_bit = 15 - (dev->track_pos & 15); - - if (d86f_reverse_bytes(drive)) { - /* Image is in reverse endianness, read the data as is. */ - encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; - } else { - /* We store the words as big endian, so we need to convert them to little endian when reading. */ - encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; - encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); - } - - if (d86f_has_surface_desc(drive)) { - if (d86f_reverse_bytes(drive)) { - surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { - surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; - surface_data |= (dev->track_surface_data[side][track_word] >> 8); - } - } - - current_bit = (encoded_data >> track_bit) & 1; - dev->last_word[side] <<= 1; - - if (d86f_has_surface_desc(drive)) { - surface_bit = (surface_data >> track_bit) & 1; - if (! surface_bit) { - if (! current_bit) { - /* Bit is 0 and is not set to fuzzy, we overwrite it as is. */ - dev->last_word[side] |= bit; - current_bit = bit; - } else { - /* Bit is 1 and is not set to fuzzy, we overwrite it as is. */ - dev->last_word[side] |= bit; - current_bit = bit; - } - } else { - if (current_bit) { - /* Bit is 1 and is set to fuzzy, we overwrite it with a non-fuzzy bit. */ - dev->last_word[side] |= bit; - current_bit = bit; - surface_bit = 0; - } - } - - surface_data &= ~(1 << track_bit); - surface_data |= (surface_bit << track_bit); - if (d86f_reverse_bytes(drive)) { - dev->track_surface_data[side][track_word] = surface_data; - } else { - dev->track_surface_data[side][track_word] = (surface_data & 0xFF) << 8; - dev->track_surface_data[side][track_word] |= (surface_data >> 8); - } - } else { - dev->last_word[side] |= bit; - current_bit = bit; - } - - encoded_data &= ~(1 << track_bit); - encoded_data |= (current_bit << track_bit); - - if (d86f_reverse_bytes(drive)) { - d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data; - } else { - d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8; - d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8); - } -} - - -static uint8_t -decodefm(int drive, uint16_t dat) -{ - uint8_t temp = 0; - - /* - * We write the encoded bytes in big endian, so we - * process the two 8-bit halves swapped here. - */ - if (dat & 0x0001) temp |= 1; - if (dat & 0x0004) temp |= 2; - if (dat & 0x0010) temp |= 4; - if (dat & 0x0040) temp |= 8; - if (dat & 0x0100) temp |= 16; - if (dat & 0x0400) temp |= 32; - if (dat & 0x1000) temp |= 64; - if (dat & 0x4000) temp |= 128; - - return temp; -} - - -void -fdd_calccrc(uint8_t byte, crc_t *crc_var) -{ - crc_var->word = (crc_var->word << 8) ^ - CRCTable[(crc_var->word >> 8)^byte]; -} - - -static void -d86f_calccrc(d86f_t *dev, uint8_t byte) -{ - fdd_calccrc(byte, &(dev->calc_crc)); -} - - -int -d86f_word_is_aligned(int drive, int side, uint32_t base_pos) -{ - d86f_t *dev = d86f[drive]; - uint32_t adjusted_track_pos = dev->track_pos; - - if (base_pos == 0xFFFFFFFF) return 0; - - /* - * This is very important, it makes sure alignment is detected - * correctly even across the index hole of a track whose length - * is not divisible by 16. - */ - if (adjusted_track_pos < base_pos) { - adjusted_track_pos += d86f_handler[drive].get_raw_size(drive, side); - } - - if ((adjusted_track_pos & 15) == (base_pos & 15)) return 1; - - return 0; -} - - -/* State 1: Find sector ID */ -void -d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) -{ - d86f_t *dev = d86f[drive]; - - d86f_get_bit(drive, side); - - if (dev->last_word[side] == req_am) { - dev->calc_crc.word = 0xFFFF; - fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - dev->preceding_bit[side] = dev->last_word[side] & 1; - dev->state++; - return; - } - - if ((ignore_other_am & 2) && (dev->last_word[side] == other_am)) { - dev->calc_crc.word = 0xFFFF; - fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - if (ignore_other_am & 1) { - /* Skip mode, let's go back to finding ID. */ - dev->state -= 2; - } else { - /* Not skip mode, process the sector anyway. */ - fdc_set_wrong_am(d86f_fdc); - dev->preceding_bit[side] = dev->last_word[side] & 1; - dev->state++; - } - } -} - - -/* When writing in FM mode, we find the beginning of the address mark by looking for 352 (22 * 16) set bits (gap fill = 0xFF, 0xFFFF FM-encoded). */ -void -d86f_write_find_address_mark_fm(int drive, int side, find_t *find) -{ - d86f_t *dev = d86f[drive]; - - d86f_get_bit(drive, side); - - if (dev->last_word[side] & 1) { - find->sync_marks++; - if (find->sync_marks == 352) { - dev->calc_crc.word = 0xFFFF; - dev->preceding_bit[side] = 1; - find->sync_marks = 0; - dev->state++; - return; - } - } - - /* If we hadn't found enough set bits but have found a clear bit, null the counter of set bits. */ - if (!(dev->last_word[side] & 1)) { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - } -} - - -void -d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) -{ - d86f_t *dev = d86f[drive]; - - d86f_get_bit(drive, side); - - if (dev->last_word[side] == 0x4489) { - find->sync_marks++; - find->sync_pos = dev->track_pos; - return; - } - - if ((dev->last_word[side] == req_am) && (find->sync_marks >= 3)) { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) { - dev->calc_crc.word = 0xCDB4; - fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - dev->preceding_bit[side] = dev->last_word[side] & 1; - dev->state++; - return; - } - } - - if ((ignore_other_am & 2) && (dev->last_word[side] == other_am) && (find->sync_marks >= 3)) { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) { - dev->calc_crc.word = 0xCDB4; - fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - if (ignore_other_am & 1) { - /* Skip mode, let's go back to finding ID. */ - dev->state -= 2; - } else { - /* Not skip mode, process the sector anyway. */ - fdc_set_wrong_am(d86f_fdc); - dev->preceding_bit[side] = dev->last_word[side] & 1; - dev->state++; - } - return; - } - } - - if (dev->last_word[side] != 0x4489) { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - } - } -} - - -/* When writing in MFM mode, we find the beginning of the address mark by looking for 3 0xA1 sync bytes. */ -void -d86f_write_find_address_mark_mfm(int drive, int side, find_t *find) -{ - d86f_t *dev = d86f[drive]; - - d86f_get_bit(drive, side); - - if (dev->last_word[side] == 0x4489) { - find->sync_marks++; - find->sync_pos = dev->track_pos; - if (find->sync_marks == 3) { - dev->calc_crc.word = 0xCDB4; - dev->preceding_bit[side] = 1; - find->sync_marks = 0; - dev->state++; - return; - } - } - - /* If we hadn't found enough address mark sync marks, null the counter. */ - if (dev->last_word[side] != 0x4489) { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - } - } -} - - -/* State 2: Read sector ID and CRC*/ -void -d86f_read_sector_id(int drive, int side, int match) -{ - d86f_t *dev = d86f[drive]; - - if (dev->id_find.bits_obtained) { - if (! (dev->id_find.bits_obtained & 15)) { - /* We've got a byte. */ - if (dev->id_find.bytes_obtained < 4) { - dev->last_sector.byte_array[dev->id_find.bytes_obtained] = decodefm(drive, dev->last_word[side]); - fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc)); - } else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) { - dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = decodefm(drive, dev->last_word[side]); - } - dev->id_find.bytes_obtained++; - - if (dev->id_find.bytes_obtained == 6) { - /* We've got the ID. */ - if (dev->calc_crc.word != dev->track_crc.word) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); - if ((dev->state != STATE_02_READ_ID) && (dev->state != STATE_0A_READ_ID)) { - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_headercrcerror(d86f_fdc); - } else if (dev->state == STATE_0A_READ_ID) { - dev->state--; - } else { - dev->error_condition |= 1; /* Mark that there was an ID CRC error. */ - dev->state++; - } - } else if ((dev->calc_crc.word == dev->track_crc.word) && (dev->state == STATE_0A_READ_ID)) { - /* CRC is valid and this is a read sector ID command. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); - dev->state = STATE_IDLE; - } else { - /* CRC is valid. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - dev->id_found++; - if ((dev->last_sector.dword == dev->req_sector.dword) || !match) { - d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); - if (dev->state == STATE_02_READ_ID) { - /* READ TRACK command, we need some special handling here. */ - /* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */ - if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { - dev->error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */ - /* Make sure we use the sector size from the FDC. */ - dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; - } - - /* If the two ID's are identical, then we do not need to do anything regarding the sector size. */ - } - dev->state++; - } else { - if (dev->last_sector.id.c != dev->req_sector.id.c) { - if (dev->last_sector.id.c == 0xFF) { - dev->error_condition |= 8; - } else { - dev->error_condition |= 0x10; - } - } - - dev->state--; - } - } - } - } - } - - d86f_get_bit(drive, side); - - dev->id_find.bits_obtained++; -} - - -uint8_t -d86f_get_data(int drive, int base) -{ - d86f_t *dev = d86f[drive]; - int data; - - if (dev->data_find.bytes_obtained < (d86f_get_data_len(drive) + base)) { - data = fdc_getdata(d86f_fdc, dev->data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1)); - if ((data & DMA_OVER) || (data == -1)) { - dev->dma_over++; - if (data == -1) - data = 0; - else - data &= 0xff; - } - } else { - data = 0; - } - - return data; -} - - -void -d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte) -{ - d86f_t *dev = d86f[drive]; - - switch(fdc_get_compare_condition(d86f_fdc)) { - case 0: /* SCAN EQUAL */ - if ((received_byte == disk_byte) || (received_byte == 0xFF)) - dev->satisfying_bytes++; - break; - - case 1: /* SCAN LOW OR EQUAL */ - if ((received_byte <= disk_byte) || (received_byte == 0xFF)) - dev->satisfying_bytes++; - break; - - case 2: /* SCAN HIGH OR EQUAL */ - if ((received_byte >= disk_byte) || (received_byte == 0xFF)) - dev->satisfying_bytes++; - break; - } -} - - -/* State 4: Read sector data and CRC*/ -void -d86f_read_sector_data(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - int data = 0; - int recv_data = 0; - int read_status = 0; - uint32_t sector_len = dev->last_sector.id.n; - uint32_t crc_pos = 0; - sector_len = 1 << (7 + sector_len); - crc_pos = sector_len + 2; - - if (dev->data_find.bits_obtained) { - if (!(dev->data_find.bits_obtained & 15)) { - /* We've got a byte. */ - if (dev->data_find.bytes_obtained < sector_len) { - data = decodefm(drive, dev->last_word[side]); - if (dev->state == STATE_11_SCAN_DATA) { - /* Scan/compare command. */ - recv_data = d86f_get_data(drive, 0); - d86f_compare_byte(drive, recv_data, data); - } else { - if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { - if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, data); - if (read_status == -1) { - dev->dma_over++; - } - } - } - } - fdd_calccrc(data, &(dev->calc_crc)); - } else if (dev->data_find.bytes_obtained < crc_pos) { - dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]); - } - dev->data_find.bytes_obtained++; - - if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { - /* We've got the data. */ - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - - d86f_get_bit(drive, side); - - dev->data_find.bits_obtained++; - return; - } - - if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { - d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_datacrcerror(d86f_fdc); - } else if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state == STATE_02_READ_DATA)) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition |= 2; /* Mark that there was a data error. */ - dev->state = STATE_IDLE; - fdc_track_finishread(d86f_fdc, dev->error_condition); - } else { - /* CRC is valid. */ - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - if (dev->state == STATE_11_SCAN_DATA) { - dev->state = STATE_IDLE; - fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); - } else { - dev->state = STATE_IDLE; - fdc_sector_finishread(d86f_fdc); - } - } - } - } - } - - d86f_get_bit(drive, side); - - dev->data_find.bits_obtained++; -} - - -void -d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) -{ - d86f_t *dev = d86f[drive]; - uint16_t bit_pos; - uint16_t temp; - uint32_t sector_len = dev->last_sector.id.n; - uint32_t crc_pos = 0; - sector_len = (1 << (7 + sector_len)) + 1; - crc_pos = sector_len + 2; - - if (! (dev->data_find.bits_obtained & 15)) { - if (dev->data_find.bytes_obtained < crc_pos) { - if (! dev->data_find.bytes_obtained) { - /* We're writing the address mark. */ - dev->current_byte[side] = am; - } else if (dev->data_find.bytes_obtained < sector_len) { - /* We're in the data field of the sector, read byte from FDC and request new byte. */ - dev->current_byte[side] = d86f_get_data(drive, 1); - if (! fdc_get_diswr(d86f_fdc)) - d86f_handler[drive].write_data(drive, side, dev->data_find.bytes_obtained - 1, dev->current_byte[side]); - } else { - /* We're in the data field of the sector, use a CRC byte. */ - dev->current_byte[side] = dev->calc_crc.bytes[(dev->data_find.bytes_obtained & 1)]; - } - - dev->current_bit[side] = (15 - (dev->data_find.bits_obtained & 15)) >> 1; - - /* Write the bit. */ - temp = (dev->current_byte[side] >> dev->current_bit[side]) & 1; - if ((!temp && !dev->preceding_bit[side]) || !mfm) { - temp |= 2; - } - - /* This is an even bit, so write the clock. */ - if (! dev->data_find.bytes_obtained) { - /* Address mark, write bit directly. */ - d86f_put_bit(drive, side, am >> 15); - } else { - d86f_put_bit(drive, side, temp >> 1); - } - - if (dev->data_find.bytes_obtained < sector_len) { - /* This is a data byte, so CRC it. */ - if (! dev->data_find.bytes_obtained) { - fdd_calccrc(decodefm(drive, am), &(dev->calc_crc)); - } else { - fdd_calccrc(dev->current_byte[side], &(dev->calc_crc)); - } - } - } - } else { - if (dev->data_find.bytes_obtained < crc_pos) { - /* Encode the bit. */ - bit_pos = 15 - (dev->data_find.bits_obtained & 15); - dev->current_bit[side] = bit_pos >> 1; - - temp = (dev->current_byte[side] >> dev->current_bit[side]) & 1; - if ((!temp && !dev->preceding_bit[side]) || !mfm) { - temp |= 2; - } - - if (! dev->data_find.bytes_obtained) { - /* Address mark, write directly. */ - d86f_put_bit(drive, side, am >> bit_pos); - if (! (bit_pos & 1)) { - dev->preceding_bit[side] = am >> bit_pos; - } - } else { - if (bit_pos & 1) { - /* Clock bit */ - d86f_put_bit(drive, side, temp >> 1); - } else { - /* Data bit */ - d86f_put_bit(drive, side, temp & 1); - dev->preceding_bit[side] = temp & 1; - } - } - } - - if ((dev->data_find.bits_obtained & 15) == 15) { - dev->data_find.bytes_obtained++; - - if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - - dev->data_find.bits_obtained++; - return; - } - - /* We've written the data. */ - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - d86f_handler[drive].writeback(drive); - fdc_sector_finishread(d86f_fdc); - return; - } - } - } - - dev->data_find.bits_obtained++; -} - - -void d86f_advance_bit(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - dev->track_pos++; - dev->track_pos %= d86f_handler[drive].get_raw_size(drive, side); - - if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { - d86f_handler[drive].read_revolution(drive); - - if (dev->state != STATE_IDLE) - dev->index_count++; - } -} - - -void -d86f_advance_word(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - dev->track_pos += 16; - dev->track_pos %= d86f_handler[drive].get_raw_size(drive, side); - - if ((dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (dev->state != STATE_IDLE)) - dev->index_count++; -} - - -void -d86f_spin_to_index(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - d86f_get_bit(drive, side); - d86f_get_bit(drive, side ^ 1); - - d86f_advance_bit(drive, side); - - if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { - if ((dev->state == STATE_0D_SPIN_TO_INDEX) || (dev->state == STATE_0D_NOP_SPIN_TO_INDEX)) { - /* When starting format, reset format state to the beginning. */ - dev->preceding_bit[side] = 1; - dev->format_state = FMT_PRETRK_GAP0; - } - - /* This is to make sure both READ TRACK and FORMAT TRACK command don't end prematurely. */ - dev->index_count = 0; - dev->state++; - } -} - - -void -d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint32_t pos) -{ - d86f_t *dev = d86f[drive]; - uint16_t encoded_byte = 0, mask_data, mask_surface, mask_hole, mask_fuzzy; - decoded_t dbyte, dpbyte; - - if (fdc_get_diswr(d86f_fdc)) return; - - dbyte.byte = byte & 0xff; - dpbyte.byte = dev->preceding_bit[side] & 0xff; - - if (type == 0) { - /* Byte write. */ - encoded_byte = d86f_encode_byte(drive, 0, dbyte, dpbyte); - if (! d86f_reverse_bytes(drive)) { - mask_data = encoded_byte >> 8; - encoded_byte &= 0xFF; - encoded_byte <<= 8; - encoded_byte |= mask_data; - } - } else { - /* Word write. */ - encoded_byte = byte; - if (d86f_reverse_bytes(drive)) { - mask_data = encoded_byte >> 8; - encoded_byte &= 0xFF; - encoded_byte <<= 8; - encoded_byte |= mask_data; - } - } - - dev->preceding_bit[side] = encoded_byte & 1; - - if (d86f_has_surface_desc(drive)) { - mask_data = dev->track_encoded_data[side][pos] ^= 0xFFFF; - mask_surface = dev->track_surface_data[side][pos]; - mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */ - encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */ - mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */ - mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */ - dev->track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */ - } - - dev->track_encoded_data[side][pos] = encoded_byte; - dev->last_word[side] = encoded_byte; -} - - -void -d86f_write_direct(int drive, int side, uint16_t byte, uint8_t type) -{ - d86f_t *dev = d86f[drive]; - - d86f_write_direct_common(drive, side, byte, type, dev->track_pos >> 4); -} - - -uint16_t -endian_swap(uint16_t word) -{ - uint16_t temp; - - temp = word & 0xff; - temp <<= 8; - temp |= (word >> 8); - - return temp; -} - - -void -d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, int do_write) -{ - d86f_t *dev = d86f[drive]; - - if (mfm && do_write) { - if (do_write && (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side))) { - d86f_write_direct_common(drive, side, gap_fill, 0, 0); - } - } - - dev->state = STATE_IDLE; - - if (do_write) - d86f_handler[drive].writeback(drive); - - dev->error_condition = 0; - dev->datac = 0; - fdc_sector_finishread(d86f_fdc); -} - - -void -d86f_format_turbo_finish(int drive, int side, int do_write) -{ - d86f_t *dev = d86f[drive]; - - dev->state = STATE_IDLE; - - if (do_write) - d86f_handler[drive].writeback(drive); - - dev->error_condition = 0; - dev->datac = 0; - fdc_sector_finishread(d86f_fdc); -} - - -void -d86f_format_track(int drive, int side, int do_write) -{ - d86f_t *dev = d86f[drive]; - int data; - uint16_t max_len; - - int mfm; - uint16_t sc = 0; - uint16_t dtl = 0; - int gap_sizes[4] = { 0, 0, 0, 0 }; - int am_len = 0; - int sync_len = 0; - uint16_t iam_mfm[4] = { 0x2452, 0x2452, 0x2452, 0x5255 }; - uint16_t idam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x5455 }; - uint16_t dataam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x4555 }; - uint16_t iam_fm = 0xFAF7; - uint16_t idam_fm = 0x7EF5; - uint16_t dataam_fm = 0x6FF5; - uint16_t gap_fill = 0x4E; - - mfm = d86f_is_mfm(drive); - am_len = mfm ? 4 : 1; - gap_sizes[0] = mfm ? 80 : 40; - gap_sizes[1] = mfm ? 50 : 26; - gap_sizes[2] = fdc_get_gap2(d86f_fdc, real_drive(d86f_fdc, drive)); - gap_sizes[3] = fdc_get_gap(d86f_fdc); - sync_len = mfm ? 12 : 6; - sc = fdc_get_format_sectors(d86f_fdc); - dtl = 128 << fdc_get_format_n(d86f_fdc); - gap_fill = mfm ? 0x4E : 0xFF; - - switch(dev->format_state) { - case FMT_POSTTRK_GAP4: - max_len = 60000; - if (do_write) - d86f_write_direct(drive, side, gap_fill, 0); - break; - - case FMT_PRETRK_GAP0: - max_len = gap_sizes[0]; - if (do_write) - d86f_write_direct(drive, side, gap_fill, 0); - break; - - case FMT_SECTOR_ID_SYNC: - max_len = sync_len; - if (dev->datac <= 3) { - data = fdc_getdata(d86f_fdc, 0); - if (data != -1) - data &= 0xff; - if ((data == -1) && (dev->datac < 3)) - data = 0; - dev->format_sector_id.byte_array[dev->datac] = data & 0xff; - if (dev->datac == 3) - fdc_stop_id_request(d86f_fdc); - } - /*FALLTHROUGH*/ - - case FMT_PRETRK_SYNC: - case FMT_SECTOR_DATA_SYNC: - max_len = sync_len; - if (do_write) - d86f_write_direct(drive, side, 0x00, 0); - break; - - case FMT_PRETRK_IAM: - max_len = am_len; - if (do_write) { - if (mfm) - d86f_write_direct(drive, side, iam_mfm[dev->datac], 1); - else - d86f_write_direct(drive, side, iam_fm, 1); - } - break; - - case FMT_PRETRK_GAP1: - max_len = gap_sizes[1]; - if (do_write) - d86f_write_direct(drive, side, gap_fill, 0); - break; - - case FMT_SECTOR_IDAM: - max_len = am_len; - if (mfm) { - if (do_write) - d86f_write_direct(drive, side, idam_mfm[dev->datac], 1); - d86f_calccrc(dev, (dev->datac < 3) ? 0xA1 : 0xFE); - } else { - if (do_write) - d86f_write_direct(drive, side, idam_fm, 1); - d86f_calccrc(dev, 0xFE); - } - break; - - case FMT_SECTOR_ID: - max_len = 4; - if (do_write) { - d86f_write_direct(drive, side, dev->format_sector_id.byte_array[dev->datac], 0); - d86f_calccrc(dev, dev->format_sector_id.byte_array[dev->datac]); - } else { - if (dev->datac == 3) { - d86f_handler[drive].set_sector(drive, side, dev->format_sector_id.id.c, dev->format_sector_id.id.h, dev->format_sector_id.id.r, dev->format_sector_id.id.n); - } - } - break; - - case FMT_SECTOR_ID_CRC: - case FMT_SECTOR_DATA_CRC: - max_len = 2; - if (do_write) - d86f_write_direct(drive, side, dev->calc_crc.bytes[dev->datac ^ 1], 0); - break; - - case FMT_SECTOR_GAP2: - max_len = gap_sizes[2]; - if (do_write) - d86f_write_direct(drive, side, gap_fill, 0); - break; - - case FMT_SECTOR_DATAAM: - max_len = am_len; - if (mfm) { - if (do_write) - d86f_write_direct(drive, side, dataam_mfm[dev->datac], 1); - d86f_calccrc(dev, (dev->datac < 3) ? 0xA1 : 0xFB); - } else { - if (do_write) - d86f_write_direct(drive, side, dataam_fm, 1); - d86f_calccrc(dev, 0xFB); - } - break; - - case FMT_SECTOR_DATA: - max_len = dtl; - if (do_write) { - d86f_write_direct(drive, side, dev->fill, 0); - d86f_handler[drive].write_data(drive, side, dev->datac, dev->fill); - } - d86f_calccrc(dev, dev->fill); - break; - - case FMT_SECTOR_GAP3: - max_len = gap_sizes[3]; - if (do_write) - d86f_write_direct(drive, side, gap_fill, 0); - break; - - default: - max_len = 0; - break; - } - - dev->datac++; - - d86f_advance_word(drive, side); - - if ((dev->index_count) && ((dev->format_state < FMT_SECTOR_ID_SYNC) || (dev->format_state > FMT_SECTOR_GAP3))) { - d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); - return; - } - - if (dev->datac >= max_len) { - dev->datac = 0; - dev->format_state++; - - switch (dev->format_state) { - case FMT_SECTOR_ID_SYNC: - fdc_request_next_sector_id(d86f_fdc); - break; - - case FMT_SECTOR_IDAM: - case FMT_SECTOR_DATAAM: - dev->calc_crc.word = 0xffff; - break; - - case FMT_POSTTRK_CHECK: - if (dev->index_count) { - d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); - return; - } - dev->sector_count++; - if (dev->sector_count < sc) { - /* Sector within allotted amount, change state to SECTOR_ID_SYNC. */ - dev->format_state = FMT_SECTOR_ID_SYNC; - fdc_request_next_sector_id(d86f_fdc); - break; - } else { - dev->format_state = FMT_POSTTRK_GAP4; - dev->sector_count = 0; - break; - } - break; - } - } -} - - -void -d86f_format_track_normal(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - d86f_format_track(drive, side, (dev->version == D86FVER)); -} - - -void -d86f_format_track_nop(int drive, int side) -{ - d86f_format_track(drive, side, 0); -} - - -void -d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n) -{ - d86f_t *dev = d86f[drive]; - - dev->last_sector.id.c = c; - dev->last_sector.id.h = h; - dev->last_sector.id.r = r; - dev->last_sector.id.n = n; -} - - -void -d86f_turbo_read(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - uint8_t dat = 0; - int recv_data = 0; - int read_status = 0; - - dat = d86f_handler[drive].read_data(drive, side, dev->turbo_pos); - dev->turbo_pos++; - - if (dev->state == STATE_11_SCAN_DATA) { - /* Scan/compare command. */ - recv_data = d86f_get_data(drive, 0); - d86f_compare_byte(drive, recv_data, dat); - } else { - if (dev->data_find.bytes_obtained < (128UL << dev->last_sector.id.n)) { - if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, dat); - if (read_status == -1) - dev->dma_over++; - } - } - } - - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - return; - } - - if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { - /* CRC is valid. */ - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - if (dev->state == STATE_11_SCAN_DATA) { - dev->state = STATE_IDLE; - fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); - } else { - dev->state = STATE_IDLE; - fdc_sector_finishread(d86f_fdc); - } - } -} - - -void -d86f_turbo_write(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - uint8_t dat = 0; - - dat = d86f_get_data(drive, 1); - d86f_handler[drive].write_data(drive, side, dev->turbo_pos, dat); - - dev->turbo_pos++; - - if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { - /* We've written the data. */ - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - d86f_handler[drive].writeback(drive); - fdc_sector_finishread(d86f_fdc); - } -} - - -void -d86f_turbo_format(int drive, int side, int nop) -{ - d86f_t *dev = d86f[drive]; - int dat; - uint16_t sc; - uint16_t dtl; - int i; - - sc = fdc_get_format_sectors(d86f_fdc); - dtl = 128 << fdc_get_format_n(d86f_fdc); - - if (dev->datac <= 3) { - dat = fdc_getdata(d86f_fdc, 0); - if (dat != -1) - dat &= 0xff; - if ((dat == -1) && (dev->datac < 3)) - dat = 0; - dev->format_sector_id.byte_array[dev->datac] = dat & 0xff; - if (dev->datac == 3) { - fdc_stop_id_request(d86f_fdc); - d86f_handler[drive].set_sector(drive, side, dev->format_sector_id.id.c, dev->format_sector_id.id.h, dev->format_sector_id.id.r, dev->format_sector_id.id.n); - } - } else if (dev->datac == 4) { - if (! nop) { - for (i = 0; i < dtl; i++) - d86f_handler[drive].write_data(drive, side, i, dev->fill); - } - - dev->sector_count++; - } - - dev->datac++; - - if (dev->datac == 6) { - dev->datac = 0; - - if (dev->sector_count < sc) { - /* Sector within allotted amount. */ - fdc_request_next_sector_id(d86f_fdc); - } else { - dev->state = STATE_IDLE; - d86f_format_turbo_finish(drive, side, nop); - } - } -} - - -int -d86f_sector_is_present(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - d86f_t *dev = d86f[drive]; - sector_t *s, *t; - - if (dev->last_side_sector[side]) { - s = dev->last_side_sector[side]; - while (s) { - if ((s->c == c) && (s->h == h) && (s->r == r) && (s->n == n)) - return 1; - if (! s->prev) - break; - t = s->prev; - s = t; - } - } - - return 0; -} - - -void -d86f_turbo_poll(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - if ((dev->state != STATE_IDLE) && (dev->state != STATE_SECTOR_NOT_FOUND) && ((dev->state & 0xF8) != 0xE8)) { - if (! d86f_can_read_address(drive)) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_noidam(d86f_fdc); - dev->state = STATE_IDLE; - return; - } - } - - switch(dev->state) { - case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_NOP_SPIN_TO_INDEX: - dev->sector_count = 0; - dev->datac = 5; - /*FALLTHROUGH*/ - - case STATE_02_SPIN_TO_INDEX: - dev->state++; - return; - - case STATE_02_FIND_ID: - if (! d86f_sector_is_present(drive, side, - fdc_get_read_track_sector(d86f_fdc).id.c, - fdc_get_read_track_sector(d86f_fdc).id.h, - fdc_get_read_track_sector(d86f_fdc).id.r, - fdc_get_read_track_sector(d86f_fdc).id.n)) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_nosector(d86f_fdc); - dev->state = STATE_IDLE; - return; - } - dev->last_sector.id.c = fdc_get_read_track_sector(d86f_fdc).id.c; - dev->last_sector.id.h = fdc_get_read_track_sector(d86f_fdc).id.h; - dev->last_sector.id.r = fdc_get_read_track_sector(d86f_fdc).id.r; - dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; - d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); - dev->turbo_pos = 0; - dev->state++; - return; - - case STATE_05_FIND_ID: - case STATE_09_FIND_ID: - case STATE_06_FIND_ID: - case STATE_0C_FIND_ID: - case STATE_11_FIND_ID: - case STATE_16_FIND_ID: - if (! d86f_sector_is_present(drive, side, - dev->req_sector.id.c, - dev->req_sector.id.h, - dev->req_sector.id.r, - dev->req_sector.id.n)) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_nosector(d86f_fdc); - dev->state = STATE_IDLE; - return; - } - dev->last_sector.id.c = dev->req_sector.id.c; - dev->last_sector.id.h = dev->req_sector.id.h; - dev->last_sector.id.r = dev->req_sector.id.r; - dev->last_sector.id.n = dev->req_sector.id.n; - d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); - /*FALLTHROUGH*/ - - case STATE_0A_FIND_ID: - dev->turbo_pos = 0; - dev->state++; - return; - - case STATE_0A_READ_ID: - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); - dev->state = STATE_IDLE; - break; - - case STATE_02_READ_ID: - case STATE_05_READ_ID: - case STATE_09_READ_ID: - case STATE_06_READ_ID: - case STATE_0C_READ_ID: - case STATE_11_READ_ID: - case STATE_16_READ_ID: - dev->state++; - break; - - case STATE_02_FIND_DATA: - case STATE_06_FIND_DATA: - case STATE_11_FIND_DATA: - case STATE_16_FIND_DATA: - case STATE_05_FIND_DATA: - case STATE_09_FIND_DATA: - case STATE_0C_FIND_DATA: - dev->state++; - break; - - case STATE_02_READ_DATA: - case STATE_06_READ_DATA: - case STATE_0C_READ_DATA: - case STATE_11_SCAN_DATA: - case STATE_16_VERIFY_DATA: - d86f_turbo_read(drive, side); - break; - - case STATE_05_WRITE_DATA: - case STATE_09_WRITE_DATA: - d86f_turbo_write(drive, side); - break; - - case STATE_0D_FORMAT_TRACK: - d86f_turbo_format(drive, side, 0); - return; - - case STATE_0D_NOP_FORMAT_TRACK: - d86f_turbo_format(drive, side, 1); - return; - - case STATE_IDLE: - case STATE_SECTOR_NOT_FOUND: - default: - break; - } -} - - -void -d86f_poll(int drive) -{ - d86f_t *dev = d86f[drive]; - int mfm, side; - - side = fdd_get_head(drive); - if (! fdd_is_double_sided(drive)) - side = 0; - - mfm = fdc_is_mfm(d86f_fdc); - - if ((dev->state & 0xF8) == 0xE8) { - if (! d86f_can_format(drive)) - dev->state = STATE_SECTOR_NOT_FOUND; - } - - if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { - d86f_turbo_poll(drive, side); - return; - } - - if ((dev->state != STATE_IDLE) && (dev->state != STATE_SECTOR_NOT_FOUND) && ((dev->state & 0xF8) != 0xE8)) { - if (! d86f_can_read_address(drive)) - dev->state = STATE_SECTOR_NOT_FOUND; - } - - if ((dev->state != STATE_02_SPIN_TO_INDEX) && (dev->state != STATE_0D_SPIN_TO_INDEX)) - d86f_get_bit(drive, side ^ 1); - - switch(dev->state) { - case STATE_02_SPIN_TO_INDEX: - case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_NOP_SPIN_TO_INDEX: - d86f_spin_to_index(drive, side); - return; - - case STATE_02_FIND_ID: - case STATE_05_FIND_ID: - case STATE_09_FIND_ID: - case STATE_06_FIND_ID: - case STATE_0A_FIND_ID: - case STATE_0C_FIND_ID: - case STATE_11_FIND_ID: - case STATE_16_FIND_ID: - if (mfm) - d86f_find_address_mark_mfm(drive, side, &(dev->id_find), 0x5554, 0, 0); - else - d86f_find_address_mark_fm(drive, side, &(dev->id_find), 0xF57E, 0, 0); - break; - - case STATE_0A_READ_ID: - case STATE_02_READ_ID: - d86f_read_sector_id(drive, side, 0); - break; - - case STATE_05_READ_ID: - case STATE_09_READ_ID: - case STATE_06_READ_ID: - case STATE_0C_READ_ID: - case STATE_11_READ_ID: - case STATE_16_READ_ID: - d86f_read_sector_id(drive, side, 1); - break; - - case STATE_02_FIND_DATA: - if (mfm) - d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x5545, 0x554A, 2); - else - d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56F, 0xF56A, 2); - break; - - case STATE_06_FIND_DATA: - case STATE_11_FIND_DATA: - case STATE_16_FIND_DATA: - if (mfm) - d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x5545, 0x554A, fdc_is_sk(d86f_fdc) | 2); - else - d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56F, 0xF56A, fdc_is_sk(d86f_fdc) | 2); - break; - - case STATE_05_FIND_DATA: - case STATE_09_FIND_DATA: - if (mfm) - d86f_write_find_address_mark_mfm(drive, side, &(dev->data_find)); - else - d86f_write_find_address_mark_fm(drive, side, &(dev->data_find)); - break; - - case STATE_0C_FIND_DATA: - if (mfm) - d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x554A, 0x5545, fdc_is_sk(d86f_fdc) | 2); - else - d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56A, 0xF56F, fdc_is_sk(d86f_fdc) | 2); - break; - - case STATE_02_READ_DATA: - case STATE_06_READ_DATA: - case STATE_0C_READ_DATA: - case STATE_11_SCAN_DATA: - case STATE_16_VERIFY_DATA: - d86f_read_sector_data(drive, side); - break; - - case STATE_05_WRITE_DATA: - if (mfm) - d86f_write_sector_data(drive, side, mfm, 0x5545); - else - d86f_write_sector_data(drive, side, mfm, 0xF56F); - break; - - case STATE_09_WRITE_DATA: - if (mfm) - d86f_write_sector_data(drive, side, mfm, 0x554A); - else - d86f_write_sector_data(drive, side, mfm, 0xF56A); - break; - - case STATE_0D_FORMAT_TRACK: - if (! (dev->track_pos & 15)) - d86f_format_track_normal(drive, side); - return; - - case STATE_0D_NOP_FORMAT_TRACK: - if (! (dev->track_pos & 15)) - d86f_format_track_nop(drive, side); - return; - - case STATE_IDLE: - case STATE_SECTOR_NOT_FOUND: - default: - d86f_get_bit(drive, side); - break; - } - - d86f_advance_bit(drive, side); - - if (d86f_wrong_densel(drive) && (dev->state != STATE_IDLE)) { - dev->state = STATE_IDLE; - fdc_noidam(d86f_fdc); - return; - } - - if ((dev->index_count == 2) && (dev->state != STATE_IDLE)) { - switch(dev->state) { - case STATE_0A_FIND_ID: - case STATE_SECTOR_NOT_FOUND: - dev->state = STATE_IDLE; - fdc_noidam(d86f_fdc); - break; - - case STATE_02_FIND_DATA: - case STATE_06_FIND_DATA: - case STATE_11_FIND_DATA: - case STATE_16_FIND_DATA: - case STATE_05_FIND_DATA: - case STATE_09_FIND_DATA: - case STATE_0C_FIND_DATA: - - dev->state = STATE_IDLE; - fdc_nodataam(d86f_fdc); - break; - - case STATE_02_SPIN_TO_INDEX: - case STATE_02_READ_DATA: - case STATE_05_WRITE_DATA: - case STATE_06_READ_DATA: - case STATE_09_WRITE_DATA: - case STATE_0C_READ_DATA: - case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_FORMAT_TRACK: - case STATE_11_SCAN_DATA: - case STATE_16_VERIFY_DATA: - /* In these states, we should *NEVER* care about how many index pulses there have been. */ - break; - - default: - dev->state = STATE_IDLE; - if (dev->id_found) { - if (dev->error_condition & 0x18) { - if ((dev->error_condition & 0x18) == 0x08) - fdc_badcylinder(d86f_fdc); - if ((dev->error_condition & 0x10) == 0x10) - fdc_wrongcylinder(d86f_fdc); - else - fdc_nosector(d86f_fdc); - } - } else { - fdc_noidam(d86f_fdc); - } - break; - } - } -} - - -void -d86f_reset_index_hole_pos(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - dev->index_hole_pos[side] = 0; -} - - -uint16_t -d86f_prepare_pretrack(int drive, int side, int iso) -{ - d86f_t *dev = d86f[drive]; - uint16_t i, pos; - int mfm; - int real_gap0_len; - int sync_len; - int real_gap1_len; - uint16_t gap_fill; - uint32_t raw_size; - uint16_t iam_fm = 0xFAF7; - uint16_t iam_mfm = 0x5255; - - mfm = d86f_is_mfm(drive); - real_gap0_len = mfm ? 80 : 40; - sync_len = mfm ? 12 : 6; - real_gap1_len = mfm ? 50 : 26; - gap_fill = mfm ? 0x4E : 0xFF; - raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; - - dev->index_hole_pos[side] = 0; - - d86f_destroy_linked_lists(drive, side); - - for (i = 0; i < raw_size; i++) - d86f_write_direct_common(drive, side, gap_fill, 0, i); - - pos = 0; - - if (! iso) { - for (i = 0; i < real_gap0_len; i++) { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < sync_len; i++) { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; - } - if (mfm) { - for (i = 0; i < 3; i++) { - d86f_write_direct_common(drive, side, 0x2452, 1, pos); - pos = (pos + 1) % raw_size; - } - } - - d86f_write_direct_common(drive, side, mfm ? iam_mfm : iam_fm, 1, pos); - pos = (pos + 1) % raw_size; - } - - for (i = 0; i < real_gap1_len; i++) { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - - return pos; -} - - -uint16_t -d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc) -{ - d86f_t *dev = d86f[drive]; - uint16_t pos; - int i; - sector_t *s; - - int real_gap2_len = gap2; - int real_gap3_len = gap3; - int mfm; - int sync_len; - uint16_t gap_fill; - uint32_t raw_size; - uint16_t idam_fm = 0x7EF5; - uint16_t dataam_fm = 0x6FF5; - uint16_t datadam_fm = 0x6AF5; - uint16_t idam_mfm = 0x5455; - uint16_t dataam_mfm = 0x4555; - uint16_t datadam_mfm = 0x4A55; - - if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { - s = (sector_t *) malloc(sizeof(sector_t)); - memset(s, 0, sizeof(sector_t)); - s->c = id_buf[0]; - s->h = id_buf[1]; - s->r = id_buf[2]; - s->n = id_buf[3]; - if (dev->last_side_sector[side]) - s->prev = dev->last_side_sector[side]; - dev->last_side_sector[side] = s; - } - - mfm = d86f_is_mfm(drive); - - gap_fill = mfm ? 0x4E : 0xFF; - raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; - - pos = prev_pos; - - sync_len = mfm ? 12 : 6; - - for (i = 0; i < sync_len; i++) { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; - } - dev->calc_crc.word = 0xffff; - if (mfm) { - for (i = 0; i < 3; i++) { - d86f_write_direct_common(drive, side, 0x8944, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, 0xA1); - } - } - d86f_write_direct_common(drive, side, mfm ? idam_mfm : idam_fm, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, 0xFE); - for (i = 0; i < 4; i++) { - d86f_write_direct_common(drive, side, id_buf[i], 0, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, id_buf[i]); - } - for (i = 1; i >= 0; i--) { - d86f_write_direct_common(drive, side, dev->calc_crc.bytes[i], 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < real_gap2_len; i++) { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < sync_len; i++) { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; - } - dev->calc_crc.word = 0xffff; - if (mfm) { - for (i = 0; i < 3; i++) { - d86f_write_direct_common(drive, side, 0x8944, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, 0xA1); - } - } - d86f_write_direct_common(drive, side, mfm ? (deleted ? datadam_mfm : dataam_mfm) : (deleted ? datadam_fm : dataam_fm), 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, deleted ? 0xF8 : 0xFB); - for (i = 0; i < data_len; i++) { - d86f_write_direct_common(drive, side, data_buf[i], 0, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(dev, data_buf[i]); - } - if (bad_crc) - dev->calc_crc.word ^= 0xffff; - for (i = 1; i >= 0; i--) { - d86f_write_direct_common(drive, side, dev->calc_crc.bytes[i], 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < real_gap3_len; i++) { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - - return pos; -} - - -/* - * Note on handling of tracks on thick track drives: - * - * - On seek, encoded data is constructed from both (track << 1) and - * ((track << 1) + 1); - * - * - Any bits that differ are treated as thus: - * - Both are regular but contents differ -> Output is fuzzy; - * - One is regular and one is fuzzy -> Output is fuzzy; - * - Both are fuzzy -> Output is fuzzy; - * - Both are physical holes -> Output is a physical hole; - * - One is regular and one is a physical hole -> Output is puzzy, - * the hole half is handled appropriately on writeback; - * - One is fuzzy and one is a physical hole -> Output is puzzy, - * the hole half is handled appropriately on writeback; - * - On write back, apart from the above notes, the final two tracks - * are written; - * - Destination ALWAYS has surface data even if the image does not. - * - * In case of a thin track drive, tracks are handled normally. - */ -void -d86f_construct_encoded_buffer(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - uint32_t i = 0; - - /* *_fuzm are fuzzy bit masks, *_holm are hole masks, dst_neim are masks is mask for bits that are neither fuzzy nor holes in both, - and src1_d and src2_d are filtered source data. */ - uint16_t src1_fuzm, src2_fuzm, dst_fuzm, src1_holm, src2_holm, dst_holm, dst_neim, src1_d, src2_d; - uint32_t len; - uint16_t *dst = dev->track_encoded_data[side]; - uint16_t *dst_s = dev->track_surface_data[side]; - uint16_t *src1 = dev->thin_track_encoded_data[0][side]; - uint16_t *src1_s = dev->thin_track_surface_data[0][side]; - uint16_t *src2 = dev->thin_track_encoded_data[1][side]; - uint16_t *src2_s = dev->thin_track_surface_data[1][side]; - len = d86f_get_array_size(drive, side); - - for (i = 0; i < len; i++) { - /* The two bits differ. */ - if (d86f_has_surface_desc(drive)) { - /* Source image has surface description data, so we have some more handling to do. */ - src1_fuzm = src1[i] & src1_s[i]; - src2_fuzm = src2[i] & src2_s[i]; - dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or - the other or both. */ - src1_holm = src1[i] | (src1_s[i] ^ 0xffff); - src2_holm = src2[i] | (src2_s[i] ^ 0xffff); - dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */ - dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither - fuzzy nor are holes in both. */ - src1_d = src1[i] & dst_neim; - src2_d = src2[i] & dst_neim; - - dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are - holes in both. */ - dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and - Source 2. */ - dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set - but data bit clear). */ - } else { - /* No surface data, the handling is much simpler - a simple OR. */ - dst[i] = src1[i] | src2[i]; - dst_s[i] = 0; - } - } -} - - -/* Decomposition is easier since we at most have to care about the holes. */ -void -d86f_decompose_encoded_buffer(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - uint32_t i = 0; - uint16_t temp, temp2; - uint32_t len; - uint16_t *dst = dev->track_encoded_data[side]; - uint16_t *src1 = dev->thin_track_encoded_data[0][side]; - uint16_t *src1_s = dev->thin_track_surface_data[0][side]; - uint16_t *src2 = dev->thin_track_encoded_data[1][side]; - uint16_t *src2_s = dev->thin_track_surface_data[1][side]; - len = d86f_get_array_size(drive, side); - - for (i = 0; i < len; i++) { - if (d86f_has_surface_desc(drive)) { - /* Source image has surface description data, so we have some more handling to do. - We need hole masks for both buffers. Holes have data bit clear and surface bit set. */ - temp = src1[i] & (src1_s[i] ^ 0xffff); - temp2 = src2[i] & (src2_s[i] ^ 0xffff); - src1[i] = dst[i] & temp; - src1_s[i] = temp ^ 0xffff; - src2[i] = dst[i] & temp2; - src2_s[i] = temp2 ^ 0xffff; - } else { - src1[i] = src2[i] = dst[i]; - } - } -} - - -int -d86f_track_header_size(int drive) -{ - int temp = 6; - - if (d86f_has_extra_bit_cells(drive)) - temp += 4; - - return temp; -} - - -void -d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, uint16_t *sa) -{ - d86f_t *dev = d86f[drive]; - int logical_track = 0; - int array_size = 0; - - if (d86f_get_sides(drive) == 2) - logical_track = ((track + thin_track) << 1) + side; - else - logical_track = track + thin_track; - - if (dev->track_offset[logical_track]) { - if (! thin_track) { - fseek(dev->f, dev->track_offset[logical_track], SEEK_SET); - fread(&(dev->side_flags[side]), 2, 1, dev->f); - if (d86f_has_extra_bit_cells(drive)) { - fread(&(dev->extra_bit_cells[side]), 4, 1, dev->f); - if (dev->extra_bit_cells[side] < -32768) - dev->extra_bit_cells[side] = -32768; - if (dev->extra_bit_cells[side] > 32768) - dev->extra_bit_cells[side] = 32768; - } else { - dev->extra_bit_cells[side] = 0; - } - fread(&(dev->index_hole_pos[side]), 4, 1, dev->f); - } else { - fseek(dev->f, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); - } - array_size = d86f_get_array_size(drive, side) << 1; - if (d86f_has_surface_desc(drive)) - fread(sa, 1, array_size, dev->f); - fread(da, 1, array_size, dev->f); - } else { - if (! thin_track) { - switch((dev->disk_flags >> 1) & 3) { - case 0: - default: - dev->side_flags[side] = 0x0A; - break; - - case 1: - dev->side_flags[side] = 0x00; - break; - - case 2: - case 3: - dev->side_flags[side] = 0x03; - break; - } - dev->extra_bit_cells[side] = 0; - } - } -} - - -void -d86f_zero_track(int drive) -{ - d86f_t *dev = d86f[drive]; - int sides, side; - sides = d86f_get_sides(drive); - - for (side = 0; side < sides; side++) { - if (d86f_has_surface_desc(drive)) - memset(dev->track_surface_data[side], 0, 106096); - memset(dev->track_encoded_data[side], 0, 106096); - } -} - - -void -d86f_seek(int drive, int track) -{ - d86f_t *dev = d86f[drive]; - int sides; - int side, thin_track; - sides = d86f_get_sides(drive); - - /* If the drive has thick tracks, shift the track number by 1. */ - if (! fdd_doublestep_40(drive)) { - track <<= 1; - - for (thin_track = 0; thin_track < sides; thin_track++) { - for (side = 0; side < sides; side++) { - if (d86f_has_surface_desc(drive)) - memset(dev->thin_track_surface_data[thin_track][side], 0, 106096); - memset(dev->thin_track_encoded_data[thin_track][side], 0, 106096); - } - } - } - - d86f_zero_track(drive); - - dev->cur_track = track; - - if (! fdd_doublestep_40(drive)) { - for (side = 0; side < sides; side++) { - for (thin_track = 0; thin_track < 2; thin_track++) - d86f_read_track(drive, track, thin_track, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); - - d86f_construct_encoded_buffer(drive, side); - } - } else { - for (side = 0; side < sides; side++) - d86f_read_track(drive, track, 0, side, dev->track_encoded_data[side], dev->track_surface_data[side]); - } - - dev->state = STATE_IDLE; -} - - -void -d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) -{ - uint16_t side_flags = d86f_handler[drive].side_flags(drive); - uint32_t extra_bit_cells = d86f_handler[drive].extra_bit_cells(drive, side); - uint32_t index_hole_pos = d86f_handler[drive].index_hole_pos(drive, side); - - fwrite(&side_flags, 1, 2, *f); - - if (d86f_has_extra_bit_cells(drive)) - fwrite(&extra_bit_cells, 1, 4, *f); - - fwrite(&index_hole_pos, 1, 4, *f); - - if (d86f_has_surface_desc(drive)) - fwrite(sa0, 1, d86f_get_array_size(drive, side) << 1, *f); - - fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, *f); -} - - -int -d86f_get_track_table_size(int drive) -{ - int temp = 2048; - - if (d86f_get_sides(drive) == 1) - temp >>= 1; - - return temp; -} - - -void -d86f_set_cur_track(int drive, int track) -{ - d86f_t *dev = d86f[drive]; - - dev->cur_track = track; -} - - -void -d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) -{ - d86f_t *dev = d86f[drive]; - int sides; - int side, thin_track; - int logical_track = 0; - sides = d86f_get_sides(drive); - uint32_t *tbl = dev->track_offset; - int fdd_side = fdd_get_head(drive); - - if (track_table) - tbl = track_table; - - if (! fdd_doublestep_40(drive)) { - for (side = 0; side < sides; side++) { - fdd_set_head(drive, side); - d86f_decompose_encoded_buffer(drive, side); - - for (thin_track = 0; thin_track < 2; thin_track++) { - if (sides == 2) - logical_track = ((dev->cur_track + thin_track) << 1) + side; - else - logical_track = dev->cur_track + thin_track; - - if (track_table && !tbl[logical_track]) { - fseek(*f, 0, SEEK_END); - track_table[logical_track] = ftell(*f); - } - if (tbl[logical_track]) { - fseek(*f, tbl[logical_track], SEEK_SET); - d86f_write_track(drive, f, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); - } - } - } - } else { - for (side = 0; side < sides; side++) { - fdd_set_head(drive, side); - if (sides == 2) - logical_track = (dev->cur_track << 1) + side; - else - logical_track = dev->cur_track; - - if (track_table && !tbl[logical_track]) { - fseek(*f, 0, SEEK_END); - track_table[logical_track] = ftell(*f); - } - - if (tbl[logical_track]) { - fseek(*f, tbl[logical_track], SEEK_SET); - d86f_write_track(drive, f, side, dev->track_encoded_data[side], dev->track_surface_data[side]); - } - } - } - - fdd_set_head(drive, fdd_side); -} - - -void -d86f_writeback(int drive) -{ - d86f_t *dev = d86f[drive]; - uint8_t header[32]; - int header_size; -#ifdef D86F_COMPRESS - uint32_t len; - int ret = 0; - FILE *cf; -#endif - header_size = d86f_header_size(drive); - - if (! dev->f) return; - - /* First write the track offsets table. */ - fseek(dev->f, 0, SEEK_SET); - fread(header, 1, header_size, dev->f); - - fseek(dev->f, 8, SEEK_SET); - fwrite(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f); - - d86f_write_tracks(drive, &dev->f, NULL); - -#ifdef D86F_COMPRESS - if (dev->is_compressed) { - /* The image is compressed. */ - - /* Open the original, compressed file. */ - cf = plat_fopen(dev->original_file_name, L"wb"); - - /* Write the header to the original file. */ - fwrite(header, 1, header_size, cf); - - fseek(dev->f, 0, SEEK_END); - len = ftell(dev->f); - len -= header_size; - - fseek(dev->f, header_size, SEEK_SET); - - /* Compress data from the temporary uncompressed file to the original, compressed file. */ - dev->filebuf = (uint8_t *) malloc(len); - dev->outbuf = (uint8_t *) malloc(len - 1); - fread(dev->filebuf, 1, len, dev->f); - ret = lzf_compress(dev->filebuf, len, dev->outbuf, len - 1); - - if (! ret) - d86f_log("86F: Error compressing file\n"); - - fwrite(dev->outbuf, 1, ret, cf); - free(dev->outbuf); - free(dev->filebuf); - } -#endif -} - - -void -d86f_stop(int drive) -{ - d86f_t *dev = d86f[drive]; - - dev->state = STATE_IDLE; -} - - -int -d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) -{ - d86f_t *dev = d86f[drive]; - - d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(d86f_fdc), d86f_get_bitcell_period(drive), rate, sector, track, side); - - dev->req_sector.id.c = track; - dev->req_sector.id.h = side; - if (sector == SECTOR_FIRST) { - dev->req_sector.id.r = 1; - } else if (sector == SECTOR_NEXT) { - dev->req_sector.id.r++; - } else { - dev->req_sector.id.r = sector; - } - dev->req_sector.id.n = sector_size; - - if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - fdc_noidam(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return 0; - } - - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->index_count = dev->error_condition = dev->satisfying_bytes = 0; - dev->id_found = 0; - dev->dma_over = 0; - - return 1; -} - - -void -d86f_readsector(int drive, int sector, int track, int side, int rate, int sector_size) -{ - d86f_t *dev = d86f[drive]; - int ret = 0; - - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (! ret) return; - - if (sector == SECTOR_FIRST) - dev->state = STATE_02_SPIN_TO_INDEX; - else if (sector == SECTOR_NEXT) - dev->state = STATE_02_FIND_ID; - else - dev->state = fdc_is_deleted(d86f_fdc) ? STATE_0C_FIND_ID : (fdc_is_verify(d86f_fdc) ? STATE_16_FIND_ID : STATE_06_FIND_ID); -} - - -void -d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size) -{ - d86f_t *dev = d86f[drive]; - int ret = 0; - - if (writeprot[drive]) { - fdc_writeprotect(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return; - } - - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (! ret) return; - - dev->state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; -} - - -void -d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size) -{ - d86f_t *dev = d86f[drive]; - int ret = 0; - - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (! ret) return; - - dev->state = STATE_11_FIND_ID; -} - - -void -d86f_readaddress(int drive, int side, int rate) -{ - d86f_t *dev = d86f[drive]; - - if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - fdc_noidam(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return; - } - - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->index_count = dev->error_condition = dev->satisfying_bytes = 0; - dev->id_found = 0; - dev->dma_over = 0; - - dev->state = STATE_0A_FIND_ID; -} - - -void -d86f_add_track(int drive, int track, int side) -{ - d86f_t *dev = d86f[drive]; - uint32_t array_size; - int logical_track; - - array_size = d86f_get_array_size(drive, side); - array_size <<= 1; - - if (d86f_get_sides(drive) == 2) { - logical_track = (track << 1) + side; - } else { - if (side) - return; - logical_track = track; - } - - if (! dev->track_offset[logical_track]) { - /* Track is absent from the file, let's add it. */ - dev->track_offset[logical_track] = dev->file_size; - - dev->file_size += (array_size + 6); - if (d86f_has_extra_bit_cells(drive)) - dev->file_size += 4; - if (d86f_has_surface_desc(drive)) - dev->file_size += array_size; - } -} - - -void -d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) -{ - d86f_t *dev = d86f[drive]; - uint32_t i = 0; - uint16_t temp, temp2; - uint32_t array_size; - - if (writeprot[drive]) { - fdc_writeprotect(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return; - } - - if (! d86f_can_format(drive)) { - fdc_cannotformat(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return; - } - - if (!side || (d86f_get_sides(drive) == 2)) { - if (! proxy) { - d86f_reset_index_hole_pos(drive, side); - - if (dev->cur_track > 256) { - fdc_writeprotect(d86f_fdc); - dev->state = STATE_IDLE; - dev->index_count = 0; - return; - } - - array_size = d86f_get_array_size(drive, side); - - if (d86f_has_surface_desc(drive)) { - /* Preserve the physical holes but get rid of the fuzzy bytes. */ - for (i = 0; i < array_size; i++) { - temp = dev->track_encoded_data[side][i] ^ 0xffff; - temp2 = dev->track_surface_data[side][i]; - temp &= temp2; - dev->track_surface_data[side][i] = temp; - } - } - - /* Zero the data buffer. */ - memset(dev->track_encoded_data[side], 0, array_size << 1); - - d86f_add_track(drive, dev->cur_track, side); - if (! fdd_doublestep_40(drive)) - d86f_add_track(drive, dev->cur_track + 1, side); - } - } - - dev->fill = fill; - - if (! proxy) { - dev->side_flags[side] = 0; - dev->side_flags[side] |= (fdd_getrpm(real_drive(d86f_fdc, drive)) == 360) ? 0x20 : 0; - dev->side_flags[side] |= fdc_get_bit_rate(d86f_fdc); - dev->side_flags[side] |= fdc_is_mfm(d86f_fdc) ? 8 : 0; - - dev->index_hole_pos[side] = 0; - } - - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->index_count = dev->error_condition = dev->satisfying_bytes = dev->sector_count = 0; - dev->dma_over = 0; - - if (!side || (d86f_get_sides(drive) == 2)) - dev->state = STATE_0D_SPIN_TO_INDEX; - else - dev->state = STATE_0D_NOP_SPIN_TO_INDEX; -} - - -void -d86f_proxy_format(int drive, int side, int rate, uint8_t fill) -{ - d86f_common_format(drive, side, rate, fill, 1); -} - - -void -d86f_format(int drive, int side, int rate, uint8_t fill) -{ - d86f_common_format(drive, side, rate, fill, 0); -} - - -void -d86f_common_handlers(int drive) -{ - drives[drive].readsector = d86f_readsector; - drives[drive].writesector = d86f_writesector; - drives[drive].comparesector =d86f_comparesector; - drives[drive].readaddress = d86f_readaddress; - drives[drive].byteperiod = d86f_byteperiod; - drives[drive].poll = d86f_poll; - drives[drive].format = d86f_proxy_format; - drives[drive].stop = d86f_stop; -} - - -int -d86f_export(int drive, wchar_t *fn) -{ - uint32_t tt[512]; - d86f_t *dev = d86f[drive]; - d86f_t *temp86; - FILE *f; - int tracks = 86; - int i; - int inc = 1; - uint32_t magic = 0x46423638; - uint16_t version = 0x020B; - uint16_t disk_flags = d86f_handler[drive].disk_flags(drive); - - memset(tt, 0, 512 * sizeof(uint32_t)); - - f = plat_fopen(fn, L"wb"); - if (!f) - return 0; - - /* Allocate a temporary drive for conversion. */ - temp86 = (d86f_t *)malloc(sizeof(d86f_t)); - memcpy(temp86, dev, sizeof(d86f_t)); - - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&disk_flags, 2, 1, f); - - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); - - /* In the case of a thick track drive, always increment track - by two, since two tracks are going to get output at once. */ - if (!fdd_doublestep_40(drive)) - inc = 2; - - for (i = 0; i < tracks; i += inc) { - if (inc == 2) - fdd_do_seek(drive, i >> 1); - else - fdd_do_seek(drive, i); - dev->cur_track = i; - d86f_write_tracks(drive, &f, tt); - } - - fclose(f); - - f = plat_fopen(fn, L"rb+"); - - fseek(f, 8, SEEK_SET); - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); - - fclose(f); - - fdd_do_seek(drive, fdd_current_track(drive)); - - /* Restore the drive from temp. */ - memcpy(dev, temp86, sizeof(d86f_t)); - free(temp86); - - return 1; -} - - -void -d86f_load(int drive, wchar_t *fn) -{ - d86f_t *dev = d86f[drive]; - uint32_t magic = 0; - uint32_t len = 0; - int i = 0, j = 0; -#ifdef D86F_COMPRESS - wchar_t temp_file_name[2048]; - uint16_t temp = 0; - FILE *tf; -#endif - - d86f_unregister(drive); - - writeprot[drive] = 0; - - dev->f = plat_fopen(fn, L"rb+"); - if (! dev->f) { - dev->f = plat_fopen(fn, L"rb"); - if (! dev->f) { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - writeprot[drive] = 1; - } - - if (ui_writeprot[drive]) { - writeprot[drive] = 1; - } - fwriteprot[drive] = writeprot[drive]; - - fseek(dev->f, 0, SEEK_END); - len = ftell(dev->f); - fseek(dev->f, 0, SEEK_SET); - - fread(&magic, 4, 1, dev->f); - - if (len < 16) { - /* File is WAY too small, abort. */ - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - if ((magic != 0x46423638) && (magic != 0x66623638)) { - /* File is not of the valid format, abort. */ - d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); - fclose(dev->f); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - fread(&(dev->version), 2, 1, dev->f); - if (dev->version != D86FVER) { - /* File is not of a recognized format version, abort. */ - if (dev->version == 0x0063) { - d86f_log("86F: File has emulator-internal version 0.99, this version is not valid in a file\n"); - } else if ((dev->version >= 0x0100) && (dev->version < D86FVER)) { - d86f_log("86F: No longer supported development file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); - } else { - d86f_log("86F: Unrecognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); - } - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } else { - d86f_log("86F: Recognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); - } - - fread(&(dev->disk_flags), 2, 1, dev->f); - - if (d86f_has_surface_desc(drive)) { - for (i = 0; i < 2; i++) - dev->track_surface_data[i] = (uint16_t *) malloc(53048 * sizeof(uint16_t)); - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) - dev->thin_track_surface_data[i][j] = (uint16_t *) malloc(53048 * sizeof(uint16_t)); - } - } - -#ifdef D86F_COMPRESS - dev->is_compressed = (magic == 0x66623638) ? 1 : 0; - if ((len < 51052) && !dev->is_compressed) { -#else - if (len < 51052) { -#endif - /* File too small, abort. */ - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - -#ifdef DO_CRC64 - fseek(dev->f, 8, SEEK_SET); - fread(&read_crc64, 1, 8, dev->f); - - fseek(dev->f, 0, SEEK_SET); - - crc64 = 0xffffffffffffffff; - - dev->filebuf = malloc(len); - fread(dev->filebuf, 1, len, dev->f); - *(uint64_t *) &(dev->filebuf[8]) = 0xffffffffffffffff; - crc64 = (uint64_t) crc64speed(0, dev->filebuf, len); - free(dev->filebuf); - - if (crc64 != read_crc64) { - d86f_log("86F: CRC64 error\n"); - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } -#endif - -#ifdef D86F_COMPRESS - if (dev->is_compressed) { - memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 256); - memcpy(dev->original_file_name, fn, (wcslen(fn) << 1) + 2); - - fclose(dev->f); - dev->f = NULL; - - dev->f = plat_fopen(temp_file_name, L"wb"); - if (! dev->f) { - d86f_log("86F: Unable to create temporary decompressed file\n"); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - tf = plat_fopen(fn, L"rb"); - - for (i = 0; i < 8; i++) { - fread(&temp, 1, 2, tf); - fwrite(&temp, 1, 2, dev->f); - } - - dev->filebuf = (uint8_t *) malloc(len); - dev->outbuf = (uint8_t *) malloc(67108864); - fread(dev->filebuf, 1, len, tf); - temp = lzf_decompress(dev->filebuf, len, dev->outbuf, 67108864); - if (temp) { - fwrite(dev->outbuf, 1, temp, dev->f); - } - free(dev->outbuf); - free(dev->filebuf); - - fclose(tf); - fclose(dev->f); - dev->f = NULL; - - if (! temp) { - d86f_log("86F: Error decompressing file\n"); - plat_remove(temp_file_name); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - dev->f = plat_fopen(temp_file_name, L"rb+"); - } -#endif - - if (dev->disk_flags & 0x100) { - /* Zoned disk. */ - d86f_log("86F: Disk is zoned (Apple or Sony)\n"); - fclose(dev->f); - dev->f = NULL; -#ifdef D86F_COMPRESS - if (dev->is_compressed) - plat_remove(temp_file_name); -#endif - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - if (dev->disk_flags & 0x600) { - /* Zone type is not 0 but the disk is fixed-RPM. */ - d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); - fclose(dev->f); - dev->f = NULL; -#ifdef D86F_COMPRESS - if (dev->is_compressed) - plat_remove(temp_file_name); -#endif - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - return; - } - - if (!writeprot[drive]) { - writeprot[drive] = (dev->disk_flags & 0x10) ? 1 : 0; - fwriteprot[drive] = writeprot[drive]; - } - - if (writeprot[drive]) { - fclose(dev->f); - dev->f = NULL; - -#ifdef D86F_COMPRESS - if (dev->is_compressed) - dev->f = plat_fopen(temp_file_name, L"rb"); - else -#endif - dev->f = plat_fopen(fn, L"rb"); - } - - /* OK, set the drive data, other code needs it. */ - d86f[drive] = dev; - - fseek(dev->f, 8, SEEK_SET); - - fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f); - - if (! (dev->track_offset[0])) { - /* File has no track 0 side 0, abort. */ - d86f_log("86F: No Track 0 side 0\n"); - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - d86f[drive] = NULL; - return; - } - - if ((d86f_get_sides(drive) == 2) && !(dev->track_offset[1])) { - /* File is 2-sided but has no track 0 side 1, abort. */ - d86f_log("86F: No Track 0 side 1\n"); - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - free(dev); - d86f[drive] = NULL; - return; - } - - /* Load track 0 flags as default. */ - fseek(dev->f, dev->track_offset[0], SEEK_SET); - fread(&(dev->side_flags[0]), 2, 1, dev->f); - if (dev->disk_flags & 0x80) { - fread(&(dev->extra_bit_cells[0]), 4, 1, dev->f); - if (dev->extra_bit_cells[0] < -32768) dev->extra_bit_cells[0] = -32768; - if (dev->extra_bit_cells[0] > 32768) dev->extra_bit_cells[0] = 32768; - } else { - dev->extra_bit_cells[0] = 0; - } - - if (d86f_get_sides(drive) == 2) { - fseek(dev->f, dev->track_offset[1], SEEK_SET); - fread(&(dev->side_flags[1]), 2, 1, dev->f); - if (dev->disk_flags & 0x80) { - fread(&(dev->extra_bit_cells[1]), 4, 1, dev->f); - if (dev->extra_bit_cells[1] < -32768) dev->extra_bit_cells[1] = -32768; - if (dev->extra_bit_cells[1] > 32768) dev->extra_bit_cells[1] = 32768; - } else { - dev->extra_bit_cells[0] = 0; - } - } else { - switch ((dev->disk_flags >> 1) >> 3) { - case 0: - default: - dev->side_flags[1] = 0x0a; - break; - - case 1: - dev->side_flags[1] = 0x00; - break; - - case 2: - case 3: - dev->side_flags[1] = 0x03; - break; - } - - dev->extra_bit_cells[1] = 0; - } - - fseek(dev->f, 0, SEEK_END); - dev->file_size = ftell(dev->f); - - fseek(dev->f, 0, SEEK_SET); - - d86f_register_86f(drive); - - drives[drive].seek = d86f_seek; - d86f_common_handlers(drive); - drives[drive].format = d86f_format; - -#ifdef D86F_COMPRESS - d86f_log("86F: Disk is %scompressed and does%s have surface description data\n", - dev->is_compressed ? "" : "not ", - d86f_has_surface_desc(drive) ? "" : " not"); -#else - d86f_log("86F: Disk does%s have surface description data\n", - d86f_has_surface_desc(drive) ? "" : " not"); -#endif -} - - -void -d86f_init(void) -{ - int i; - - setup_crc(0x1021); - - for (i = 0; i < FDD_NUM; i++) - d86f[i] = NULL; -} - - -void -d86f_set_fdc(void *fdc) -{ - d86f_fdc = (fdc_t *) fdc; -} - - -void -d86f_close(int drive) -{ - int i, j; - - wchar_t temp_file_name[2048]; - d86f_t *dev = d86f[drive]; - - /* Make sure the drive is alive. */ - if (dev == NULL) return; - - memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); - - if (d86f_has_surface_desc(drive)) { - for (i = 0; i < 2; i++) { - if (dev->track_surface_data[i]) { - free(dev->track_surface_data[i]); - dev->track_surface_data[i] = NULL; - } - } - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - if (dev->thin_track_surface_data[i][j]) { - free(dev->thin_track_surface_data[i][j]); - dev->thin_track_surface_data[i][j] = NULL; - } - } - } - } - - if (dev->f) { - fclose(dev->f); - dev->f = NULL; - } -#ifdef D86F_COMPRESS - if (dev->is_compressed) - plat_remove(temp_file_name); -#endif -} - - -/* When an FDD is mounted, set up the D86F data structures. */ -void -d86f_setup(int drive) -{ - d86f_t *dev; - - /* Allocate a drive structure. */ - dev = (d86f_t *)malloc(sizeof(d86f_t)); - memset(dev, 0x00, sizeof(d86f_t)); - dev->state = STATE_IDLE; - - dev->last_side_sector[0] = NULL; - dev->last_side_sector[1] = NULL; - - /* Set the drive as active. */ - d86f[drive] = dev; -} - - -/* If an FDD is unmounted, unlink the D86F data structures. */ -void -d86f_destroy(int drive) -{ - int i, j; - - d86f_t *dev = d86f[drive]; - - if (dev == NULL) return; - - if (d86f_has_surface_desc(drive)) { - for (i = 0; i < 2; i++) { - if (dev->track_surface_data[i]) { - free(dev->track_surface_data[i]); - dev->track_surface_data[i] = NULL; - } - } - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - if (dev->thin_track_surface_data[i][j]) { - free(dev->thin_track_surface_data[i][j]); - dev->thin_track_surface_data[i][j] = NULL; - } - } - } - } - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - free(d86f[drive]); - d86f[drive] = NULL; -} diff --git a/src - Cópia/floppy/fdd_86f.h b/src - Cópia/floppy/fdd_86f.h deleted file mode 100644 index 8242f5bb7..000000000 --- a/src - Cópia/floppy/fdd_86f.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 86F floppy image format. - * - * Version: @(#)floppy_86f.h 1.0.4 2018/03/17 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef EMU_FLOPPY_86F_H -# define EMU_FLOPPY_86F_H - - -#define D86FVER 0x020B - - -extern void d86f_init(void); -extern void d86f_load(int drive, wchar_t *fn); -extern void d86f_close(int drive); -extern void d86f_seek(int drive, int track); -extern int d86f_hole(int drive); -extern double d86f_byteperiod(int drive); -extern void d86f_stop(int drive); -extern void d86f_poll(int drive); -extern int d86f_realtrack(int track, int drive); -extern void d86f_reset(int drive, int side); -extern void d86f_readsector(int drive, int sector, int track, int side, int density, int sector_size); -extern void d86f_writesector(int drive, int sector, int track, int side, int density, int sector_size); -extern void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size); -extern void d86f_readaddress(int drive, int side, int density); -extern void d86f_format(int drive, int side, int density, uint8_t fill); - -extern void d86f_prepare_track_layout(int drive, int side); -extern void d86f_set_version(int drive, uint16_t version); -extern uint16_t d86f_side_flags(int drive); -extern uint16_t d86f_track_flags(int drive); -extern void d86f_initialize_last_sector_id(int drive, int c, int h, - int r, int n); -extern void d86f_initialize_linked_lists(int drive); -extern void d86f_destroy_linked_lists(int drive, int side); - -#define length_gap0 80 -#define length_gap1 50 -#define length_sync 12 -#define length_am 4 -#define length_crc 2 - -#define IBM -#define MFM -#ifdef IBM -#define pre_gap1 length_gap0 + length_sync + length_am -#else -#define pre_gap1 0 -#endif - -#define pre_track pre_gap1 + length_gap1 -#define pre_gap length_sync + length_am + 4 + length_crc -#define pre_data length_sync + length_am -#define post_gap length_crc - - -#endif /*EMU_FLOPPY_86F_H*/ diff --git a/src - Cópia/floppy/fdd_common.c b/src - Cópia/floppy/fdd_common.c deleted file mode 100644 index 5638b0565..000000000 --- a/src - Cópia/floppy/fdd_common.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * 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. - * - * Shared code for all the floppy modules. - * - * Version: @(#)fdd_common.c 1.0.2 2018/03/16 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "fdd.h" -#include "fdd_common.h" - - -const uint8_t fdd_holes[6] = { 0, 0, 0, 1, 1, 2 }; - -const uint8_t fdd_rates[6] = { 2, 2, 1, 4, 0, 3 }; - -const double fdd_bit_rates_300[6] = { - (250.0 * 300.0) / 360.0, - 250.0, - 300.0, - (500.0 * 300.0) / 360.0, - 500.0, - 1000.0 -}; - -/* - * First dimension is possible sector sizes (0 = 128, 7 = 16384), - * second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). - * - * Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM - * single-RPM 5.25" drive by setting the rate to 250 kbps. - * - * Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM - * single-RPM drive by setting the rate to 300 kbps. - */ -const uint8_t fdd_max_sectors[8][6] = { - { 26, 31, 38, 53, 64, 118 }, /* 128 */ - { 15, 19, 23, 32, 38, 73 }, /* 256 */ - { 7, 10, 12, 17, 22, 41 }, /* 512 */ - { 3, 5, 6, 9, 11, 22 }, /* 1024 */ - { 2, 2, 3, 4, 5, 11 }, /* 2048 */ - { 1, 1, 1, 2, 2, 5 }, /* 4096 */ - { 0, 0, 0, 1, 1, 3 }, /* 8192 */ - { 0, 0, 0, 0, 0, 1 } /* 16384 */ -}; - -const uint8_t fdd_dmf_r[21] = { - 12,2,13,3,14,4,15,5,16,6,17,7,18,8,19,9,20,10,21,11,1 -}; - - -static const uint8_t fdd_gap3_sizes[5][8][48] = { - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][0] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][1] */ - 0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][2] */ - 0x00,0x00,0x6C,0x48,0x2A,0x08,0x02,0x01, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x83,0x26,0x00,0x00,0x00,0x00, /* [0][3] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][4] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][5] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][6] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][7] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][0] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][1] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x54,0x1C,0x0E,0x00,0x00, /* [1][2] */ - 0x00,0x00,0x6C,0x48,0x2A,0x08,0x02,0x01, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x06, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][3] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][4] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][5] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][6] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [1][7] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][0] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x32,0x0C,0x00,0x00,0x00,0x36, /* [2][1] */ - 0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x58,0x50,0x2E,0x00,0x00,0x00,0x00,0x00, /* [2][2] */ - 0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0xF0,0x74,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][3] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][4] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][5] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][6] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [2][7] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][0] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][1] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][2] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x53,0x4E,0x3D,0x2C, - 0x1C,0x0D,0x02,0x00,0x00,0x00,0x01,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][3] */ - 0x00,0x00,0xF7,0xAF,0x6F,0x55,0x1F,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][4] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][5] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][6] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [3][7] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][0] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][1] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x92,0x54, /* [4][2] */ - 0x38,0x23,0x00,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x74,0x24,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][3] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][4] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][5] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][6] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [4][7] */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - } -}; - - -int -fdd_get_gap3_size(int rate, int size, int sector) -{ - return(fdd_gap3_sizes[rate][size][sector]); -} - - -uint8_t -fdd_sector_size_code(int size) -{ - int ret = 2; - - switch(size) { - case 128: - ret = 0; - break; - - case 256: - ret = 1; - break; - - case 512: - ret = 2; - break; - - case 1024: - ret = 3; - break; - - case 2048: - ret = 4; - break; - - case 4096: - ret = 5; - break; - - case 8192: - ret = 6; - break; - - case 16384: - ret = 7; - break; - - default: - break; - } - - return(ret); -} - - -int -fdd_sector_code_size(uint8_t code) -{ - return(128 << code); -} - - -int -fdd_bps_valid(uint16_t bps) -{ - int i; - - for (i=0; i<=8; i++) { - if (bps == (128 << i)) { - return 1; - } - } - - return(0); -} - - -int -fdd_interleave(int sector, int skew, int spt) -{ - uint32_t add = (spt & 1); - uint32_t adjust = (spt >> 1); - uint32_t adjusted_r; - uint32_t skewed_i; - - skewed_i = (sector + skew) % spt; - adjusted_r = (skewed_i >> 1) + 1; - if (skewed_i & 1) { - adjusted_r += (adjust + add); - } - - return(adjusted_r); -} diff --git a/src - Cópia/floppy/fdd_common.h b/src - Cópia/floppy/fdd_common.h deleted file mode 100644 index 02ff78375..000000000 --- a/src - Cópia/floppy/fdd_common.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * - * Shared code for all the floppy modules. - * - * Version: @(#)fdd_common.h 1.0.2 2018/03/16 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * 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 FDD_COMMON_H -# define FDD_COMMON_H - - -extern const uint8_t fdd_holes[6]; -extern const uint8_t fdd_rates[6]; -extern const double fdd_bit_rates_300[6]; -extern const uint8_t fdd_max_sectors[8][6]; -extern const uint8_t fdd_dmf_r[21]; - - -extern int fdd_get_gap3_size(int rate, int size, int sector); -extern uint8_t fdd_sector_size_code(int size); -extern int fdd_sector_code_size(uint8_t code); -extern int fdd_bps_valid(uint16_t bps); -extern int fdd_interleave(int sector, int skew, int spt); - - -#endif /*FDD_COMMON_H*/ diff --git a/src - Cópia/floppy/fdd_fdi.c b/src - Cópia/floppy/fdd_fdi.c deleted file mode 100644 index a8c7a0dce..000000000 --- a/src - Cópia/floppy/fdd_fdi.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * 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. - * - * Implementation of the FDI floppy stream image format - * interface to the FDI2RAW module. - * - * Version: @(#)fdd_fdi.c 1.0.3 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "fdd.h" -#include "fdd_86f.h" -#include "fdd_img.h" -#include "fdd_fdi.h" -#include "fdc.h" -#include "fdi2raw.h" - - -typedef struct { - FILE *f; - FDI *h; - - int lasttrack; - int sides; - int track; - int tracklen[2][4]; - int trackindex[2][4]; - - uint8_t track_data[2][4][256*1024]; - uint8_t track_timing[2][4][256*1024]; -} fdi_t; - - -static fdi_t *fdi[FDD_NUM]; -static fdc_t *fdi_fdc; - - -#ifdef ENABLE_FDI_LOG -int fdi_do_log = ENABLE_FDI_LOG; -#endif - - -static void -fdi_log(const char *fmt, ...) -{ -#ifdef ENABLE_FDI_LOG - va_list ap; - - if (fdi_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static uint16_t -disk_flags(int drive) -{ - fdi_t *dev = fdi[drive]; - uint16_t temp_disk_flags = 0x80; /* We ALWAYS claim to have extra bit cells, even if the actual amount is 0. */ - - switch (fdi2raw_get_bit_rate(dev->h)) { - case 500: - temp_disk_flags |= 2; - break; - - case 300: - case 250: - temp_disk_flags |= 0; - break; - - case 1000: - temp_disk_flags |= 4; - break; - - default: - temp_disk_flags |= 0; - } - - if (dev->sides == 2) - temp_disk_flags |= 8; - - /* - * Tell the 86F handler that we will handle our - * data to handle it in reverse byte endianness. - */ - temp_disk_flags |= 0x800; - - return(temp_disk_flags); -} - - -static uint16_t -side_flags(int drive) -{ - fdi_t *dev = fdi[drive]; - uint16_t temp_side_flags = 0; - - switch (fdi2raw_get_bit_rate(dev->h)) { - case 500: - temp_side_flags = 0; - break; - - case 300: - temp_side_flags = 1; - break; - - case 250: - temp_side_flags = 2; - break; - - case 1000: - temp_side_flags = 3; - break; - - default: - temp_side_flags = 2; - } - - if (fdi2raw_get_rotation(dev->h) == 360) - temp_side_flags |= 0x20; - - /* - * Set the encoding value to match that provided by the FDC. - * Then if it's wrong, it will sector not found anyway. - */ - temp_side_flags |= 0x08; - - return(temp_side_flags); -} - - -static int -fdi_density(void) -{ - if (! fdc_is_mfm(fdi_fdc)) return(0); - - switch (fdc_get_bit_rate(fdi_fdc)) { - case 0: - return(2); - - case 1: - return(1); - - case 2: - return(1); - - case 3: - case 5: - return(3); - - default: - break; - } - - return(1); -} - - -static int32_t -extra_bit_cells(int drive, int side) -{ - fdi_t *dev = fdi[drive]; - int density = 0; - int raw_size = 0; - int is_300_rpm = 0; - - density = fdi_density(); - - is_300_rpm = (fdd_getrpm(drive) == 300); - - switch (fdc_get_bit_rate(fdi_fdc)) { - case 0: - raw_size = is_300_rpm ? 200000 : 166666; - break; - - case 1: - raw_size = is_300_rpm ? 120000 : 100000; - break; - - case 2: - raw_size = is_300_rpm ? 100000 : 83333; - break; - - case 3: - case 5: - raw_size = is_300_rpm ? 400000 : 333333; - break; - - default: - raw_size = is_300_rpm ? 100000 : 83333; - } - - return((dev->tracklen[side][density] - raw_size)); -} - - -static void -read_revolution(int drive) -{ - fdi_t *dev = fdi[drive]; - int c, den, side; - int track = dev->track; - - if (track > dev->lasttrack) { - for (den = 0; den < 4; den++) { - memset(dev->track_data[0][den], 0, 106096); - memset(dev->track_data[1][den], 0, 106096); - dev->tracklen[0][den] = dev->tracklen[1][den] = 100000; - } - return; - } - - for (den = 0; den < 4; den++) { - for (side = 0; side < dev->sides; side++) { - c = fdi2raw_loadtrack(dev->h, - (uint16_t *)dev->track_data[side][den], - (uint16_t *)dev->track_timing[side][den], - (track * dev->sides) + side, - &dev->tracklen[side][den], - &dev->trackindex[side][den], NULL, den); - if (! c) - memset(dev->track_data[side][den], 0, dev->tracklen[side][den]); - } - - if (dev->sides == 1) { - memset(dev->track_data[1][den], 0, 106096); - dev->tracklen[1][den] = 100000; - } - } -} - - -static uint32_t -index_hole_pos(int drive, int side) -{ - fdi_t *dev = fdi[drive]; - int density; - - density = fdi_density(); - - return(dev->trackindex[side][density]); -} - - -static uint32_t -get_raw_size(int drive, int side) -{ - fdi_t *dev = fdi[drive]; - int density; - - density = fdi_density(); - - return(dev->tracklen[side][density]); -} - - -static uint16_t * -encoded_data(int drive, int side) -{ - fdi_t *dev = fdi[drive]; - int density = 0; - - density = fdi_density(); - - return((uint16_t *)dev->track_data[side][density]); -} - - -void -fdi_seek(int drive, int track) -{ - fdi_t *dev = fdi[drive]; - - if (fdd_doublestep_40(drive)) { - if (fdi2raw_get_tpi(dev->h) < 2) - track /= 2; - } - - d86f_set_cur_track(drive, track); - - if (dev->f == NULL) return; - - if (track < 0) - track = 0; - -#if 0 - if (track > dev->lasttrack) - track = dev->lasttrack - 1; -#endif - - dev->track = track; - - read_revolution(drive); -} - - -void -fdi_load(int drive, wchar_t *fn) -{ - char header[26]; - fdi_t *dev; - - writeprot[drive] = fwriteprot[drive] = 1; - - /* Allocate a drive block. */ - dev = (fdi_t *)malloc(sizeof(fdi_t)); - memset(dev, 0x00, sizeof(fdi_t)); - - dev->f = plat_fopen(fn, L"rb"); - if (dev == NULL) { - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - d86f_unregister(drive); - - fread(header, 1, 25, dev->f); - fseek(dev->f, 0, SEEK_SET); - header[25] = 0; - if (strcmp(header, "Formatted Disk Image file") != 0) { - /* This is a Japanese FDI file. */ - fdi_log("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n"); - fclose(dev->f); - free(dev); - img_load(drive, fn); - return; - } - - /* Set up the drive unit. */ - fdi[drive] = dev; - - dev->h = fdi2raw_header(dev->f); - dev->lasttrack = fdi2raw_get_last_track(dev->h); - dev->sides = fdi2raw_get_last_head(dev->h) + 1; - - /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = null_set_sector; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = extra_bit_cells; - d86f_handler[drive].encoded_data = encoded_data; - d86f_handler[drive].read_revolution = read_revolution; - d86f_handler[drive].index_hole_pos = index_hole_pos; - d86f_handler[drive].get_raw_size = get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, D86FVER); - - d86f_common_handlers(drive); - - drives[drive].seek = fdi_seek; - - fdi_log("Loaded as FDI\n"); -} - - -void -fdi_close(int drive) -{ - fdi_t *dev = fdi[drive]; - - if (dev == NULL) return; - - d86f_unregister(drive); - - drives[drive].seek = NULL; - - if (dev->h) - fdi2raw_header_free(dev->h); - - if (dev->f) - fclose(dev->f); - - /* Release the memory. */ - free(dev); - fdi[drive] = NULL; -} - - -void -fdi_set_fdc(void *fdc) -{ - fdi_fdc = (fdc_t *)fdc; -} diff --git a/src - Cópia/floppy/fdd_fdi.h b/src - Cópia/floppy/fdd_fdi.h deleted file mode 100644 index 4808ecb03..000000000 --- a/src - Cópia/floppy/fdd_fdi.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Implementation of the FDI floppy stream image format - * interface to the FDI2RAW module. - * - * Version: @(#)floppy_fdi.h 1.0.2 2018/03/17 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_FLOPPY_FDI_H -# define EMU_FLOPPY_FDI_H - - -extern void fdi_seek(int drive, int track); -extern void fdi_load(int drive, wchar_t *fn); -extern void fdi_close(int drive); - - -#endif /*EMU_FLOPPY_FDI_H*/ diff --git a/src - Cópia/floppy/fdd_imd.c b/src - Cópia/floppy/fdd_imd.c deleted file mode 100644 index 9e690a479..000000000 --- a/src - Cópia/floppy/fdd_imd.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * 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. - * - * Implementation of the IMD floppy image format. - * - * Version: @(#)fdd_imd.c 1.0.7 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "fdd.h" -#include "fdd_imd.h" -#include "fdc.h" - - -typedef struct { - uint8_t is_present; - uint32_t file_offs; - uint8_t params[5]; - uint32_t r_map_offs; - uint32_t c_map_offs; - uint32_t h_map_offs; - uint32_t n_map_offs; - uint32_t data_offs; - uint32_t sector_data_offs[255]; - uint32_t sector_data_size[255]; - uint32_t gap3_len; - uint16_t side_flags; -} imd_track_t; - -typedef struct { - FILE *f; - char *buffer; - uint32_t start_offs; - int track_count, sides; - int track; - uint16_t disk_flags; - int track_width; - imd_track_t tracks[256][2]; - uint16_t current_side_flags[2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; - char *current_data[2]; - uint8_t track_buffer[2][25000]; -} imd_t; - - -static imd_t *imd[FDD_NUM]; -static fdc_t *imd_fdc; - - -#ifdef ENABLE_IMD_LOG -int imd_do_log = ENABLE_IMD_LOG; -#endif - - -static void -imd_log(const char *fmt, ...) -{ -#ifdef ENABLE_IMD_LOG - va_list ap; - - if (imd_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static uint32_t -get_raw_tsize(int side_flags, int slower_rpm) -{ - uint32_t size; - - switch(side_flags & 0x27) { - case 0x22: - size = slower_rpm ? 5314 : 5208; - break; - - default: - case 0x02: - case 0x21: - size = slower_rpm ? 6375 : 6250; - break; - - case 0x01: - size = slower_rpm ? 7650 : 7500; - break; - - case 0x20: - size = slower_rpm ? 10629 : 10416; - break; - - case 0x00: - size = slower_rpm ? 12750 : 12500; - break; - - case 0x23: - size = slower_rpm ? 21258 : 20833; - break; - - case 0x03: - size = slower_rpm ? 25500 : 25000; - break; - - case 0x25: - size = slower_rpm ? 42517 : 41666; - break; - - case 0x05: - size = slower_rpm ? 51000 : 50000; - break; - } - - return(size); -} - - -static int -track_is_xdf(int drive, int side, int track) -{ - imd_t *dev = imd[drive]; - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; - uint8_t *r_map; - uint8_t *n_map; - char *data_base; - char *cur_data; - - effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - - for (i = 0; i < 256; i++) - dev->xdf_ordered_pos[i][side] = 0; - - if (dev->tracks[track][side].params[2] & 0xC0) return(0); - - if ((dev->tracks[track][side].params[3] != 16) && - (dev->tracks[track][side].params[3] != 19)) return(0); - - r_map = (uint8_t *)(dev->buffer + dev->tracks[track][side].r_map_offs); - data_base = dev->buffer + dev->tracks[track][side].data_offs; - - if (! track) { - if (dev->tracks[track][side].params[4] != 2) return(0); - - if (! side) { - max_high_id = (dev->tracks[track][side].params[3] == 19) ? 0x8B : 0x88; - expected_high_count = (dev->tracks[track][side].params[3] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } else { - max_high_id = (dev->tracks[track][side].params[3] == 19) ? 0x93 : 0x90; - expected_high_count = (dev->tracks[track][side].params[3] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } - - for (i = 0; i < dev->tracks[track][side].params[3]; i++) { - if ((r_map[i] >= 0x81) && (r_map[i] <= max_high_id)) { - high_sectors++; - dev->xdf_ordered_pos[(int) r_map[i]][side] = i; - } - if ((r_map[i] >= 0x01) && (r_map[i] <= 0x08)) { - low_sectors++; - dev->xdf_ordered_pos[(int) r_map[i]][side] = i; - } - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { - dev->current_side_flags[side] = (dev->tracks[track][side].params[3] == 19) ? 0x08 : 0x28; - return((dev->tracks[track][side].params[3] == 19) ? 2 : 1); - } - return(0); - } - } else { - if (dev->tracks[track][side].params[4] != 0xFF) return(0); - - n_map = (uint8_t *) (dev->buffer + dev->tracks[track][side].n_map_offs); - - cur_data = data_base; - for (i = 0; i < dev->tracks[track][side].params[3]; i++) { - effective_sectors++; - if (!(r_map[i]) && !(n_map[i])) - effective_sectors--; - - if (r_map[i] == (n_map[i] | 0x80)) { - xdf_sectors++; - dev->xdf_ordered_pos[(int) r_map[i]][side] = i; - } - cur_data += (128 << ((uint32_t) n_map[i])); - } - - if ((effective_sectors == 3) && (xdf_sectors == 3)) { - dev->current_side_flags[side] = 0x28; - return(1); /* 5.25" 2HD XDF */ - } - - if ((effective_sectors == 4) && (xdf_sectors == 4)) { - dev->current_side_flags[side] = 0x08; - return(2); /* 3.5" 2HD XDF */ - } - - return(0); - } - - return(0); -} - - -static int -track_is_interleave(int drive, int side, int track) -{ - imd_t *dev = imd[drive]; - int i, effective_sectors; - char *r_map; - int track_spt; - - effective_sectors = 0; - - for (i = 0; i < 256; i++) - dev->interleave_ordered_pos[i][side] = 0; - - track_spt = dev->tracks[track][side].params[3]; - - r_map = dev->buffer + dev->tracks[track][side].r_map_offs; - - if (dev->tracks[track][side].params[2] & 0xC0) return(0); - - if (track_spt != 21) return(0); - - if (dev->tracks[track][side].params[4] != 2) return(0); - - for (i = 0; i < track_spt; i++) { - if ((r_map[i] >= 1) && (r_map[i] <= track_spt)) { - effective_sectors++; - dev->interleave_ordered_pos[(int) r_map[i]][side] = i; - } - } - - if (effective_sectors == track_spt) return(1); - - return(0); -} - - -static void -sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, int len) -{ - imd_t *dev = imd[drive]; - int type = dev->buffer[dev->tracks[track][side].sector_data_offs[sector]]; - - if (type == 0) - memset(buffer, 0x00, len); - else { - if (type & 1) - memcpy(buffer, &(dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1]), len); - else - memset(buffer, dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1], len); - } -} - - -static void -imd_seek(int drive, int track) -{ - uint32_t track_buf_pos[2] = { 0, 0 }; - uint8_t id[4] = { 0, 0, 0, 0 }; - uint8_t type, deleted, bad_crc; - imd_t *dev = imd[drive]; - int sector, current_pos; - int side, c = 0, h, n; - int ssize = 512; - int track_rate = 0; - int track_gap2 = 22; - int track_gap3 = 12; - int xdf_type = 0; - int interleave_type = 0; - int is_trackx = 0; - int xdf_spt = 0; - int xdf_sector = 0; - int ordered_pos = 0; - int real_sector = 0; - int actual_sector = 0; - char *c_map = NULL; - char *h_map = NULL; - char *r_map; - char *n_map = NULL; - uint8_t *data; - - if (dev->f == NULL) return; - - if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; - - d86f_set_cur_track(drive, track); - - is_trackx = (track == 0) ? 0 : 1; - - dev->track = track; - - dev->current_side_flags[0] = dev->tracks[track][0].side_flags; - dev->current_side_flags[1] = dev->tracks[track][1].side_flags; - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > dev->track_count) { - d86f_zero_track(drive); - return; - } - - for (side = 0; side < dev->sides; side++) { - track_rate = dev->current_side_flags[side] & 7; - if (!track_rate && (dev->current_side_flags[side] & 0x20)) - track_rate = 4; - if ((dev->current_side_flags[side] & 0x27) == 0x21) - track_rate = 2; - - r_map = dev->buffer + dev->tracks[track][side].r_map_offs; - h = dev->tracks[track][side].params[2]; - if (h & 0x80) - c_map = dev->buffer + dev->tracks[track][side].c_map_offs; - else - c = dev->tracks[track][side].params[1]; - - if (h & 0x40) - h_map = dev->buffer + dev->tracks[track][side].h_map_offs; - - n = dev->tracks[track][side].params[4]; - if (n == 0xFF) { - n_map = dev->buffer + dev->tracks[track][side].n_map_offs; - track_gap3 = gap3_sizes[track_rate][(int) n_map[0]][dev->tracks[track][side].params[3]]; - } else { - track_gap3 = gap3_sizes[track_rate][n][dev->tracks[track][side].params[3]]; - } - - if (! track_gap3) - track_gap3 = dev->tracks[track][side].gap3_len; - - xdf_type = track_is_xdf(drive, side, track); - - interleave_type = track_is_interleave(drive, side, track); - - current_pos = d86f_prepare_pretrack(drive, side, 0); - - if (! xdf_type) { - for (sector = 0; sector < dev->tracks[track][side].params[3]; sector++) { - if (interleave_type == 0) { - real_sector = r_map[sector]; - actual_sector = sector; - } else { - real_sector = dmf_r[sector]; - actual_sector = dev->interleave_ordered_pos[real_sector][side]; - } - id[0] = (h & 0x80) ? c_map[actual_sector] : c; - id[1] = (h & 0x40) ? h_map[actual_sector] : (h & 1); - id[2] = real_sector; - id[3] = (n == 0xFF) ? n_map[actual_sector] : n; - ssize = 128 << ((uint32_t) id[3]); - data = dev->track_buffer[side] + track_buf_pos[side]; - type = dev->buffer[dev->tracks[track][side].sector_data_offs[actual_sector]]; - type = (type >> 1) & 7; - deleted = bad_crc = 0; - if ((type == 2) || (type == 4)) deleted = 1; - if ((type == 3) || (type == 4)) bad_crc = 1; - - sector_to_buffer(drive, track, side, data, actual_sector, ssize); - current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, 22, track_gap3, deleted, bad_crc); - track_buf_pos[side] += ssize; - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } else { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ssize = 128 << ((uint32_t) id[3]); - ordered_pos = dev->xdf_ordered_pos[id[2]][side]; - - data = dev->track_buffer[side] + track_buf_pos[side]; - type = dev->buffer[dev->tracks[track][side].sector_data_offs[ordered_pos]]; - type = (type >> 1) & 7; - deleted = bad_crc = 0; - if ((type == 2) || (type == 4)) deleted = 1; - if ((type == 3) || (type == 4)) bad_crc = 1; - sector_to_buffer(drive, track, side, data, ordered_pos, ssize); - - if (is_trackx) - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], deleted, bad_crc); - else - current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], deleted, bad_crc); - - track_buf_pos[side] += ssize; - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } - } -} - - -static uint16_t -disk_flags(int drive) -{ - imd_t *dev = imd[drive]; - - return(dev->disk_flags); -} - - -static uint16_t -side_flags(int drive) -{ - imd_t *dev = imd[drive]; - int side = 0; - uint16_t sflags = 0; - - side = fdd_get_head(drive); - sflags = dev->current_side_flags[side]; - - return(sflags); -} - - -static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - imd_t *dev = imd[drive]; - int track = dev->track; - int i, sc, sh, sn; - char *c_map = NULL, *h_map = NULL, *r_map = NULL, *n_map = NULL; - uint8_t id[4] = { 0, 0, 0, 0 }; - sc = dev->tracks[track][side].params[1]; - sh = dev->tracks[track][side].params[2]; - sn = dev->tracks[track][side].params[4]; - - if (sh & 0x80) - c_map = dev->buffer + dev->tracks[track][side].c_map_offs; - if (sh & 0x40) - h_map = dev->buffer + dev->tracks[track][side].h_map_offs; - r_map = dev->buffer + dev->tracks[track][side].r_map_offs; - - if (sn == 0xFF) - n_map = dev->buffer + dev->tracks[track][side].n_map_offs; - - if (c != dev->track) return; - - for (i = 0; i < dev->tracks[track][side].params[3]; i++) { - id[0] = (sh & 0x80) ? c_map[i] : sc; - id[1] = (sh & 0x40) ? h_map[i] : (sh & 1); - id[2] = r_map[i]; - id[3] = (sn == 0xFF) ? n_map[i] : sn; - if ((id[0] == c) && (id[1] == h) && (id[2] == r) && (id[3] == n)) { - dev->current_data[side] = dev->buffer + dev->tracks[track][side].sector_data_offs[i]; - } - } -} - - -static void -imd_writeback(int drive) -{ - imd_t *dev = imd[drive]; - int side; - int track = dev->track; - int i = 0; - char *n_map = 0; - uint8_t h, n, spt; - uint32_t ssize; - - if (writeprot[drive]) return; - - for (side = 0; side < dev->sides; side++) { - if (dev->tracks[track][side].is_present) { - fseek(dev->f, dev->tracks[track][side].file_offs, SEEK_SET); - h = dev->tracks[track][side].params[2]; - spt = dev->tracks[track][side].params[3]; - n = dev->tracks[track][side].params[4]; - fwrite(dev->tracks[track][side].params, 1, 5, dev->f); - - if (h & 0x80) - fwrite(dev->buffer + dev->tracks[track][side].c_map_offs, 1, spt, dev->f); - - if (h & 0x40) - fwrite(dev->buffer + dev->tracks[track][side].h_map_offs, 1, spt, dev->f); - - if (n == 0xFF) { - n_map = dev->buffer + dev->tracks[track][side].n_map_offs; - fwrite(n_map, 1, spt, dev->f); - } - for (i = 0; i < spt; i++) { - ssize = (n == 0xFF) ? n_map[i] : n; - ssize = 128 << ssize; - fwrite(dev->buffer + dev->tracks[track][side].sector_data_offs[i], 1, ssize, dev->f); - } - } - } -} - - -static uint8_t -poll_read_data(int drive, int side, uint16_t pos) -{ - imd_t *dev = imd[drive]; - int type = dev->current_data[side][0]; - - if (! (type & 1)) return(0xf6); /* Should never happen. */ - - return(dev->current_data[side][pos + 1]); -} - - -static void -poll_write_data(int drive, int side, uint16_t pos, uint8_t data) -{ - imd_t *dev = imd[drive]; - int type = dev->current_data[side][0]; - - if (writeprot[drive]) return; - - if (! (type & 1)) return; /* Should never happen. */ - - dev->current_data[side][pos + 1] = data; -} - - -static int -format_conditions(int drive) -{ - imd_t *dev = imd[drive]; - int track = dev->track; - int side, temp; - - side = fdd_get_head(drive); - temp = (fdc_get_format_sectors(imd_fdc) == dev->tracks[track][side].params[3]); - temp = temp && (fdc_get_format_n(imd_fdc) == dev->tracks[track][side].params[4]); - - return(temp); -} - - -void -imd_init(void) -{ - memset(imd, 0x00, sizeof(imd)); -} - - -void -imd_load(int drive, wchar_t *fn) -{ - uint32_t magic = 0; - uint32_t fsize = 0; - char *buffer; - char *buffer2; - imd_t *dev; - int i = 0; - int track_spt = 0; - int sector_size = 0; - int track = 0; - int side = 0; - int extra = 0; - uint32_t last_offset = 0; - uint32_t data_size = 512; - uint32_t mfm = 0; - uint32_t pre_sector = 0; - uint32_t track_total = 0; - uint32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; - uint8_t converted_rate; - - d86f_unregister(drive); - - writeprot[drive] = 0; - - /* Allocate a drive block. */ - dev = (imd_t *)malloc(sizeof(imd_t)); - memset(dev, 0x00, sizeof(imd_t)); - - dev->f = plat_fopen(fn, L"rb+"); - if (dev->f == NULL) { - dev->f = plat_fopen(fn, L"rb"); - if (dev->f == NULL) { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; - } - - if (ui_writeprot[drive]) - writeprot[drive] = 1; - fwriteprot[drive] = writeprot[drive]; - - fseek(dev->f, 0, SEEK_SET); - fread(&magic, 1, 4, dev->f); - if (magic != 0x20444D49) { - imd_log("IMD: Not a valid ImageDisk image\n"); - fclose(dev->f); - free(dev);; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } else { - imd_log("IMD: Valid ImageDisk image\n"); - } - - fseek(dev->f, 0, SEEK_END); - fsize = ftell(dev->f); - fseek(dev->f, 0, SEEK_SET); - dev->buffer = malloc(fsize); - fread(dev->buffer, 1, fsize, dev->f); - buffer = dev->buffer; - - buffer2 = strchr(buffer, 0x1A); - if (buffer2 == NULL) { - imd_log("IMD: No ASCII EOF character\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } else { - imd_log("IMD: ASCII EOF character found at offset %08X\n", buffer2 - buffer); - } - - buffer2++; - if ((buffer2 - buffer) == fsize) { - imd_log("IMD: File ends after ASCII EOF character\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } else { - imd_log("IMD: File continues after ASCII EOF character\n"); - } - - dev->start_offs = (buffer2 - buffer); - dev->disk_flags = 0x00; - dev->track_count = 0; - dev->sides = 1; - - /* Set up the drive unit. */ - imd[drive] = dev; - - while(1) { - track = buffer2[1]; - side = buffer2[2]; - if (side & 1) - dev->sides = 2; - extra = side & 0xC0; - side &= 0x3F; - - dev->tracks[track][side].side_flags = (buffer2[0] % 3); - if (! dev->tracks[track][side].side_flags) - dev->disk_flags |= (0x02); - dev->tracks[track][side].side_flags |= (!(buffer2[0] - dev->tracks[track][side].side_flags) ? 0 : 8); - mfm = dev->tracks[track][side].side_flags & 8; - track_total = mfm ? 146 : 73; - pre_sector = mfm ? 60 : 42; - - track_spt = buffer2[3]; - sector_size = buffer2[4]; - if ((track_spt == 15) && (sector_size == 2)) - dev->tracks[track][side].side_flags |= 0x20; - if ((track_spt == 16) && (sector_size == 2)) - dev->tracks[track][side].side_flags |= 0x20; - if ((track_spt == 17) && (sector_size == 2)) - dev->tracks[track][side].side_flags |= 0x20; - if ((track_spt == 8) && (sector_size == 3)) - dev->tracks[track][side].side_flags |= 0x20; - if ((dev->tracks[track][side].side_flags & 7) == 1) - dev->tracks[track][side].side_flags |= 0x20; - /* imd_log("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); */ - dev->tracks[track][side].is_present = 1; - dev->tracks[track][side].file_offs = (buffer2 - buffer); - memcpy(dev->tracks[track][side].params, buffer2, 5); - dev->tracks[track][side].r_map_offs = dev->tracks[track][side].file_offs + 5; - last_offset = dev->tracks[track][side].r_map_offs + track_spt; - - if (extra & 0x80) { - dev->tracks[track][side].c_map_offs = last_offset; - last_offset += track_spt; - } - - if (extra & 0x40) { - dev->tracks[track][side].h_map_offs = last_offset; - last_offset += track_spt; - } - - if (sector_size == 0xFF) { - dev->tracks[track][side].n_map_offs = last_offset; - buffer2 = buffer + last_offset; - last_offset += track_spt; - - dev->tracks[track][side].data_offs = last_offset; - - for (i = 0; i < track_spt; i++) { - data_size = buffer2[i]; - data_size = 128 << data_size; - dev->tracks[track][side].sector_data_offs[i] = last_offset; - dev->tracks[track][side].sector_data_size[i] = 1; - if (buffer[dev->tracks[track][side].sector_data_offs[i]] != 0) - dev->tracks[track][side].sector_data_size[i] += (buffer[dev->tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; - last_offset += dev->tracks[track][side].sector_data_size[i]; - if (!(buffer[dev->tracks[track][side].sector_data_offs[i]] & 1)) - fwriteprot[drive] = writeprot[drive] = 1; - track_total += (pre_sector + data_size + 2); - } - } else { - dev->tracks[track][side].data_offs = last_offset; - - for (i = 0; i < track_spt; i++) { - data_size = sector_size; - data_size = 128 << data_size; - dev->tracks[track][side].sector_data_offs[i] = last_offset; - dev->tracks[track][side].sector_data_size[i] = 1; - if (buffer[dev->tracks[track][side].sector_data_offs[i]] != 0) - dev->tracks[track][side].sector_data_size[i] += (buffer[dev->tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; - last_offset += dev->tracks[track][side].sector_data_size[i]; - if (!(buffer[dev->tracks[track][side].sector_data_offs[i]] & 1)) - fwriteprot[drive] = writeprot[drive] = 1; - track_total += (pre_sector + data_size + 2); - } - } - buffer2 = buffer + last_offset; - - /* Leaving even GAP4: 80 : 40 */ - /* Leaving only GAP1: 96 : 47 */ - /* Not leaving even GAP1: 146 : 73 */ - raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 0); - minimum_gap3 = 12 * track_spt; - - if ((dev->tracks[track][side].side_flags == 0x0A) || (dev->tracks[track][side].side_flags == 0x29)) - converted_rate = 2; - else if (dev->tracks[track][side].side_flags == 0x28) - converted_rate = 4; - else - converted_rate = dev->tracks[track][side].side_flags & 0x03; - - if (gap3_sizes[converted_rate][sector_size][track_spt] == 0x00) { - if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 1); - /* Set disk flags so that rotation speed is 2% slower. */ - dev->disk_flags |= (3 << 5); - if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - imd_log("IMD: Unable to fit the %i sectors in a track\n", track_spt); - fclose(dev->f); - free(dev); - imd[drive] = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - } - - dev->tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; - } else if (gap3_sizes[converted_rate][sector_size][track_spt] != 0x00) - dev->tracks[track][side].gap3_len = gap3_sizes[converted_rate][sector_size][track_spt]; - - /* imd_log("GAP3 length for (%02i)(%01i): %i bytes\n", track, side, dev->tracks[track][side].gap3_len); */ - - if (track > dev->track_count) - dev->track_count = track; - - if (last_offset >= fsize) break; - } - - /* If more than 43 tracks, then the tracks are thin (96 tpi). */ - dev->track_count++; - dev->track_width = 0; - if (dev->track_count > 43) - dev->track_width = 1; - - /* If 2 sides, mark it as such. */ - if (dev->sides == 2) - dev->disk_flags |= 8; - - /* imd_log("%i tracks, %i sides\n", dev->track_count, dev->sides); */ - - /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = imd_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = poll_write_data; - d86f_handler[drive].format_conditions = format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, 0x0063); - - drives[drive].seek = imd_seek; - - d86f_common_handlers(drive); -} - - -void -imd_close(int drive) -{ - imd_t *dev = imd[drive]; - - if (dev == NULL) return; - - d86f_unregister(drive); - - if (dev->f != NULL) { - free(dev->buffer); - - fclose(dev->f); - } - - /* Release the memory. */ - free(dev); - imd[drive] = NULL; -} - - -void -imd_set_fdc(void *fdc) -{ - imd_fdc = (fdc_t *) fdc; -} diff --git a/src - Cópia/floppy/fdd_imd.h b/src - Cópia/floppy/fdd_imd.h deleted file mode 100644 index 4e16bd096..000000000 --- a/src - Cópia/floppy/fdd_imd.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 IMD floppy image format. - * - * Version: @(#)floppy_imd.h 1.0.2 2018/03/17 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef EMU_FLOPPY_IMD_H -# define EMU_FLOPPY_IMD_H - - -extern void imd_init(void); -extern void imd_load(int drive, wchar_t *fn); -extern void imd_close(int drive); - - -#endif /*EMU_FLOPPY_IMD_H*/ diff --git a/src - Cópia/floppy/fdd_img.c b/src - Cópia/floppy/fdd_img.c deleted file mode 100644 index 09bd27655..000000000 --- a/src - Cópia/floppy/fdd_img.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* - * 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. - * - * Implementation of the raw sector-based floppy image format, - * as well as the Japanese FDI, CopyQM, and FDF formats. - * - * NOTE: This file is still a disaster, needs to be cleaned up and - * re-merged with the other files. Much of it is generic to - * all formats. - * - * Version: @(#)fdd_img.c 1.0.8 2018/05/09 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../plat.h" -#include "fdd.h" -#include "fdd_img.h" -#include "fdc.h" - - -typedef struct { - FILE *f; - uint8_t track_data[2][50000]; - int sectors, tracks, sides; - uint8_t sector_size; - int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ - int dmf; - int track; - int track_width; - uint32_t base; - uint8_t gap2_size; - uint8_t gap3_size; - uint16_t disk_flags; - uint16_t track_flags; - uint8_t sector_pos_side[2][256]; - uint16_t sector_pos[2][256]; - uint8_t current_sector_pos_side; - uint16_t current_sector_pos; - uint8_t *disk_data; - uint8_t is_cqm; - uint8_t disk_at_once; - uint8_t interleave; - uint8_t skew; -} img_t; - - -static img_t *img[FDD_NUM]; -static fdc_t *img_fdc; - -static double bit_rate_300; -static wchar_t *ext; -static uint8_t first_byte, - second_byte, - third_byte, - fourth_byte; -static uint8_t fdf_suppress_final_byte = 0; /* This is hard-coded to 0 - - * if you really need to read - * those NT 3.1 Beta floppy - * images, change this to 1 - * and recompile. - */ - - -const uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 }; -static const uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } }; -const uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } }; -const uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } }; -const uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } }; - -/* XDF: Layout of the sectors in the image. */ -const xdf_sector_t xdf_img_layout[2][2][46] = { { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, - {0x8101}, {0x8201}, {0x0100}, {0x0200}, {0x0300}, {0x0400}, {0x0500}, {0x0600}, - {0x0700}, {0x0800}, { 0}, - {0x8301}, {0x8401}, {0x8501}, {0x8601}, {0x8701}, {0x8801}, {0x8901}, {0x8A01}, - {0x8B01}, {0x8C01}, {0x8D01}, {0x8E01}, {0x8F01}, {0x9001}, { 0}, { 0}, - { 0}, { 0}, { 0} }, - { {0x8300}, {0x8600}, {0x8201}, {0x8200}, {0x8601}, {0x8301} } - }, /* 5.25" 2HD */ - { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, - {0x8900}, {0x8A00}, {0x8B00}, {0x8101}, {0x0100}, {0x0200}, {0x0300}, {0x0400}, - {0x0500}, {0x0600}, {0x0700}, {0x0800}, { 0}, { 0}, { 0}, - {0x8201}, {0x8301}, {0x8401}, {0x8501}, {0x8601}, {0x8701}, {0x8801}, {0x8901}, - {0x8A01}, {0x8B01}, {0x8C01}, {0x8D01}, {0x8E01}, {0x8F01}, { 0}, { 0}, - { 0}, { 0}, { 0}, {0x9001}, {0x9101}, {0x9201}, {0x9301} }, - { {0x8300}, {0x8400}, {0x8601}, {0x8200}, {0x8201}, {0x8600}, {0x8401}, {0x8301} } - } /* 3.5" 2HD */ - }; - -/* XDF: Layout of the sectors on the disk's track. */ -const xdf_sector_t xdf_disk_layout[2][2][38] = { { { {0x0100}, {0x0200}, {0x8100}, {0x8800}, {0x8200}, {0x0300}, {0x8300}, {0x0400}, - {0x8400}, {0x0500}, {0x8500}, {0x0600}, {0x8600}, {0x0700}, {0x8700}, {0x0800}, - {0x8D01}, {0x8501}, {0x8E01}, {0x8601}, {0x8F01}, {0x8701}, {0x9001}, {0x8801}, - {0x8101}, {0x8901}, {0x8201}, {0x8A01}, {0x8301}, {0x8B01}, {0x8401}, {0x8C01} }, - { {0x8300}, {0x8200}, {0x8600}, {0x8201}, {0x8301}, {0x8601} } - }, /* 5.25" 2HD */ - { { {0x0100}, {0x8A00}, {0x8100}, {0x8B00}, {0x8200}, {0x0200}, {0x8300}, {0x0300}, - {0x8400}, {0x0400}, {0x8500}, {0x0500}, {0x8600}, {0x0600}, {0x8700}, {0x0700}, - {0x8800}, {0x0800}, {0x8900}, - {0x9001}, {0x8701}, {0x9101}, {0x8801}, {0x9201}, {0x8901}, {0x9301}, {0x8A01}, - {0x8101}, {0x8B01}, {0x8201}, {0x8C01}, {0x8301}, {0x8D01}, {0x8401}, {0x8E01}, - {0x8501}, {0x8F01}, {0x8601} }, - { {0x8300}, {0x8200}, {0x8400}, {0x8600}, {0x8401}, {0x8201}, {0x8301}, {0x8601} }, - }, /* 3.5" 2HD */ - }; - -/* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */ -/* Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM single-RPM 5.25" drive by setting the rate to 250 kbps. - Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM single-RPM drive by setting the rate rate to 300 kbps. */ -static const uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */ - { 15, 19, 23, 32, 38, 73 }, /* 256 */ - { 7, 10, 12, 17, 22, 41 }, /* 512 */ - { 3, 5, 6, 9, 11, 22 }, /* 1024 */ - { 2, 2, 3, 4, 5, 11 }, /* 2048 */ - { 1, 1, 1, 2, 2, 5 }, /* 4096 */ - { 0, 0, 0, 1, 1, 3 }, /* 8192 */ - { 0, 0, 0, 0, 0, 1 } }; /* 16384 */ - -static const uint8_t xdf_sectors[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ - { 0, 0, 0, 0, 0, 0 }, /* 256 */ - { 0, 0, 0, 19, 23, 0 }, /* 512 */ - { 0, 0, 0, 0, 0, 0 }, /* 1024 */ - { 0, 0, 0, 0, 0, 0 }, /* 2048 */ - { 0, 0, 0, 0, 0, 0 }, /* 4096 */ - { 0, 0, 0, 0, 0, 0 }, /* 8192 */ - { 0, 0, 0, 0, 0, 0 } }; /* 16384 */ - -static const uint8_t xdf_types[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ - { 0, 0, 0, 0, 0, 0 }, /* 256 */ - { 0, 0, 0, 1, 2, 0 }, /* 512 */ - { 0, 0, 0, 0, 0, 0 }, /* 1024 */ - { 0, 0, 0, 0, 0, 0 }, /* 2048 */ - { 0, 0, 0, 0, 0, 0 }, /* 4096 */ - { 0, 0, 0, 0, 0, 0 }, /* 8192 */ - { 0, 0, 0, 0, 0, 0 } }; /* 16384 */ - -static const double bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, (500.0 * 300.0) / 360.0, 500.0, 1000.0 }; - -static const uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 }; - -static const uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 }; - -const int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][0] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][1] */ - 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][2] */ - 0x00, 0x00, 0x6C, 0x48, 0x2A, 0x08, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x26, 0x00, 0x00, 0x00, 0x00, /* [0][3] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][4] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][5] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][6] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][7] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][0] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][1] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1C, 0x0E, 0x00, 0x00, /* [1][2] */ - 0x00, 0x00, 0x6C, 0x48, 0x2A, 0x08, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][3] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][4] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][5] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][6] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][7] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][0] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x0C, 0x00, 0x00, 0x00, 0x36, /* [2][1] */ - 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x50, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][2] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0xF0, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][3] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][4] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][5] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][6] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][7] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][0] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][1] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][2] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x53, 0x4E, 0x3D, 0x2C, 0x1C, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][3] */ - 0x00, 0x00, 0xF7, 0xAF, 0x6F, 0x55, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][4] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][5] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][6] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][7] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][0] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][1] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x54, /* [4][2] */ - 0x38, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][3] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][4] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][5] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][6] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][7] */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }; - - -#ifdef ENABLE_IMG_LOG -int img_do_log = ENABLE_IMG_LOG; -#endif - - -static void -img_log(const char *fmt, ...) -{ -#ifdef ENABLE_IMG_LOG - va_list ap; - - if (img_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Generic */ -static int -sector_size_code(int sector_size) -{ - switch(sector_size) { - case 128: - return(0); - - case 256: - return(1); - - default: - case 512: - return(2); - - case 1024: - return(3); - - case 2048: - return(4); - - case 4096: - return(5); - - case 8192: - return(6); - - case 16384: - return(7); - } -} - - -static int -bps_is_valid(uint16_t bps) -{ - int i; - - for (i = 0; i <= 8; i++) { - if (bps == (128 << i)) return(1); - } - - return(0); -} - - -static int -first_byte_is_valid(uint8_t first_byte) -{ - switch(first_byte) { - case 0x60: - case 0xE9: - case 0xEB: - return(1); - - default: - break; - } - - return(0); -} - - -#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] -#define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector] - - -static int -interleave(int sector, int skew, int track_spt) -{ - uint32_t skewed_i; - uint32_t adjusted_r; - uint32_t add = (track_spt & 1); - uint32_t adjust = (track_spt >> 1); - - skewed_i = (sector + skew) % track_spt; - adjusted_r = (skewed_i >> 1) + 1; - if (skewed_i & 1) - adjusted_r += (adjust + add); - - return(adjusted_r); -} - - -static void -write_back(int drive) -{ - img_t *dev = img[drive]; - int ssize = 128 << ((int) dev->sector_size); - int side; - - if (dev->f == NULL) return; - - if (dev->disk_at_once) return; - - fseek(dev->f, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET); - for (side = 0; side < dev->sides; side++) - fwrite(dev->track_data[side], dev->sectors * ssize, 1, dev->f); -} - - -static uint16_t -disk_flags(int drive) -{ - img_t *dev = img[drive]; - - return(dev->disk_flags); -} - - -static uint16_t -side_flags(int drive) -{ - img_t *dev = img[drive]; - - return(dev->track_flags); -} - - -static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - img_t *dev = img[drive]; - - dev->current_sector_pos_side = dev->sector_pos_side[h][r]; - dev->current_sector_pos = dev->sector_pos[h][r]; -} - - -static uint8_t -poll_read_data(int drive, int side, uint16_t pos) -{ - img_t *dev = img[drive]; - - return(dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); -} - - -static void -poll_write_data(int drive, int side, uint16_t pos, uint8_t data) -{ - img_t *dev = img[drive]; - - dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos] = data; -} - - -static int -format_conditions(int drive) -{ - img_t *dev = img[drive]; - int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); - - temp = temp && (fdc_get_format_n(img_fdc) == dev->sector_size); - temp = temp && (dev->xdf_type == 0); - - return(temp); -} - - -static void -img_seek(int drive, int track) -{ - img_t *dev = img[drive]; - int side; - int current_xdft = dev->xdf_type - 1; - int read_bytes = 0; - uint8_t id[4] = { 0, 0, 0, 0 }; - int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; - int ssize = 128 << ((int) dev->sector_size); - uint32_t cur_pos = 0; - - if (dev->f == NULL) return; - - if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; - - dev->track = track; - d86f_set_cur_track(drive, track); - - is_t0 = (track == 0) ? 1 : 0; - - if (! dev->disk_at_once) - fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET); - - for (side = 0; side < dev->sides; side++) { - if (dev->disk_at_once) { - cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); - memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); - } else { - read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); - if (read_bytes < (dev->sectors * ssize)) - memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); - } - } - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > dev->tracks) { - d86f_zero_track(drive); - return; - } - - if (!dev->xdf_type || dev->is_cqm) { - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); - - for (sector = 0; sector < dev->sectors; sector++) { - if (dev->is_cqm) { - if (dev->interleave) - sr = interleave(sector, dev->skew, dev->sectors); - else { - sr = sector + 1; - sr += dev->skew; - if (sr > dev->sectors) - sr -= dev->sectors; - } - } else { - if (dev->gap3_size < 68) - sr = interleave(sector, 1, dev->sectors); - else - sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); - } - id[0] = track; - id[1] = side; - id[2] = sr; - id[3] = dev->sector_size; - dev->sector_pos_side[side][sr] = side; - dev->sector_pos[side][sr] = (sr - 1) * ssize; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0, 0); - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } - } else { - total = dev->sectors; - img_pos = 0; - sside = 0; - - /* Pass 1, get sector positions in the image. */ - for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { - if (is_t0) { - img_pos = (sector % total) << 9; - sside = (sector >= total) ? 1 : 0; - } - - if (xdf_img_sector.word) { - dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; - dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; - } - - if (! is_t0) { - img_pos += (128 << (xdf_img_sector.id.r & 7)); - if (img_pos >= (total << 9)) sside = 1; - img_pos %= (total << 9); - } - } - - /* Pass 2, prepare the actual track. */ - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); - - for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { - array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; - buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - - id[0] = track; - id[1] = xdf_disk_sector.id.h; - id[2] = xdf_disk_sector.id.r; - - if (is_t0) { - id[3] = 2; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); - } else { - id[3] = id[2] & 7; - ssize = (128 << id[3]); - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); - } - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } - } -} - - -void -img_init(void) -{ - memset(img, 0x00, sizeof(img)); -} - - -void -img_load(int drive, wchar_t *fn) -{ - uint16_t bpb_bps; - uint16_t bpb_total; - uint8_t bpb_mid; /* Media type ID. */ - uint8_t bpb_sectors; - uint8_t bpb_sides; - uint8_t cqm, ddi, fdf, fdi; - uint16_t comment_len = 0; - int16_t block_len = 0; - uint32_t cur_pos = 0; - uint8_t rep_byte = 0; - uint8_t run = 0; - uint8_t real_run = 0; - uint8_t *bpos; - uint16_t track_bytes = 0; - uint8_t *literal; - img_t *dev; - int temp_rate; - int guess = 0; - int size; - int i; - - ext = plat_get_extension(fn); - - d86f_unregister(drive); - - writeprot[drive] = 0; - - /* Allocate a drive block. */ - dev = (img_t *)malloc(sizeof(img_t)); - memset(dev, 0x00, sizeof(img_t)); - - dev->f = plat_fopen(fn, L"rb+"); - if (dev->f == NULL) { - dev->f = plat_fopen(fn, L"rb"); - if (dev->f == NULL) { - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; - } - - if (ui_writeprot[drive]) - writeprot[drive] = 1; - fwriteprot[drive] = writeprot[drive]; - - cqm = ddi = fdf = fdi = 0; - - dev->interleave = dev->skew = 0; - - if (! wcscasecmp(ext, L"DDI")) { - ddi = 1; - dev->base = 0x2400; - } else - dev->base = 0; - - if (! wcscasecmp(ext, L"FDI")) { - /* This is a Japanese FDI image, so let's read the header */ - img_log("img_load(): File is a Japanese FDI image...\n"); - fseek(dev->f, 0x10, SEEK_SET); - (void)fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, 0x0C, SEEK_SET); - (void)fread(&size, 1, 4, dev->f); - bpb_total = size / bpb_bps; - fseek(dev->f, 0x08, SEEK_SET); - (void)fread(&(dev->base), 1, 4, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - if (bpb_mid < 0xF0) - bpb_mid = 0xF0; - fseek(dev->f, 0x14, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x18, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, dev->base, SEEK_SET); - first_byte = fgetc(dev->f); - - fdi = 1; - cqm = 0; - dev->disk_at_once = 0; - fdf = 0; - } else { - /* Read the first four bytes. */ - fseek(dev->f, 0x00, SEEK_SET); - first_byte = fgetc(dev->f); - fseek(dev->f, 0x01, SEEK_SET); - second_byte = fgetc(dev->f); - fseek(dev->f, 0x02, SEEK_SET); - third_byte = fgetc(dev->f); - fseek(dev->f, 0x03, SEEK_SET); - fourth_byte = fgetc(dev->f); - - if ((first_byte == 0x1A) && (second_byte == 'F') && - (third_byte == 'D') && (fourth_byte == 'F')) { - /* This is a FDF image. */ - img_log("img_load(): File is a FDF image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, L"rb"); - - fdf = 1; - cqm = 0; - dev->disk_at_once = 1; - - fseek(dev->f, 0x50, SEEK_SET); - (void)fread(&dev->tracks, 1, 4, dev->f); - - /* Decode the entire file - pass 1, no write to buffer, determine length. */ - fseek(dev->f, 0x80, SEEK_SET); - size = 0; - track_bytes = 0; - bpos = dev->disk_data; - while (! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } - - if (feof(dev->f)) break; - - if (first_byte == 0xFF) break; - - if (first_byte) { - run = fgetc(dev->f); - - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; - - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - rep_byte = fgetc(dev->f); - } else { - /* Literal. */ - track_bytes -= (run & 0x7f); - literal = (uint8_t *)malloc(run & 0x7f); - fread(literal, 1, (run & 0x7f), dev->f); - free(literal); - } - size += (run & 0x7f); - if (!track_bytes) - size -= fdf_suppress_final_byte; - } else { - /* Literal block. */ - size += (track_bytes - fdf_suppress_final_byte); - literal = (uint8_t *)malloc(track_bytes); - fread(literal, 1, track_bytes, dev->f); - free(literal); - track_bytes = 0; - } - - if (feof(dev->f)) break; - } - - /* Allocate the buffer. */ - dev->disk_data = (uint8_t *)malloc(size); - - /* Decode the entire file - pass 2, write to buffer. */ - fseek(dev->f, 0x80, SEEK_SET); - track_bytes = 0; - bpos = dev->disk_data; - while(! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } - - if (feof(dev->f)) break; - - if (first_byte == 0xFF) break; - - if (first_byte) { - run = fgetc(dev->f); - real_run = (run & 0x7f); - - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; - - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - rep_byte = fgetc(dev->f); - if (real_run) - memset(bpos, rep_byte, real_run); - } else { - /* Literal. */ - track_bytes -= real_run; - literal = (uint8_t *) malloc(real_run); - fread(literal, 1, real_run, dev->f); - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - if (run & 0x7f) - memcpy(bpos, literal, real_run); - free(literal); - } - bpos += real_run; - } else { - /* Literal block. */ - literal = (uint8_t *) malloc(track_bytes); - fread(literal, 1, track_bytes, dev->f); - memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); - free(literal); - bpos += (track_bytes - fdf_suppress_final_byte); - track_bytes = 0; - } - - if (feof(dev->f)) break; - } - - first_byte = *dev->disk_data; - - bpb_bps = *(uint16_t *)(dev->disk_data + 0x0B); - bpb_total = *(uint16_t *)(dev->disk_data + 0x13); - bpb_mid = *(dev->disk_data + 0x15); - bpb_sectors = *(dev->disk_data + 0x18); - bpb_sides = *(dev->disk_data + 0x1A); - - /* Jump ahead to determine the image's geometry. */ - goto jump_if_fdf; - } - - if (((first_byte == 'C') && (second_byte == 'Q')) || - ((first_byte == 'c') && (second_byte == 'q'))) { - img_log("img_load(): File is a CopyQM image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, L"rb"); - - fseek(dev->f, 0x03, SEEK_SET); - fread(&bpb_bps, 1, 2, dev->f); -#if 0 - fseek(dev->f, 0x0B, SEEK_SET); - fread(&bpb_total, 1, 2, dev->f); -#endif - fseek(dev->f, 0x10, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x12, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, 0x5B, SEEK_SET); - dev->tracks = fgetc(dev->f); - - bpb_total = ((uint16_t)bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; - - fseek(dev->f, 0x74, SEEK_SET); - dev->interleave = fgetc(dev->f); - fseek(dev->f, 0x76, SEEK_SET); - dev->skew = fgetc(dev->f); - - dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - - fseek(dev->f, 0x6F, SEEK_SET); - fread(&comment_len, 1, 2, dev->f); - - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; - - fseek(dev->f, 133 + comment_len, SEEK_SET); - - cur_pos = 0; - - while(! feof(dev->f)) { - fread(&block_len, 1, 2, dev->f); - - if (! feof(dev->f)) { - if (block_len < 0) { - rep_byte = fgetc(dev->f); - block_len = -block_len; - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - memset(dev->disk_data + cur_pos, rep_byte, block_len); - break; - } else { - memset(dev->disk_data + cur_pos, rep_byte, block_len); - cur_pos += block_len; - } - } else if (block_len > 0) { - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - break; - } else { - fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - cur_pos += block_len; - } - } - } - } - img_log("Finished reading CopyQM image data\n"); - - cqm = 1; - dev->disk_at_once = 1; - fdf = 0; - first_byte = *dev->disk_data; - } else { - dev->disk_at_once = 0; - /* Read the BPB */ - if (ddi) { - img_log("img_load(): File is a DDI image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - } else - img_log("img_load(): File is a raw image...\n"); - fseek(dev->f, dev->base + 0x0B, SEEK_SET); - fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x13, SEEK_SET); - fread(&bpb_total, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - fseek(dev->f, dev->base + 0x18, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, dev->base + 0x1A, SEEK_SET); - bpb_sides = fgetc(dev->f); - - cqm = 0; - } - - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; - if (ddi) - size -= 0x2400; - -jump_if_fdf: - if (!ddi) - dev->base = 0; - fdi = 0; - } - - dev->sides = 2; - dev->sector_size = 2; - - img_log("BPB reports %i sides and %i bytes per sector (%i sectors total)\n", - bpb_sides, bpb_bps, bpb_total); - - guess = (bpb_sides < 1); - guess = guess || (bpb_sides > 2); - guess = guess || !bps_is_valid(bpb_bps); - guess = guess || !first_byte_is_valid(first_byte); - guess = guess || !fdd_get_check_bpb(drive); - guess = guess && !fdi; - guess = guess && !cqm; - if (guess) { - /* - * The BPB is giving us a wacky number of sides and/or bytes - * per sector, therefore it is most probably not a BPB at all, - * so we have to guess the parameters from file size. - */ - if (size <= (160*1024)) { - dev->sectors = 8; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (180*1024)) { - dev->sectors = 9; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (315*1024)) { - dev->sectors = 9; - dev->tracks = 70; - dev->sides = 1; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (360*1024)) { /*DD 360K*/ - dev->sectors = 9; - dev->tracks = 40; - } else if (size <= (400*1024)) { /*DEC RX50*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sides = 1; - } else if (size <= (640*1024)) { /*DD 640K*/ - dev->sectors = 8; - dev->tracks = 80; - } else if (size <= (720*1024)) { /*DD 720K*/ - dev->sectors = 9; - dev->tracks = 80; - } else if (size <= (800*1024)) { /*DD*/ - dev->sectors = 10; - dev->tracks = 80; - } else if (size <= (880*1024)) { /*DD*/ - dev->sectors = 11; - dev->tracks = 80; - } else if (size <= (960*1024)) { /*DD*/ - dev->sectors = 12; - dev->tracks = 80; - } else if (size <= (1040*1024)) { /*DD*/ - dev->sectors = 13; - dev->tracks = 80; - } else if (size <= (1120*1024)) { /*DD*/ - dev->sectors = 14; - dev->tracks = 80; - } else if (size <= 1228800) { /*HD 1.2MB*/ - dev->sectors = 15; - dev->tracks = 80; - } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ - dev->sectors = 8; - dev->tracks = 77; - dev->sector_size = 3; - } else if (size <= 1474560) { /*HD 1.44MB*/ - dev->sectors = 18; - dev->tracks = 80; - } else if (size <= 1556480) { /*HD*/ - dev->sectors = 19; - dev->tracks = 80; - } else if (size <= 1638400) { /*HD 1024 sector*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 1720320) { /*DMF (Windows 95) */ - dev->sectors = 21; - dev->tracks = 80; - } else if (size <= 1741824) { - dev->sectors = 21; - dev->tracks = 81; - } else if (size <= 1763328) { - dev->sectors = 21; - dev->tracks = 82; - } else if (size <= 1802240) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ - dev->sectors = 23; - dev->tracks = 80; - } else if (size <= 2949120) { /*ED*/ - dev->sectors = 36; - dev->tracks = 80; - } else if (size <= 3194880) { /*ED*/ - dev->sectors = 39; - dev->tracks = 80; - } else if (size <= 3276800) { /*ED*/ - dev->sectors = 40; - dev->tracks = 80; - } else if (size <= 3358720) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 80; - } else if (size <= 3440640) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 80; -#if 0 - } else if (size <= 3440640) { /*HD 1024 sector*/ - dev->sectors = 21; - dev->tracks = 80; - dev->sector_size = 3; -#endif - } else if (size <= 3604480) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 3610624) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 86; - } else if (size <= 3698688) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 86; - } else { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - bpb_sides = dev->sides; - bpb_sectors = dev->sectors; - bpb_total = size >> (dev->sector_size + 7); - } else { - /* The BPB readings appear to be valid, so let's set the values. */ - if (fdi) { - /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ - fseek(dev->f, 0x1C, SEEK_SET); - fread(&(dev->tracks), 1, 4, dev->f); - } else { - if (!cqm && !fdf) { - /* Number of tracks = number of total sectors divided by sides times sectors per track. */ - dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); - } - } - - /* The rest we just set directly from the BPB. */ - dev->sectors = bpb_sectors; - dev->sides = bpb_sides; - - /* The sector size. */ - dev->sector_size = sector_size_code(bpb_bps); - - temp_rate = 0xFF; - } - - for (i = 0; i < 6; i++) { - if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { - bit_rate_300 = bit_rates_300[i]; - temp_rate = rates[i]; - dev->disk_flags = holes[i] << 1; - dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; - if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ - dev->dmf = 1; - } else { - if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is marked specially because of the track flag (a RPM slow down is needed). */ - dev->interleave = 2; - } - dev->dmf = 0; - } - - img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); - break; - } - } - - if (temp_rate == 0xFF) { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - dev->gap2_size = (temp_rate == 3) ? 41 : 22; - if (dev->dmf) - dev->gap3_size = 8; - else - dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; - if (! dev->gap3_size) { - img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - dev->track_width = 0; - if (dev->tracks > 43) - dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ - if (dev->sides == 2) - dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ - if (dev->interleave == 2) { - dev->interleave = 1; - dev->disk_flags |= 0x60; - } - - dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ - dev->track_flags |= temp_rate & 3; /* Data rate. */ - if (temp_rate & 4) - dev->track_flags |= 0x20; /* RPM. */ - - dev->is_cqm = cqm; - - img_log("Disk flags: %i, track flags: %i\n", - dev->disk_flags, dev->track_flags); - - /* Set up the drive unit. */ - img[drive] = dev; - - /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = write_back; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = poll_write_data; - d86f_handler[drive].format_conditions = format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, 0x0063); - - drives[drive].seek = img_seek; - - d86f_common_handlers(drive); -} - - -void -img_close(int drive) -{ - img_t *dev = img[drive]; - - if (dev == NULL) return; - - d86f_unregister(drive); - - if (dev->f != NULL) { - fclose(dev->f); - dev->f = NULL; - } - - if (dev->disk_data != NULL) - free(dev->disk_data); - - /* Release the memory. */ - free(dev); - img[drive] = NULL; -} - - -void -img_set_fdc(void *fdc) -{ - img_fdc = (fdc_t *) fdc; -} diff --git a/src - Cópia/floppy/fdd_img.h b/src - Cópia/floppy/fdd_img.h deleted file mode 100644 index b5bddb4ad..000000000 --- a/src - Cópia/floppy/fdd_img.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Implementation of the raw sector-based floppy image format, - * as well as the Japanese FDI, CopyQM, and FDF formats. - * - * Version: @(#)floppy_img.h 1.0.2 2018/03/17 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_FLOPPY_IMG_H -# define EMU_FLOPPY_IMG_H - - -extern void img_init(void); -extern void img_load(int drive, wchar_t *fn); -extern void img_close(int drive); - - -#endif /*EMU_FLOPPY_IMG_H*/ diff --git a/src - Cópia/floppy/fdd_json.c b/src - Cópia/floppy/fdd_json.c deleted file mode 100644 index c56bbd80d..000000000 --- a/src - Cópia/floppy/fdd_json.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - * 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. - * - * Implementation of the PCjs JSON floppy image format. - * - * Version: @(#)fdd_json.c 1.0.5 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "fdd.h" -#include "fdc.h" -#include "fdd_common.h" -#include "fdd_json.h" - - -#define NTRACKS 256 -#define NSIDES 2 -#define NSECTORS 256 - - -typedef struct { - uint8_t track, /* ID: track number */ - side, /* side number */ - sector; /* sector number 1.. */ - uint16_t size; /* encoded size of sector */ - uint8_t *data; /* allocated data for it */ -} sector_t; - -typedef struct { - FILE *f; - - /* Geometry. */ - uint8_t tracks, /* number of tracks */ - sides, /* number of sides */ - sectors, /* number of sectors per track */ - spt[NTRACKS][NSIDES]; /* number of sectors per track */ - - uint8_t track, /* current track */ - side, /* current side */ - sector[NSIDES]; /* current sector */ - - uint8_t dmf; /* disk is DMF format */ - uint8_t interleave; -#if 0 - uint8_t skew; -#endif - uint8_t gap2_len; - uint8_t gap3_len; - int track_width; - - uint16_t disk_flags, /* flags for the entire disk */ - track_flags; /* flags for the current track */ - - uint8_t interleave_ordered[NTRACKS][NSIDES]; - - sector_t sects[NTRACKS][NSIDES][NSECTORS]; -} json_t; - - -static json_t *images[FDD_NUM]; - - -#ifdef ENABLE_JSON_LOG -int json_do_log = ENABLE_JSON_LOG; -#endif - - -static void -json_log(const char *fmt, ...) -{ -#ifdef ENABLE_JSON_LOG - va_list ap; - - if (json_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -handle(json_t *dev, char *name, char *str) -{ - sector_t *sec = NULL; - uint32_t l, pat; - uint8_t *p; - char *sp; - int i, s; - - /* Point to the currently selected sector. */ - sec = &dev->sects[dev->track][dev->side][dev->dmf-1]; - - /* If no name given, assume sector is done. */ - if (name == NULL) { - /* If no buffer, assume one with 00's. */ - if (sec->data == NULL) { - sec->data = (uint8_t *)malloc(sec->size); - memset(sec->data, 0x00, sec->size); - } - - /* Encode the sector size. */ - sec->size = fdd_sector_size_code(sec->size); - - /* Set up the rest of the Sector ID. */ - sec->track = dev->track; - sec->side = dev->side; - - return; - } - - if (! strcmp(name, "sector")) { - sec->sector = atoi(str); - sec->size = 512; - } else if (! strcmp(name, "length")) { - sec->size = atoi(str); - } else if (! strcmp(name, "pattern")) { - pat = atol(str); - - if (sec->data == NULL) - sec->data = (uint8_t *)malloc(sec->size); - p = sec->data; - s = (sec->size / sizeof(uint32_t)); - for (i=0; i>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - } - } else if (! strcmp(name, "data")) { - if (sec->data == NULL) - sec->data = (uint8_t *)malloc(sec->size); - p = sec->data; - while (str && *str) { - sp = strchr(str, ','); - if (sp != NULL) *sp++ = '\0'; - l = atol(str); - - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - l >>= 8; - *p++ = (l & 0x000000ff); - - str = sp; - } - } -} - - -static int -unexpect(int c, int state, int level) -{ - json_log("JSON: Unexpected '%c' in state %d/%d.\n", c, state, level); - - return(-1); -} - - -static int -load_image(json_t *dev) -{ - char buff[4096], name[32]; - int c, i, j, state, level; - char *ptr; - - if (dev->f == NULL) { - json_log("JSON: no file loaded!\n"); - return(0); - } - - /* Initialize. */ - for (i=0; isects[i][j], 0x00, sizeof(sector_t)); - } - dev->track = dev->side = dev->dmf = 0; /* "dmf" is "sector#" */ - - /* Now run the state machine. */ - ptr = NULL; - level = state = 0; - while (state >= 0) { - /* Get a character from the input. */ - c = fgetc(dev->f); - if ((c == EOF) || ferror(dev->f)) { - state = -1; - break; - } - - /* Process it. */ - switch(state) { - case 0: /* read level header */ - dev->dmf = 1; - if (c != '[') { - state = unexpect(c, state, level); - } else { - if (++level == 3) - state++; - } - break; - - case 1: /* read sector header */ - if (c != '{') - state = unexpect(c, state, level); - else - state++; - break; - - case 2: /* begin sector data name */ - if (c != '\"') { - state = unexpect(c, state, level); - } else { - ptr = name; - state++; - } - break; - - case 3: /* read sector data name */ - if (c == '\"') { - *ptr = '\0'; - state++; - } else { - *ptr++ = c; - } - break; - - case 4: /* end of sector data name */ - if (c != ':') { - state = unexpect(c, state, level); - } else { - ptr = buff; - state++; - } - break; - - case 5: /* read sector value data */ - switch(c) { - case ',': - case '}': - *ptr = '\0'; - handle(dev, name, buff); - - if (c == '}') - state = 7; /* done */ - else - state = 2; /* word */ - break; - - case '[': - state++; - break; - - default: - *ptr++ = c; - } - break; - - case 6: /* read sector data complex */ - if (c != ']') - *ptr++ = c; - else - state = 5; - break; - - case 7: /* sector done */ - handle(dev, NULL, NULL); - switch(c) { - case ',': /* next sector */ - dev->dmf++; - state = 1; - break; - - case ']': /* all sectors done */ - if (--level == 0) - state = -1; - else state++; - break; - - default: - state = unexpect(c, state, level); - } - break; - - case 8: /* side done */ - switch(c) { - case ',': /* next side */ - state = 0; - break; - - case ']': /* all sides done */ - if (--level == 0) - state = -1; - else state++; - break; - - default: - state = unexpect(c, state, level); - } - dev->spt[dev->track][dev->side] = dev->dmf; - dev->side++; - break; - - case 9: /* track done */ - switch(c) { - case ',': /* next track */ - dev->side = 0; - state = 0; - break; - - case ']': /* all tracks done */ - if (--level == 0) - state = -1; - else state++; - break; - - default: - state = unexpect(c, state, level); - } - dev->track++; - break; - } - - } - - /* Save derived values. */ - dev->tracks = dev->track; - dev->sides = dev->side; - - return(1); -} - - -/* Seek the heads to a track, and prepare to read data from that track. */ -static void -json_seek(int drive, int track) -{ - uint8_t id[4] = { 0,0,0,0 }; - json_t *dev = images[drive]; - int side, sector; - int rate, gap2, gap3, pos; - int ssize, rsec, asec; - int interleave_type; - - if (dev->f == NULL) { - json_log("JSON: seek: no file loaded!\n"); - return; - } - - /* Allow for doublestepping tracks. */ - if (! dev->track_width && fdd_doublestep_40(drive)) track /= 2; - - /* Set the new track. */ - dev->track = track; - d86f_set_cur_track(drive, track); - - /* Reset the 86F state machine. */ - d86f_reset_index_hole_pos(drive, 0); - d86f_destroy_linked_lists(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - d86f_destroy_linked_lists(drive, 1); - - interleave_type = 0; - - if (track > dev->tracks) { - d86f_zero_track(drive); - return; - } - - for (side=0; sidesides; side++) { - /* Get transfer rate for this side. */ - rate = dev->track_flags & 0x07; - if (!rate && (dev->track_flags & 0x20)) rate = 4; - - /* Get correct GAP3 value for this side. */ - gap3 = fdd_get_gap3_size(rate, - dev->sects[track][side][0].size, - dev->spt[track][side]); - - /* Get correct GAP2 value for this side. */ - gap2 = ((dev->track_flags & 0x07) >= 3) ? 41 : 22; - - pos = d86f_prepare_pretrack(drive, side, 0); - - for (sector=0; sectorspt[track][side]; sector++) { - if (interleave_type == 0) { - rsec = dev->sects[track][side][sector].sector; - asec = sector; - } else { - rsec = fdd_dmf_r[sector]; - asec = dev->interleave_ordered[rsec][side]; - } - id[0] = track; - id[1] = side; - id[2] = rsec; - if (dev->sects[track][side][asec].size > 255) - perror("fdd_json.c: json_seek: sector size too big."); - id[3] = dev->sects[track][side][asec].size & 0xff; - ssize = fdd_sector_code_size(dev->sects[track][side][asec].size & 0xff); - - pos = d86f_prepare_sector( - drive, side, pos, id, - dev->sects[track][side][asec].data, - ssize, gap2, gap3, - 0, /*deleted flag*/ - 0 /*bad_crc flag*/ - ); - - if (sector == 0) - d86f_initialize_last_sector_id(drive,id[0],id[1],id[2],id[3]); - } - } -} - - -static uint16_t -disk_flags(int drive) -{ - json_t *dev = images[drive]; - - return(dev->disk_flags); -} - - -static uint16_t -track_flags(int drive) -{ - json_t *dev = images[drive]; - - return(dev->track_flags); -} - - -static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - json_t *dev = images[drive]; - int i; - - dev->sector[side] = 0; - - /* Make sure we are on the desired track. */ - if (c != dev->track) return; - - /* Set the desired side. */ - dev->side = side; - - /* Now loop over all sector ID's on this side to find our sector. */ - for (i=0; ispt[c][side]; i++) { - if ((dev->sects[dev->track][side][i].track == c) && - (dev->sects[dev->track][side][i].side == h) && - (dev->sects[dev->track][side][i].sector == r) && - (dev->sects[dev->track][side][i].size == n)) { - dev->sector[side] = i; - } - } -} - - -static uint8_t -poll_read_data(int drive, int side, uint16_t pos) -{ - json_t *dev = images[drive]; - uint8_t sec = dev->sector[side]; - - return(dev->sects[dev->track][side][sec].data[pos]); -} - - -void -json_init(void) -{ - memset(images, 0x00, sizeof(images)); -} - - -void -json_load(int drive, wchar_t *fn) -{ - double bit_rate; - int temp_rate; - sector_t *sec; - json_t *dev; - int i; - - /* Just in case- remove ourselves from 86F. */ - d86f_unregister(drive); - - /* Allocate a drive block. */ - dev = (json_t *)malloc(sizeof(json_t)); - memset(dev, 0x00, sizeof(json_t)); - - /* Open the image file. */ - dev->f = plat_fopen(fn, L"rb"); - if (dev->f == NULL) { - free(dev); - memset(fn, 0x00, sizeof(wchar_t)); - return; - } - - /* Our images are always RO. */ - writeprot[drive] = 1; - - /* Set up the drive unit. */ - images[drive] = dev; - - /* Load all sectors from the image file. */ - if (! load_image(dev)) { - json_log("JSON: failed to initialize\n"); - (void)fclose(dev->f); - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(wchar_t)); - return; - } - - json_log("JSON(%d): %ls (%i tracks, %i sides, %i sectors)\n", - drive, fn, dev->tracks, dev->sides, dev->spt[0][0]); - - /* - * If the image has more than 43 tracks, then - * the tracks are thin (96 tpi). - */ - dev->track_width = (dev->tracks > 43) ? 1 : 0; - - /* If the image has 2 sides, mark it as such. */ - dev->disk_flags = 0x00; - if (dev->sides == 2) - dev->disk_flags |= 0x08; - - /* JSON files are always assumed to be MFM-encoded. */ - dev->track_flags = 0x08; - - dev->interleave = 0; -#if 0 - dev->skew = 0; -#endif - - temp_rate = 0xff; - sec = &dev->sects[0][0][0]; - for (i=0; i<6; i++) { - if (dev->spt[0][0] > fdd_max_sectors[sec->size][i]) continue; - - bit_rate = fdd_bit_rates_300[i]; - temp_rate = fdd_rates[i]; - dev->disk_flags |= (fdd_holes[i] << 1); - - if ((bit_rate == 500.0) && (dev->spt[0][0] == 21) && - (sec->size == 2) && (dev->tracks >= 80) && - (dev->tracks <= 82) && (dev->sides == 2)) { - /* - * This is a DMF floppy, set the flag so - * we know to interleave the sectors. - */ - dev->dmf = 1; - } else { - if ((bit_rate == 500.0) && (dev->spt[0][0] == 22) && - (sec->size == 2) && (dev->tracks >= 80) && - (dev->tracks <= 82) && (dev->sides == 2)) { - /* - * This is marked specially because of the - * track flag (a RPM slow down is needed). - */ - dev->interleave = 2; - } - - dev->dmf = 0; - } - - break; - } - - if (temp_rate == 0xff) { - json_log("JSON: invalid image (temp_rate=0xff)\n"); - (void)fclose(dev->f); - dev->f = NULL; - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(wchar_t)); - return; - } - - if (dev->interleave == 2) { - dev->interleave = 1; - dev->disk_flags |= 0x60; - } - - dev->gap2_len = (temp_rate == 3) ? 41 : 22; - if (dev->dmf) - dev->gap3_len = 8; - else - dev->gap3_len = fdd_get_gap3_size(temp_rate,sec->size,dev->spt[0][0]); - - if (! dev->gap3_len) { - json_log("JSON: image of unknown format was inserted into drive %c:!\n", - 'C'+drive); - (void)fclose(dev->f); - dev->f = NULL; - free(dev); - images[drive] = NULL; - memset(fn, 0x00, sizeof(wchar_t)); - return; - } - - dev->track_flags |= (temp_rate & 0x03); /* data rate */ - if (temp_rate & 0x04) - dev->track_flags |= 0x20; /* RPM */ - - json_log(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n", - dev->disk_flags, dev->track_flags, dev->gap3_len); - json_log(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n", - bit_rate, temp_rate, (dev->disk_flags >> 1), dev->dmf); - - /* Set up handlers for 86F layer. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = track_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, 0x0063); - - d86f_common_handlers(drive); - - drives[drive].seek = json_seek; -} - - -/* Close the image. */ -void -json_close(int drive) -{ - json_t *dev = images[drive]; - int t, h, s; - - if (dev == NULL) return; - - /* Unlink image from the system. */ - d86f_unregister(drive); - - /* Release all the sector buffers. */ - for (t=0; t<256; t++) { - for (h=0; h<2; h++) { - memset(dev->sects[t][h], 0x00, sizeof(sector_t)); - for (s=0; s<256; s++) { - if (dev->sects[t][h][s].data != NULL) - free(dev->sects[t][h][s].data); - dev->sects[t][h][s].data = NULL; - } - } - } - - if (dev->f != NULL) - (void)fclose(dev->f); - - /* Release the memory. */ - free(dev); - images[drive] = NULL; -} diff --git a/src - Cópia/floppy/fdd_json.h b/src - Cópia/floppy/fdd_json.h deleted file mode 100644 index 0df9dab7d..000000000 --- a/src - Cópia/floppy/fdd_json.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 PCjs JSON floppy image format. - * - * Version: @(#)floppy_json.h 1.0.2 2018/03/17 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef EMU_FLOPPY_JSON_H -# define EMU_FLOPPY_JSON_H - - -extern void json_init(void); -extern void json_load(int drive, wchar_t *fn); -extern void json_close(int drive); - - -#endif /*EMU_FLOPPY_JSON_H*/ diff --git a/src - Cópia/floppy/fdd_td0.c b/src - Cópia/floppy/fdd_td0.c deleted file mode 100644 index f956e9421..000000000 --- a/src - Cópia/floppy/fdd_td0.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * 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. - * - * Implementation of the Teledisk floppy image format. - * - * Version: @(#)fdd_td0.c 1.0.6 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Milodrag Milanovic, - * Haruhiko OKUMURA, - * Haruyasu YOSHIZAKI, - * Kenji RIKITAKE, - * - * Based on Japanese version 29-NOV-1988 - * LZSS coded by Haruhiko OKUMURA - * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI - * Edited and translated to English by Kenji RIKITAKE - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2013-2018 Milodrag Milanovic. - * Copyright 1988-2018 Haruhiko OKUMURA. - * Copyright 1988-2018 Haruyasu YOSHIZAKI. - * Copyright 1988-2018 Kenji RIKITAKE. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "fdd.h" -#include "fdd_td0.h" -#include "fdc.h" - - -#define BUFSZ 512 /* new input buffer */ -#define TD0_MAX_BUFSZ (1024UL*1024UL*4UL) - -/* LZSS Parameters */ -#define N 4096 /* Size of string buffer */ -#define F 60 /* Size of look-ahead buffer */ -#define THRESHOLD 2 -#define NIL N /* End of tree's node */ - -/* Huffman coding parameters */ -#define N_CHAR (256-THRESHOLD+F) /* code (= 0..N_CHAR-1) */ -#define T (N_CHAR*2-1) /* Size of table */ -#define R (T-1) /* root position */ -#define MAX_FREQ 0x8000 - /* update when cumulative frequency */ - /* reaches to this value */ - -typedef struct { - uint16_t r, - bufcnt,bufndx,bufpos, /* string buffer */ - /* the following to allow block reads - from input in next_word() */ - ibufcnt,ibufndx; /* input buffer counters */ - uint8_t inbuf[BUFSZ]; /* input buffer */ -} tdlzhuf; - -typedef struct { - FILE *fdd_file; - off_t fdd_file_offset; - - tdlzhuf tdctl; - uint8_t text_buf[N + F - 1]; - uint16_t freq[T + 1]; /* cumulative freq table */ - - /* - * pointing parent nodes. - * area [T..(T + N_CHAR - 1)] are pointers for leaves - */ - int16_t prnt[T + N_CHAR]; - - /* pointing children nodes (son[], son[] + 1)*/ - int16_t son[T]; - - uint16_t getbuf; - uint8_t getlen; -} td0dsk_t; - -typedef struct { - uint8_t track; - uint8_t head; - uint8_t sector; - uint8_t size; - uint8_t deleted; - uint8_t bad_crc; - uint8_t *data; -} td0_sector_t; - -typedef struct { - FILE *f; - - int tracks; - int track_width; - int sides; - uint16_t disk_flags; - uint16_t default_track_flags; - uint16_t side_flags[256][2]; - uint8_t track_in_file[256][2]; - td0_sector_t sects[256][2][256]; - uint8_t track_spt[256][2]; - uint8_t gap3_len; - uint16_t current_side_flags[2]; - int track; - int current_sector_index[2]; - uint8_t calculated_gap3_lengths[256][2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; - - uint8_t *imagebuf; - uint8_t *processed_buf; -} td0_t; - - -/* - * Tables for encoding/decoding upper 6 bits of - * sliding dictionary pointer - */ -static const uint8_t d_code[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, - 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, - 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, - 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, - 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, - 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, - 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, - 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, - 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, -}; - -static const uint8_t d_len[256] = { - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -}; - - -static td0_t *td0[FDD_NUM]; - - -#ifdef ENABLE_TD0_LOG -int td0_do_log = ENABLE_TD0_LOG; -#endif - - -static void -td0_log(const char *fmt, ...) -{ -#ifdef ENABLE_TD0_LOG - va_list ap; - - if (td0_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) -{ - td0_t *dev = td0[drive]; - - fseek(dev->f, offset, SEEK_SET); - fread(buffer, 1, len, dev->f); -} - - -static int -dsk_identify(int drive) -{ - char header[2]; - - fdd_image_read(drive, header, 0, 2); - if (header[0]=='T' && header[1]=='D') - return(1); - else if (header[0]=='t' && header[1]=='d') - return(1); - - return(0); -} - - -static int -state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) -{ - uint32_t image_size = 0; - - fseek(state->fdd_file, 0, SEEK_END); - image_size = ftell(state->fdd_file); - if (size > image_size - state->fdd_file_offset) - size = (image_size - state->fdd_file_offset) & 0xffff; - fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET); - fread(buf, 1, size, state->fdd_file); - state->fdd_file_offset += size; - - return(size); -} - - -static int -state_next_word(td0dsk_t *state) -{ - if (state->tdctl.ibufndx >= state->tdctl.ibufcnt) { - state->tdctl.ibufndx = 0; - state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf,BUFSZ); - if (state->tdctl.ibufcnt == 0) - return(-1); - } - - while (state->getlen <= 8) { /* typically reads a word at a time */ - state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); - state->getlen += 8; - } - - return(0); -} - - -/* get one bit */ -static int -state_GetBit(td0dsk_t *state) -{ - int16_t i; - - if (state_next_word(state) < 0) - return(-1); - - i = state->getbuf; - state->getbuf <<= 1; - state->getlen--; - if (i < 0) - return(1); - - return(0); -} - - -/* get a byte */ -static int -state_GetByte(td0dsk_t *state) -{ - uint16_t i; - - if (state_next_word(state) != 0) - return(-1); - - i = state->getbuf; - state->getbuf <<= 8; - state->getlen -= 8; - i = i >> 8; - - return((int) i); -} - - -/* initialize freq tree */ -static void -state_StartHuff(td0dsk_t *state) -{ - int i, j; - - for (i = 0; i < N_CHAR; i++) { - state->freq[i] = 1; - state->son[i] = i + T; - state->prnt[i + T] = i; - } - i = 0; j = N_CHAR; - while (j <= R) { - state->freq[j] = state->freq[i] + state->freq[i + 1]; - state->son[j] = i; - state->prnt[i] = state->prnt[i + 1] = j; - i += 2; j++; - } - state->freq[T] = 0xffff; - state->prnt[R] = 0; -} - - -/* reconstruct freq tree */ -static void -state_reconst(td0dsk_t *state) -{ - int16_t i, j, k; - uint16_t f, l; - - /* halven cumulative freq for leaf nodes */ - j = 0; - for (i = 0; i < T; i++) { - if (state->son[i] >= T) { - state->freq[j] = (state->freq[i] + 1) / 2; - state->son[j] = state->son[i]; - j++; - } - } - - /* make a tree : first, connect children nodes */ - for (i = 0, j = N_CHAR; j < T; i += 2, j++) { - k = i + 1; - f = state->freq[j] = state->freq[i] + state->freq[k]; - for (k = j - 1; f < state->freq[k]; k--) {}; - k++; - l = (j - k) * 2; - - memcpy(&state->freq[k + 1], &state->freq[k], l); - state->freq[k] = f; - memcpy(&state->son[k + 1], &state->son[k], l); - state->son[k] = i; - } - - /* connect parent nodes */ - for (i = 0; i < T; i++) { - if ((k = state->son[i]) >= T) - state->prnt[k] = i; - else - state->prnt[k] = state->prnt[k + 1] = i; - } -} - - -/* update freq tree */ -static void -state_update(td0dsk_t *state, int c) -{ - int i, j, k, l; - - if (state->freq[R] == MAX_FREQ) - state_reconst(state); - - c = state->prnt[c + T]; - - /* do it until reaching the root */ - do { - k = ++state->freq[c]; - - /* swap nodes to keep the tree freq-ordered */ - if (k > state->freq[l = c + 1]) { - while (k > state->freq[++l]) {}; - l--; - state->freq[c] = state->freq[l]; - state->freq[l] = k; - - i = state->son[c]; - state->prnt[i] = l; - if (i < T) state->prnt[i + 1] = l; - - j = state->son[l]; - state->son[l] = i; - - state->prnt[j] = c; - if (j < T) state->prnt[j + 1] = c; - state->son[c] = j; - - c = l; - } - } while ((c = state->prnt[c]) != 0); -} - - -static int16_t -state_DecodeChar(td0dsk_t *state) -{ - int ret; - uint16_t c; - - c = state->son[R]; - - /* - * start searching tree from the root to leaves. - * choose node #(son[]) if input bit == 0 - * else choose #(son[]+1) (input bit == 1) - */ - while (c < T) { - if ((ret = state_GetBit(state)) < 0) - return(-1); - c += (unsigned) ret; - c = state->son[c]; - } - c -= T; - - state_update(state, c); - - return(c); -} - - -static int16_t -state_DecodePosition(td0dsk_t *state) -{ - int16_t bit; - uint16_t i, j, c; - - /* decode upper 6 bits from given table */ - if ((bit = state_GetByte(state)) < 0) - return(-1); - - i = (uint16_t) bit; - c = (uint16_t)d_code[i] << 6; - j = d_len[i]; - - /* input lower 6 bits directly */ - j -= 2; - while (j--) { - if ((bit = state_GetBit(state)) < 0) - return(-1); - i = (i << 1) + bit; - } - - return(c | (i & 0x3f)); -} - - -/* DeCompression - split out initialization code to init_Decode() */ -static void -state_init_Decode(td0dsk_t *state) -{ - int i; - - state->getbuf = 0; - state->getlen = 0; - state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ - state->tdctl.bufcnt = 0; - - state_StartHuff(state); - for (i = 0; i < N - F; i++) - state->text_buf[i] = ' '; - - state->tdctl.r = N - F; -} - - -/* Decoding/Uncompressing */ -static int -state_Decode(td0dsk_t *state, uint8_t *buf, int len) -{ - int16_t c, pos; - int count; /* was an unsigned long, seems unnecessary */ - - for (count = 0; count < len; ) { - if (state->tdctl.bufcnt == 0) { - if ((c = state_DecodeChar(state)) < 0) - return(count); /* fatal error */ - if (c < 256) { - *(buf++) = c & 0xff; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } else { - if ((pos = state_DecodePosition(state)) < 0) - return(count); /* fatal error */ - state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); - state->tdctl.bufcnt = c - 255 + THRESHOLD; - state->tdctl.bufndx = 0; - } - } else { - /* still chars from last string */ - while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { - c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; - *(buf++) = c & 0xff; - state->tdctl.bufndx++; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } - - /* reset bufcnt after copy string from text_buf[] */ - if (state->tdctl.bufndx >= state->tdctl.bufcnt) - state->tdctl.bufndx = state->tdctl.bufcnt = 0; - } - } - - return(count); /* count == len, success */ -} - - -static uint32_t -get_raw_tsize(int side_flags, int slower_rpm) -{ - uint32_t size; - - switch(side_flags & 0x27) { - case 0x22: - size = slower_rpm ? 5314 : 5208; - break; - - default: - case 0x02: - case 0x21: - size = slower_rpm ? 6375 : 6250; - break; - - case 0x01: - size = slower_rpm ? 7650 : 7500; - break; - - case 0x20: - size = slower_rpm ? 10629 : 10416; - break; - - case 0x00: - size = slower_rpm ? 12750 : 12500; - break; - - case 0x23: - size = slower_rpm ? 21258 : 20833; - break; - - case 0x03: - size = slower_rpm ? 25500 : 25000; - break; - - case 0x25: - size = slower_rpm ? 42517 : 41666; - break; - - case 0x05: - size = slower_rpm ? 51000 : 50000; - break; - } - - return(size); -} - - -static int -td0_initialize(int drive) -{ - td0_t *dev = td0[drive]; - uint8_t header[12]; - int fm, head, track; - int track_count = 0; - int head_count = 0; - int track_spt; - int offset = 0; - int density = 0; - int temp_rate = 0; - uint32_t file_size; - uint16_t len, rep; - td0dsk_t disk_decode; - uint8_t *hs; - uint16_t size; - uint8_t *dbuf = dev->processed_buf; - uint32_t total_size = 0; - uint32_t pre_sector = 0; - uint32_t track_size = 0; - uint32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; - int i, j, k; - - if (dev->f == NULL) { - td0_log("TD0: Attempted to initialize without loading a file first\n"); - return(0); - } - - fseek(dev->f, 0, SEEK_END); - file_size = ftell(dev->f); - - if (file_size < 12) { - td0_log("TD0: File is too small to even contain the header\n"); - return(0); - } - - if (file_size > TD0_MAX_BUFSZ) { - td0_log("TD0: File exceeds the maximum size\n"); - return(0); - } - - fseek(dev->f, 0, SEEK_SET); - fread(header, 1, 12, dev->f); - head_count = header[9]; - - if (header[0] == 't') { - td0_log("TD0: File is compressed\n"); - disk_decode.fdd_file = dev->f; - state_init_Decode(&disk_decode); - disk_decode.fdd_file_offset = 12; - state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); - } else { - td0_log("TD0: File is uncompressed\n"); - fseek(dev->f, 12, SEEK_SET); - fread(dev->imagebuf, 1, file_size - 12, dev->f); - } - - if (header[7] & 0x80) - offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); - - track_spt = dev->imagebuf[offset]; - if (track_spt == 255) { - /* Empty file? */ - td0_log("TD0: File has no tracks\n"); - return(0); - } - - density = (header[5] >> 1) & 3; - - if (density == 3) { - td0_log("TD0: Unknown density\n"); - return(0); - } - - /* - * We determine RPM from the drive type as well as we possibly can. - * This byte is actually the BIOS floppy drive type read by Teledisk - * from the CMOS. - */ - switch (header[6]) { - case 0: /* 5.25" 360k in 1.2M drive: 360 rpm - CMOS Drive type: None, value probably - reused by Teledisk */ - case 2: /* 5.25" 1.2M 360 rpm */ - case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ - dev->default_track_flags = (density == 1) ? 0x20 : 0x21; - break; - - case 1: /* 5.25" 360k: 300 rpm */ - case 3: /* 3.5" 720k: 300 rpm */ - dev->default_track_flags = 0x02; - break; - - case 4: /* 3.5" 1.44M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : 0x02; - break; - - case 6: /* 3.5" 2.88M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); - break; - } - - dev->disk_flags = header[5] & 0x06; - - dev->track_width = (header[7] & 1) ^ 1; - - for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); - } - - while (track_spt != 255) { - track = dev->imagebuf[offset + 1]; - head = dev->imagebuf[offset + 2] & 1; - fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ - dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); - dev->track_in_file[track][head] = 1; - offset += 4; - track_size = fm ? 73 : 146; - pre_sector = fm ? 42 : 60; - - for (i = 0; i < track_spt; i++) { - hs = &dev->imagebuf[offset]; - offset += 6; - - dev->sects[track][head][i].track = hs[0]; - dev->sects[track][head][i].head = hs[1]; - dev->sects[track][head][i].sector = hs[2]; - dev->sects[track][head][i].size = hs[3]; - dev->sects[track][head][i].deleted = (hs[4] & 4) == 4; - dev->sects[track][head][i].bad_crc = (hs[4] & 2) == 2; - dev->sects[track][head][i].data = dbuf; - - size = 128 << hs[3]; - if ((total_size + size) >= TD0_MAX_BUFSZ) { - td0_log("TD0: Processed buffer overflow\n"); - return(0); - } - - if (hs[4] & 0x30) { - memset(dbuf, 0, size); - } else { - offset += 3; - switch (hs[8]) { - default: - td0_log("TD0: Image uses an unsupported sector data encoding\n"); - return(0); - - case 0: - memcpy(dbuf, &dev->imagebuf[offset], size); - offset += size; - break; - - case 1: - offset += 4; - k = (hs[9] + (hs[10] << 8)) * 2; - k = (k <= size) ? k : size; - for(j = 0; j < k; j += 2) { - dbuf[j] = hs[11]; - dbuf[j + 1] = hs[12]; - } - if (k < size) - memset(&(dbuf[k]), 0, size - k); - break; - - case 2: - k = 0; - while (k < size) { - len = dev->imagebuf[offset]; - rep = dev->imagebuf[offset + 1]; - offset += 2; - if (! len) { - memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); - offset += rep; - k += rep; - } else { - len = (1 << len); - rep = len * rep; - rep = ((rep + k) <= size) ? rep : (size - k); - for(j = 0; j < rep; j += len) - memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); - k += rep; - offset += len; - } - } - break; - } - } - - dbuf += size; - total_size += size; - track_size += (pre_sector + size + 2); - } - - if (track > track_count) - track_count = track; - - if (track_spt != 255) { - dev->track_spt[track][head] = track_spt; - - if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) { - dev->side_flags[track][head] |= 0x20; - } - - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); - minimum_gap3 = 12 * track_spt; - if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); - /* Set disk flags so that rotation speed is 2% slower. */ - dev->disk_flags |= (3 << 5); - if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - td0_log("TD0: Unable to fit the %i sectors in a track\n", track_spt); - return 0; - } - } - dev->calculated_gap3_lengths[track][head] = (raw_tsize - track_size - minimum_gap4 + (fm ? 73 : 146)) / track_spt; - - track_spt = dev->imagebuf[offset]; - } - } - - if ((dev->disk_flags & 0x60) == 0x60) - td0_log("TD0: Disk will rotate 2% below perfect RPM\n"); - - dev->tracks = track_count + 1; - - temp_rate = dev->default_track_flags & 7; - if ((dev->default_track_flags & 0x27) == 0x20) - temp_rate = 4; - dev->gap3_len = gap3_sizes[temp_rate][dev->sects[0][0][0].size][dev->track_spt[0][0]]; - if (! dev->gap3_len) - dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ - - if (head_count == 2) - dev->disk_flags |= 8; /* 2 sides */ - - if (dev->tracks <= 43) - dev->track_width &= ~1; - - dev->sides = head_count; - - dev->current_side_flags[0] = dev->side_flags[0][0]; - dev->current_side_flags[1] = dev->side_flags[0][1]; - - td0_log("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len); - - return(1); -} - - -static uint16_t -disk_flags(int drive) -{ - td0_t *dev = td0[drive]; - - return(dev->disk_flags); -} - - -static uint16_t -side_flags(int drive) -{ - td0_t *dev = td0[drive]; - int side = 0; - uint16_t sflags = 0; - - side = fdd_get_head(drive); - sflags = dev->current_side_flags[side]; - - return(sflags); -} - - -static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - td0_t *dev = td0[drive]; - int i = 0; - - dev->current_sector_index[side] = 0; - if (c != dev->track) return; - for (i = 0; i < dev->track_spt[c][side]; i++) { - if ((dev->sects[c][side][i].track == c) && - (dev->sects[c][side][i].head == h) && - (dev->sects[c][side][i].sector == r) && - (dev->sects[c][side][i].size == n)) { - dev->current_sector_index[side] = i; - } - } -} - - -static uint8_t -poll_read_data(int drive, int side, uint16_t pos) -{ - td0_t *dev = td0[drive]; - - return(dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); -} - - -static int -track_is_xdf(int drive, int side, int track) -{ - td0_t *dev = td0[drive]; - uint8_t id[4] = { 0, 0, 0, 0 }; - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; - - effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - - memset(dev->xdf_ordered_pos[side], 0, 256); - - if (! track) { - if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { - if (! side) { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } else { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } - - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { - if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { - high_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - - if ((id[2] >= 0x01) && (id[2] <= 0x08)) { - low_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } - } - - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { - dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; - return((dev->track_spt[track][side] == 19) ? 2 : 1); - } - } - } else { - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - effective_sectors++; - if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { - effective_sectors--; - } - if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { - xdf_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } - - if ((effective_sectors == 3) && (xdf_sectors == 3)) { - dev->current_side_flags[side] = 0x28; - return(1); /* 5.25" 2HD XDF */ - } - - if ((effective_sectors == 4) && (xdf_sectors == 4)) { - dev->current_side_flags[side] = 0x08; - return(2); /* 3.5" 2HD XDF */ - } - } - - return(0); -} - - -static int -track_is_interleave(int drive, int side, int track) -{ - td0_t *dev = td0[drive]; - int i, effective_sectors; - int track_spt; - - effective_sectors = 0; - - for (i = 0; i < 256; i++) - dev->interleave_ordered_pos[i][side] = 0; - - track_spt = dev->track_spt[track][side]; - - if (track_spt != 21) return(0); - - for (i = 0; i < track_spt; i++) { - if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { - effective_sectors++; - dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; - } - } - - if (effective_sectors == track_spt) return(1); - - return(0); -} - - -static void -td0_seek(int drive, int track) -{ - td0_t *dev = td0[drive]; - int side; - uint8_t id[4] = { 0, 0, 0, 0 }; - int sector, current_pos; - int ssize = 512; - int track_rate = 0; - int track_gap2 = 22; - int track_gap3 = 12; - int xdf_type = 0; - int interleave_type = 0; - int is_trackx = 0; - int xdf_spt = 0; - int xdf_sector = 0; - int ordered_pos = 0; - int real_sector = 0; - int actual_sector = 0; - - if (dev->f == NULL) return; - - if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; - - d86f_set_cur_track(drive, track); - - is_trackx = (track == 0) ? 0 : 1; - dev->track = track; - - dev->current_side_flags[0] = dev->side_flags[track][0]; - dev->current_side_flags[1] = dev->side_flags[track][1]; - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > dev->tracks) { - d86f_zero_track(drive); - return; - } - - for (side = 0; side < dev->sides; side++) { - track_rate = dev->current_side_flags[side] & 7; - if (!track_rate && (dev->current_side_flags[side] & 0x20)) - track_rate = 4; - track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; - if (! track_gap3) - track_gap3 = dev->calculated_gap3_lengths[track][side]; - - track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; - - xdf_type = track_is_xdf(drive, side, track); - - interleave_type = track_is_interleave(drive, side, track); - - current_pos = d86f_prepare_pretrack(drive, side, 0); - - if (! xdf_type) { - for (sector = 0; sector < dev->track_spt[track][side]; sector++) { - if (interleave_type == 0) { - real_sector = dev->sects[track][side][sector].sector; - actual_sector = sector; - } else { - real_sector = dmf_r[sector]; - actual_sector = dev->interleave_ordered_pos[real_sector][side]; - } - - id[0] = dev->sects[track][side][actual_sector].track; - id[1] = dev->sects[track][side][actual_sector].head; - id[2] = real_sector; - id[3] = dev->sects[track][side][actual_sector].size; - ssize = 128 << ((uint32_t) dev->sects[track][side][actual_sector].size); - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].deleted, dev->sects[track][side][actual_sector].bad_crc); - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } else { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ssize = 128 << ((uint32_t) id[3]); - ordered_pos = dev->xdf_ordered_pos[id[2]][side]; - if (is_trackx) { - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].deleted, dev->sects[track][side][ordered_pos].bad_crc); - } else { - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].deleted, dev->sects[track][side][ordered_pos].bad_crc); - } - - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } - } -} - - -void -td0_init(void) -{ - memset(td0, 0x00, sizeof(td0)); -} - - -void -td0_load(int drive, wchar_t *fn) -{ - td0_t *dev; - uint32_t i; - - d86f_unregister(drive); - - writeprot[drive] = 1; - - dev = (td0_t *)malloc(sizeof(td0_t)); - memset(dev, 0x00, sizeof(td0_t)); - td0[drive] = dev; - - dev->f = plat_fopen(fn, L"rb"); - if (dev->f == NULL) { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - fwriteprot[drive] = writeprot[drive]; - - if (! dsk_identify(drive)) { - td0_log("TD0: Not a valid Teledisk image\n"); - fclose(dev->f); - dev->f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } else { - td0_log("TD0: Valid Teledisk image\n"); - } - - /* Allocate the processing buffers. */ - i = 1024UL * 1024UL * 4UL; - dev->imagebuf = (uint8_t *)malloc(i); - memset(dev->imagebuf, 0x00, i); - dev->processed_buf = (uint8_t *)malloc(i); - memset(dev->processed_buf, 0x00, i); - - if (! td0_initialize(drive)) { - td0_log("TD0: Failed to initialize\n"); - fclose(dev->f); - free(dev->imagebuf); - free(dev->processed_buf); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } else { - td0_log("TD0: Initialized successfully\n"); - } - - /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; - d86f_set_version(drive, 0x0063); - - drives[drive].seek = td0_seek; - - d86f_common_handlers(drive); -} - - -void -td0_close(int drive) -{ - td0_t *dev = td0[drive]; - int i, j, k; - - if (dev == NULL) return; - - d86f_unregister(drive); - - free(dev->imagebuf); - free(dev->processed_buf); - - for (i = 0; i < 256; i++) { - for (j = 0; j < 2; j++) { - for (k = 0; k < 256; k++) - dev->sects[i][j][k].data = NULL; - } - } - - for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); - } - - if (dev->f != NULL) - fclose(dev->f); - - /* Release resources. */ - free(dev); - td0[drive] = NULL; -} diff --git a/src - Cópia/floppy/fdd_td0.h b/src - Cópia/floppy/fdd_td0.h deleted file mode 100644 index 8c3593241..000000000 --- a/src - Cópia/floppy/fdd_td0.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 Teledisk floppy image format. - * - * Version: @(#)floppy_td0.h 1.0.2 2018/03/17 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef EMU_FLOPPY_TD0_H -# define EMU_FLOPPY_TD0_H - - -extern void td0_init(void); -extern void td0_load(int drive, wchar_t *fn); -extern void td0_close(int drive); - - -#endif /*EMU_FLOPPY_TD0_H*/ diff --git a/src - Cópia/floppy/fdi2raw.c b/src - Cópia/floppy/fdi2raw.c deleted file mode 100644 index dee8dbfdf..000000000 --- a/src - Cópia/floppy/fdi2raw.c +++ /dev/null @@ -1,2206 +0,0 @@ -/* - * 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. - * - * FDI to raw bit stream converter - * FDI format created by Vincent "ApH" Joguin - * Tiny changes - function type fixes, multiple drives, - * addition of get_last_head and C++ callability by Thomas - * Harte. - * - * Version: @(#)fdi2raw.c 1.0.3 2018/04/29 - * - * Authors: Toni Wilen, - * and Vincent Joguin, - * Thomas Harte, - * - * Copyright 2001-2004 Toni Wilen. - * Copyright 2001-2004 Vincent Joguin. - * Copyright 2001 Thomas Harte. - * - * 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. - */ -#define STATIC_INLINE -#include -#include -#include -#include -#include -#include - -/* IF UAE */ -/*#include "sysconfig.h" -#include "sysdeps.h" -#include "zfile.h"*/ -/* ELSE */ -#define xmalloc malloc -#define HAVE_STDARG_H -#include "../86box.h" -#include "fdi2raw.h" - - -#undef DEBUG -#define VERBOSE -#undef VERBOSE - - -#ifdef ENABLE_FDI2RAW_LOG -int fdi2raw_do_log = ENABLE_FDI2RAW_LOG; -#endif - - -static void -fdi2raw_log(const char *fmt, ...) -{ -#ifdef ENABLE_FDI2RAW_LOG - va_list ap; - - if (fdi2raw_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -#ifdef DEBUG -static char *datalog(uae_u8 *src, int len) -{ - static char buf[1000]; - static int offset; - int i = 0, offset2; - - offset2 = offset; - buf[offset++]='\''; - while(len--) { - sprintf (buf + offset, "%02.2X", src[i]); - offset += 2; - i++; - if (i > 10) break; - } - buf[offset++]='\''; - buf[offset++] = 0; - if (offset >= 900) offset = 0; - return buf + offset2; -} -#else -static char *datalog(uae_u8 *src, int len) { return ""; } -#endif - -static int fdi_allocated; -#ifdef DEBUG -static void fdi_free (void *p) -{ - int size; - if (!p) - return; - size = ((int*)p)[-1]; - fdi_allocated -= size; - write_log ("%d freed (%d)\n", size, fdi_allocated); - free ((int*)p - 1); -} -static void *fdi_malloc (int size) -{ - void *p = xmalloc (size + sizeof (int)); - ((int*)p)[0] = size; - fdi_allocated += size; - write_log ("%d allocated (%d)\n", size, fdi_allocated); - return (int*)p + 1; -} -#else -#define fdi_free free -#define fdi_malloc xmalloc -#endif - -#define MAX_SRC_BUFFER 4194304 -#define MAX_DST_BUFFER 40000 -#define MAX_MFM_SYNC_BUFFER 60000 -#define MAX_TIMING_BUFFER 400000 -#define MAX_TRACKS 166 - -struct fdi_cache { - uae_u32 *avgp, *minp, *maxp; - uae_u8 *idxp; - int avg_free, idx_free, min_free, max_free; - uae_u32 totalavg, pulses, maxidx, indexoffset; - int weakbits; - int lowlevel; -}; - -struct fdi { - uae_u8 *track_src_buffer; - uae_u8 *track_src; - int track_src_len; - uae_u8 *track_dst_buffer; - uae_u8 *track_dst; - uae_u16 *track_dst_buffer_timing; - uae_u8 track_len; - uae_u8 track_type; - int current_track; - int last_track; - int last_head; - int rotation_speed; - int bit_rate; - int disk_type; - int write_protect; - int err; - uae_u8 header[2048]; - int track_offsets[MAX_TRACKS]; - FILE *file; - int out; - int mfmsync_offset; - int *mfmsync_buffer; - /* sector described only */ - int index_offset; - int encoding_type; - /* bit handling */ - int nextdrop; - struct fdi_cache cache[MAX_TRACKS]; -}; - -#define get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3])) -#define get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2])) -STATIC_INLINE void put_u32 (uae_u8 *d, uae_u32 v) -{ - d[0] = v >> 24; - d[1] = v >> 16; - d[2] = v >> 8; - d[3] = v; -} - -struct node { - uae_u16 v; - struct node *left; - struct node *right; -}; -typedef struct node NODE; - -static uae_u8 temp, temp2; - -static uae_u8 *expand_tree (uae_u8 *stream, NODE *node) -{ - if (temp & temp2) { - fdi_free (node->left); - node->left = 0; - fdi_free (node->right); - node->right = 0; - temp2 >>= 1; - if (!temp2) { - temp = *stream++; - temp2 = 0x80; - } - return stream; - } else { - uae_u8 *stream_temp; - temp2 >>= 1; - if (!temp2) { - temp = *stream++; - temp2 = 0x80; - } - node->left = fdi_malloc (sizeof (NODE)); - memset (node->left, 0, sizeof (NODE)); - stream_temp = expand_tree (stream, node->left); - node->right = fdi_malloc (sizeof (NODE)); - memset (node->right, 0, sizeof (NODE)); - return expand_tree (stream_temp, node->right); - } -} - -static uae_u8 *values_tree8 (uae_u8 *stream, NODE *node) -{ - if (node->left == 0) { - node->v = *stream++; - return stream; - } else { - uae_u8 *stream_temp = values_tree8 (stream, node->left); - return values_tree8 (stream_temp, node->right); - } -} - -static uae_u8 *values_tree16 (uae_u8 *stream, NODE *node) -{ - if (node->left == 0) { - uae_u16 high_8_bits = (*stream++) << 8; - node->v = high_8_bits | (*stream++); - return stream; - } else { - uae_u8 *stream_temp = values_tree16 (stream, node->left); - return values_tree16 (stream_temp, node->right); - } -} - -static void free_nodes (NODE *node) -{ - if (node) { - free_nodes (node->left); - free_nodes (node->right); - fdi_free (node); - } -} - -static uae_u32 sign_extend16 (uae_u32 v) -{ - if (v & 0x8000) - v |= 0xffff0000; - return v; -} - -static uae_u32 sign_extend8 (uae_u32 v) -{ - if (v & 0x80) - v |= 0xffffff00; - return v; -} - -static void fdi_decode (uae_u8 *stream, int size, uae_u8 *out) -{ - int i; - uae_u8 sign_extend, sixteen_bit, sub_stream_shift; - NODE root; - NODE *current_node; - - memset (out, 0, size * 4); - sub_stream_shift = 1; - while (sub_stream_shift) { - - /* sub-stream header decode */ - sign_extend = *stream++; - sub_stream_shift = sign_extend & 0x7f; - sign_extend &= 0x80; - sixteen_bit = (*stream++) & 0x80; - - /* huffman tree architecture decode */ - temp = *stream++; - temp2 = 0x80; - stream = expand_tree (stream, &root); - if (temp2 == 0x80) - stream--; - - /* huffman output values decode */ - if (sixteen_bit) - stream = values_tree16 (stream, &root); - else - stream = values_tree8 (stream, &root); - - /* sub-stream data decode */ - temp2 = 0; - for (i = 0; i < size; i++) { - uae_u32 v; - uae_u8 decode = 1; - current_node = &root; - while (decode) { - if (current_node->left == 0) { - decode = 0; - } else { - temp2 >>= 1; - if (!temp2) { - temp2 = 0x80; - temp = *stream++; - } - if (temp & temp2) - current_node = current_node->right; - else - current_node = current_node->left; - } - } - v = ((uae_u32*)out)[i]; - if (sign_extend) { - if (sixteen_bit) - v |= sign_extend16 (current_node->v) << sub_stream_shift; - else - v |= sign_extend8 (current_node->v) << sub_stream_shift; - } else { - v |= current_node->v << sub_stream_shift; - } - ((uae_u32*)out)[i] = v; - } - free_nodes (root.left); - free_nodes (root.right); - } -} - - -static int decode_raw_track (FDI *fdi) -{ - int size = get_u32(fdi->track_src); - memcpy (fdi->track_dst, fdi->track_src, (size + 7) >> 3); - fdi->track_src += (size + 7) >> 3; - return size; -} - -/* unknown track */ -static void zxx (FDI *fdi) -{ - fdi2raw_log("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); -} -/* unsupported track */ -#if 0 -static void zyy (FDI *fdi) -{ - fdi2raw_log("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type); -} -#endif -/* empty track */ -static void track_empty (FDI *fdi) -{ - return; -} - -/* unknown sector described type */ -static void dxx (FDI *fdi) -{ - fdi2raw_log("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type); - fdi->err = 1; -} -/* add position of mfm sync bit */ -static void add_mfm_sync_bit (FDI *fdi) -{ - if (fdi->nextdrop) { - fdi->nextdrop = 0; - return; - } - fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out; - if (fdi->out == 0) { - fdi2raw_log("illegal position for mfm sync bit, offset=%d\n",fdi->out); - fdi->err = 1; - } - if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) { - fdi->mfmsync_offset = 0; - fdi2raw_log("mfmsync buffer overflow\n"); - fdi->err = 1; - } - fdi->out++; -} - -#define BIT_BYTEOFFSET ((fdi->out) >> 3) -#define BIT_BITOFFSET (7-((fdi->out)&7)) - -/* add one bit */ -static void bit_add (FDI *fdi, int bit) -{ - if (fdi->nextdrop) { - fdi->nextdrop = 0; - return; - } - fdi->track_dst[BIT_BYTEOFFSET] &= ~(1 << BIT_BITOFFSET); - if (bit) - fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET); - fdi->out++; - if (fdi->out >= MAX_DST_BUFFER * 8) { - fdi2raw_log("destination buffer overflow\n"); - fdi->err = 1; - fdi->out = 1; - } -} -/* add bit and mfm sync bit */ -static void bit_mfm_add (FDI *fdi, int bit) -{ - add_mfm_sync_bit (fdi); - bit_add (fdi, bit); -} -/* remove following bit */ -static void bit_drop_next (FDI *fdi) -{ - if (fdi->nextdrop > 0) { - fdi2raw_log("multiple bit_drop_next() called"); - } else if (fdi->nextdrop < 0) { - fdi->nextdrop = 0; - fdi2raw_log(":DNN:"); - return; - } - fdi2raw_log(":DN:"); - fdi->nextdrop = 1; -} - -/* ignore next bit_drop_next() */ -static void bit_dedrop (FDI *fdi) -{ - if (fdi->nextdrop) { - fdi2raw_log("bit_drop_next called before bit_dedrop"); - } - fdi->nextdrop = -1; - fdi2raw_log(":BDD:"); -} - -/* add one byte */ -static void byte_add (FDI *fdi, uae_u8 v) -{ - int i; - for (i = 7; i >= 0; i--) - bit_add (fdi, v & (1 << i)); -} -/* add one word */ -static void word_add (FDI *fdi, uae_u16 v) -{ - byte_add (fdi, (uae_u8)(v >> 8)); - byte_add (fdi, (uae_u8)v); -} -/* add one byte and mfm encode it */ -static void byte_mfm_add (FDI *fdi, uae_u8 v) -{ - int i; - for (i = 7; i >= 0; i--) - bit_mfm_add (fdi, v & (1 << i)); -} -/* add multiple bytes and mfm encode them */ -static void bytes_mfm_add (FDI *fdi, uae_u8 v, int len) -{ - int i; - for (i = 0; i < len; i++) byte_mfm_add (fdi, v); -} -/* add one mfm encoded word and re-mfm encode it */ -static void word_post_mfm_add (FDI *fdi, uae_u16 v) -{ - int i; - for (i = 14; i >= 0; i -= 2) - bit_mfm_add (fdi, v & (1 << i)); -} - -/* bit 0 */ -static void s00(FDI *fdi) { bit_add (fdi, 0); } -/* bit 1*/ -static void s01(FDI *fdi) { bit_add (fdi, 1); } -/* 4489 */ -static void s02(FDI *fdi) { word_add (fdi, 0x4489); } -/* 5224 */ -static void s03(FDI *fdi) { word_add (fdi, 0x5224); } -/* mfm sync bit */ -static void s04(FDI *fdi) { add_mfm_sync_bit (fdi); } -/* RLE MFM-encoded data */ -static void s08(FDI *fdi) -{ - int bytes = *fdi->track_src++; - uae_u8 byte = *fdi->track_src++; - if (bytes == 0) bytes = 256; - fdi2raw_log("s08:len=%d,data=%02.2X",bytes,byte); - while(bytes--) byte_add (fdi, byte); -} -/* RLE MFM-decoded data */ -static void s09(FDI *fdi) -{ - int bytes = *fdi->track_src++; - uae_u8 byte = *fdi->track_src++; - if (bytes == 0) bytes = 256; - bit_drop_next (fdi); - fdi2raw_log("s09:len=%d,data=%02.2X",bytes,byte); - while(bytes--) byte_mfm_add (fdi, byte); -} -/* MFM-encoded data */ -static void s0a(FDI *fdi) -{ - int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1]; - uae_u8 b; - fdi->track_src += 2; - fdi2raw_log("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8)); - while (bits >= 8) { - byte_add (fdi, *fdi->track_src++); - bits -= 8; - } - if (bits > 0) { - i = 7; - b = *fdi->track_src++; - while (bits--) { - bit_add (fdi, b & (1 << i)); - i--; - } - } -} -/* MFM-encoded data */ -static void s0b(FDI *fdi) -{ - int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536; - uae_u8 b; - fdi->track_src += 2; - fdi2raw_log("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8)); - while (bits >= 8) { - byte_add (fdi, *fdi->track_src++); - bits -= 8; - } - if (bits > 0) { - i = 7; - b = *fdi->track_src++; - while (bits--) { - bit_add (fdi, b & (1 << i)); - i--; - } - } -} -/* MFM-decoded data */ -static void s0c(FDI *fdi) -{ - int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1]; - uae_u8 b; - fdi->track_src += 2; - bit_drop_next (fdi); - fdi2raw_log("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8)); - while (bits >= 8) { - byte_mfm_add (fdi, *fdi->track_src++); - bits -= 8; - } - if (bits > 0) { - i = 7; - b = *fdi->track_src++; - while(bits--) { - bit_mfm_add (fdi, b & (1 << i)); - i--; - } - } -} -/* MFM-decoded data */ -static void s0d(FDI *fdi) -{ - int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536; - uae_u8 b; - fdi->track_src += 2; - bit_drop_next (fdi); - fdi2raw_log("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8)); - while (bits >= 8) { - byte_mfm_add (fdi, *fdi->track_src++); - bits -= 8; - } - if (bits > 0) { - i = 7; - b = *fdi->track_src++; - while(bits--) { - bit_mfm_add (fdi, b & (1 << i)); - i--; - } - } -} - -/* ***** */ -/* AMIGA */ -/* ***** */ - -/* just for testing integrity of Amiga sectors */ - -/*static void rotateonebit (uae_u8 *start, uae_u8 *end, int shift) -{ - if (shift == 0) - return; - while (start <= end) { - start[0] <<= shift; - start[0] |= start[1] >> (8 - shift); - start++; - } -}*/ - -/*static uae_u16 getmfmword (uae_u8 *mbuf) -{ - uae_u32 v; - - v = (mbuf[0] << 8) | (mbuf[1] << 0); - if (check_offset == 0) - return v; - v <<= 8; - v |= mbuf[2]; - v >>= check_offset; - return v; -}*/ - -#define MFMMASK 0x55555555 -/*static uae_u32 getmfmlong (uae_u8 * mbuf) -{ - return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK; -}*/ - -#if 0 -static int amiga_check_track (FDI *fdi) -{ - int i, j, secwritten = 0; - int fwlen = fdi->out / 8; - int length = 2 * fwlen; - int drvsec = 11; - uae_u32 odd, even, chksum, id, dlong; - uae_u8 *secdata; - uae_u8 secbuf[544]; - uae_u8 bigmfmbuf[60000]; - uae_u8 *mbuf, *mbuf2, *mend; - char sectable[22]; - uae_u8 *raw = fdi->track_dst_buffer; - int slabel, off; - int ok = 1; - - memset (bigmfmbuf, 0, sizeof (bigmfmbuf)); - mbuf = bigmfmbuf; - check_offset = 0; - for (i = 0; i < (fdi->out + 7) / 8; i++) - *mbuf++ = raw[i]; - off = fdi->out & 7; -#if 1 - if (off > 0) { - mbuf--; - *mbuf &= ~((1 << (8 - off)) - 1); - } - j = 0; - while (i < (fdi->out + 7) / 8 + 600) { - *mbuf++ |= (raw[j] >> off) | ((raw[j + 1]) << (8 - off)); - j++; - i++; - } -#endif - mbuf = bigmfmbuf; - - memset (sectable, 0, sizeof (sectable)); - mend = bigmfmbuf + length; - mend -= (4 + 16 + 8 + 512); - - while (secwritten < drvsec) { - int trackoffs; - - for (;;) { - rotateonebit (bigmfmbuf, mend, 1); - if (getmfmword (mbuf) == 0) - break; - if (secwritten == 10) { - mbuf[0] = 0x44; - mbuf[1] = 0x89; - } - if (check_offset > 7) { - check_offset = 0; - mbuf++; - if (mbuf >= mend || *mbuf == 0) - break; - } - if (getmfmword (mbuf) == 0x4489) - break; - } - if (mbuf >= mend || *mbuf == 0) - break; - - rotateonebit (bigmfmbuf, mend, check_offset); - check_offset = 0; - - while (getmfmword (mbuf) == 0x4489) - mbuf+= 1 * 2; - mbuf2 = mbuf + 8; - - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2 * 2); - mbuf += 4 * 2; - id = (odd << 1) | even; - - trackoffs = (id & 0xff00) >> 8; - if (trackoffs + 1 > drvsec) { - fdi2raw_log("illegal sector offset %d\n",trackoffs); - ok = 0; - mbuf = mbuf2; - continue; - } - if ((id >> 24) != 0xff) { - fdi2raw_log("sector %d format type %02.2X?\n", trackoffs, id >> 24); - ok = 0; - } - chksum = odd ^ even; - slabel = 0; - for (i = 0; i < 4; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 8 * 2); - mbuf += 2* 2; - - dlong = (odd << 1) | even; - if (dlong) slabel = 1; - chksum ^= odd ^ even; - } - mbuf += 8 * 2; - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2 * 2); - mbuf += 4 * 2; - if (((odd << 1) | even) != chksum) { - fdi2raw_log("sector %d header crc error\n", trackoffs); - ok = 0; - mbuf = mbuf2; - continue; - } - fdi2raw_log("sector %d header crc ok\n", trackoffs); - if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) { - fdi2raw_log("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000) >> 16); - ok++; - mbuf = mbuf2; - continue; - } - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2 * 2); - mbuf += 4 * 2; - chksum = (odd << 1) | even; - secdata = secbuf + 32; - for (i = 0; i < 128; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 256 * 2); - mbuf += 2 * 2; - dlong = (odd << 1) | even; - *secdata++ = (uae_u8) (dlong >> 24); - *secdata++ = (uae_u8) (dlong >> 16); - *secdata++ = (uae_u8) (dlong >> 8); - *secdata++ = (uae_u8) dlong; - chksum ^= odd ^ even; - } - mbuf += 256 * 2; - if (chksum) { - fdi2raw_log("sector %d data checksum error\n",trackoffs); - ok = 0; - } else if (sectable[trackoffs]) { - fdi2raw_log("sector %d already found?\n", trackoffs); - mbuf = mbuf2; - } else { - fdi2raw_log("sector %d ok\n",trackoffs); - if (slabel) fdi2raw_log("(non-empty sector header)\n"); - sectable[trackoffs] = 1; - secwritten++; - if (trackoffs == 9) - mbuf += 0x228; - } - } - for (i = 0; i < drvsec; i++) { - if (!sectable[i]) { - fdi2raw_log("sector %d missing\n", i); - ok = 0; - } - } - return ok; -} -#endif - -static void amiga_data_raw (FDI *fdi, uae_u8 *secbuf, uae_u8 *crc, int len) -{ - int i; - uae_u8 crcbuf[4]; - - if (!crc) { - memset (crcbuf, 0, 4); - } else { - memcpy (crcbuf, crc ,4); - } - for (i = 0; i < 4; i++) - byte_mfm_add (fdi, crcbuf[i]); - for (i = 0; i < len; i++) - byte_mfm_add (fdi, secbuf[i]); -} - -static void amiga_data (FDI *fdi, uae_u8 *secbuf) -{ - uae_u16 mfmbuf[4 + 512]; - uae_u32 dodd, deven, dck; - int i; - - for (i = 0; i < 512; i += 4) { - deven = ((secbuf[i + 0] << 24) | (secbuf[i + 1] << 16) - | (secbuf[i + 2] << 8) | (secbuf[i + 3])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[(i >> 1) + 4] = (uae_u16) (dodd >> 16); - mfmbuf[(i >> 1) + 5] = (uae_u16) dodd; - mfmbuf[(i >> 1) + 256 + 4] = (uae_u16) (deven >> 16); - mfmbuf[(i >> 1) + 256 + 5] = (uae_u16) deven; - } - dck = 0; - for (i = 4; i < 4 + 512; i += 2) - dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - deven = dodd = dck; - dodd >>= 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[0] = (uae_u16) (dodd >> 16); - mfmbuf[1] = (uae_u16) dodd; - mfmbuf[2] = (uae_u16) (deven >> 16); - mfmbuf[3] = (uae_u16) deven; - - for (i = 0; i < 4 + 512; i ++) - word_post_mfm_add (fdi, mfmbuf[i]); -} - -static void amiga_sector_header (FDI *fdi, uae_u8 *header, uae_u8 *data, int sector, int untilgap) -{ - uae_u8 headerbuf[4], databuf[16]; - uae_u32 deven, dodd, hck; - uae_u16 mfmbuf[24]; - int i; - - byte_mfm_add (fdi, 0); - byte_mfm_add (fdi, 0); - word_add (fdi, 0x4489); - word_add (fdi, 0x4489); - if (header) { - memcpy (headerbuf, header, 4); - } else { - headerbuf[0] = 0xff; - headerbuf[1] = (uae_u8)fdi->current_track; - headerbuf[2] = (uae_u8)sector; - headerbuf[3] = (uae_u8)untilgap; - } - if (data) - memcpy (databuf, data, 16); - else - memset (databuf, 0, 16); - - deven = ((headerbuf[0] << 24) | (headerbuf[1] << 16) - | (headerbuf[2] << 8) | (headerbuf[3])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[0] = (uae_u16) (dodd >> 16); - mfmbuf[1] = (uae_u16) dodd; - mfmbuf[2] = (uae_u16) (deven >> 16); - mfmbuf[3] = (uae_u16) deven; - for (i = 0; i < 16; i += 4) { - deven = ((databuf[i] << 24) | (databuf[i + 1] << 16) - | (databuf[i + 2] << 8) | (databuf[i + 3])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[(i >> 1) + 0 + 4] = (uae_u16) (dodd >> 16); - mfmbuf[(i >> 1) + 0 + 5] = (uae_u16) dodd; - mfmbuf[(i >> 1) + 8 + 4] = (uae_u16) (deven >> 16); - mfmbuf[(i >> 1) + 8 + 5] = (uae_u16) deven; - } - hck = 0; - for (i = 0; i < 4 + 16; i += 2) - hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - deven = dodd = hck; - dodd >>= 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[20] = (uae_u16) (dodd >> 16); - mfmbuf[21] = (uae_u16) dodd; - mfmbuf[22] = (uae_u16) (deven >> 16); - mfmbuf[23] = (uae_u16) deven; - - for (i = 0; i < 4 + 16 + 4; i ++) - word_post_mfm_add (fdi, mfmbuf[i]); -} - -/* standard super-extended Amiga sector header */ -static void s20(FDI *fdi) -{ - bit_drop_next (fdi); - fdi2raw_log("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16)); - amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0); - fdi->track_src += 4 + 16; -} -/* standard extended Amiga sector header */ -static void s21(FDI *fdi) -{ - bit_drop_next (fdi); - fdi2raw_log("s21:header=%s", datalog(fdi->track_src, 4)); - amiga_sector_header (fdi, fdi->track_src, 0, 0, 0); - fdi->track_src += 4; -} -/* standard Amiga sector header */ -static void s22(FDI *fdi) -{ - bit_drop_next (fdi); - fdi2raw_log("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]); - amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]); - fdi->track_src += 2; -} -/* standard 512-byte, CRC-correct Amiga data */ -static void s23(FDI *fdi) -{ - fdi2raw_log("s23:data=%s", datalog (fdi->track_src, 512)); - amiga_data (fdi, fdi->track_src); - fdi->track_src += 512; -} -/* not-decoded, 128*2^x-byte, CRC-correct Amiga data */ -static void s24(FDI *fdi) -{ - int shift = *fdi->track_src++; - fdi2raw_log("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift)); - amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift); - fdi->track_src += 128 << shift; -} -/* not-decoded, 128*2^x-byte, CRC-incorrect Amiga data */ -static void s25(FDI *fdi) -{ - int shift = *fdi->track_src++; - fdi2raw_log("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift)); - amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift); - fdi->track_src += 4 + (128 << shift); -} -/* standard extended Amiga sector */ -static void s26(FDI *fdi) -{ - s21 (fdi); - fdi2raw_log("s26:data=%s", datalog (fdi->track_src, 512)); - amiga_data (fdi, fdi->track_src); - fdi->track_src += 512; -} -/* standard short Amiga sector */ -static void s27(FDI *fdi) -{ - s22 (fdi); - fdi2raw_log("s27:data=%s", datalog (fdi->track_src, 512)); - amiga_data (fdi, fdi->track_src); - fdi->track_src += 512; -} - -/* *** */ -/* IBM */ -/* *** */ - -static uae_u16 ibm_crc (uae_u8 byte, int reset) -{ - static uae_u16 crc; - int i; - - if (reset) crc = 0xcdb4; - for (i = 0; i < 8; i++) { - if (crc & 0x8000) { - crc <<= 1; - if (!(byte & 0x80)) crc ^= 0x1021; - } else { - crc <<= 1; - if (byte & 0x80) crc ^= 0x1021; - } - byte <<= 1; - } - return crc; -} - -static void ibm_data (FDI *fdi, uae_u8 *data, uae_u8 *crc, int len) -{ - int i; - uae_u8 crcbuf[2]; - uae_u16 crcv = 0; - - word_add (fdi, 0x4489); - word_add (fdi, 0x4489); - word_add (fdi, 0x4489); - byte_mfm_add (fdi, 0xfb); - ibm_crc (0xfb, 1); - for (i = 0; i < len; i++) { - byte_mfm_add (fdi, data[i]); - crcv = ibm_crc (data[i], 0); - } - if (!crc) { - crc = crcbuf; - crc[0] = (uae_u8)(crcv >> 8); - crc[1] = (uae_u8)crcv; - } - byte_mfm_add (fdi, crc[0]); - byte_mfm_add (fdi, crc[1]); -} - -static void ibm_sector_header (FDI *fdi, uae_u8 *data, uae_u8 *crc, int secnum, int pre) -{ - uae_u8 secbuf[5]; - uae_u8 crcbuf[2]; - uae_u16 crcv; - int i; - - if (pre) - bytes_mfm_add (fdi, 0, 12); - word_add (fdi, 0x4489); - word_add (fdi, 0x4489); - word_add (fdi, 0x4489); - secbuf[0] = 0xfe; - if (secnum >= 0) { - secbuf[1] = (uae_u8)(fdi->current_track/2); - secbuf[2] = (uae_u8)(fdi->current_track%2); - secbuf[3] = (uae_u8)secnum; - secbuf[4] = 2; - } else { - memcpy (secbuf + 1, data, 4); - } - ibm_crc (secbuf[0], 1); - ibm_crc (secbuf[1], 0); - ibm_crc (secbuf[2], 0); - ibm_crc (secbuf[3], 0); - crcv = ibm_crc (secbuf[4], 0); - if (crc) { - memcpy (crcbuf, crc, 2); - } else { - crcbuf[0] = (uae_u8)(crcv >> 8); - crcbuf[1] = (uae_u8)crcv; - } - /* data */ - for (i = 0;i < 5; i++) - byte_mfm_add (fdi, secbuf[i]); - /* crc */ - byte_mfm_add (fdi, crcbuf[0]); - byte_mfm_add (fdi, crcbuf[1]); -} - -/* standard IBM index address mark */ -static void s10(FDI *fdi) -{ - bit_drop_next (fdi); - bytes_mfm_add (fdi, 0, 12); - word_add (fdi, 0x5224); - word_add (fdi, 0x5224); - word_add (fdi, 0x5224); - byte_mfm_add (fdi, 0xfc); -} -/* standard IBM pre-gap */ -static void s11(FDI *fdi) -{ - bit_drop_next (fdi); - bytes_mfm_add (fdi, 0x4e, 78); - bit_dedrop (fdi); - s10 (fdi); - bytes_mfm_add (fdi, 0x4e, 50); -} -/* standard ST pre-gap */ -static void s12(FDI *fdi) -{ - bit_drop_next (fdi); - bytes_mfm_add (fdi, 0x4e, 78); -} -/* standard extended IBM sector header */ -static void s13(FDI *fdi) -{ - bit_drop_next (fdi); - fdi2raw_log("s13:header=%s", datalog (fdi->track_src, 4)); - ibm_sector_header (fdi, fdi->track_src, 0, -1, 1); - fdi->track_src += 4; -} -/* standard mini-extended IBM sector header */ -static void s14(FDI *fdi) -{ - fdi2raw_log("s14:header=%s", datalog (fdi->track_src, 4)); - ibm_sector_header (fdi, fdi->track_src, 0, -1, 0); - fdi->track_src += 4; -} -/* standard short IBM sector header */ -static void s15(FDI *fdi) -{ - bit_drop_next (fdi); - fdi2raw_log("s15:sector=%d", *fdi->track_src); - ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1); -} -/* standard mini-short IBM sector header */ -static void s16(FDI *fdi) -{ - fdi2raw_log("s16:track=%d", *fdi->track_src); - ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0); -} -/* standard CRC-incorrect mini-extended IBM sector header */ -static void s17(FDI *fdi) -{ - fdi2raw_log("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2)); - ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0); - fdi->track_src += 4 + 2; -} -/* standard CRC-incorrect mini-short IBM sector header */ -static void s18(FDI *fdi) -{ - fdi2raw_log("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4)); - ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0); - fdi->track_src += 1 + 4; -} -/* standard 512-byte CRC-correct IBM data */ -static void s19(FDI *fdi) -{ - fdi2raw_log("s19:data=%s", datalog (fdi->track_src , 512)); - ibm_data (fdi, fdi->track_src, 0, 512); - fdi->track_src += 512; -} -/* standard 128*2^x-byte-byte CRC-correct IBM data */ -static void s1a(FDI *fdi) -{ - int shift = *fdi->track_src++; - fdi2raw_log("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift)); - ibm_data (fdi, fdi->track_src, 0, 128 << shift); - fdi->track_src += 128 << shift; -} -/* standard 128*2^x-byte-byte CRC-incorrect IBM data */ -static void s1b(FDI *fdi) -{ - int shift = *fdi->track_src++; - fdi2raw_log("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift)); - ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift); - fdi->track_src += (128 << shift) + 2; -} -/* standard extended IBM sector */ -static void s1c(FDI *fdi) -{ - int shift = fdi->track_src[3]; - s13 (fdi); - bytes_mfm_add (fdi, 0x4e, 22); - bytes_mfm_add (fdi, 0x00, 12); - ibm_data (fdi, fdi->track_src, 0, 128 << shift); - fdi->track_src += 128 << shift; -} -/* standard short IBM sector */ -static void s1d(FDI *fdi) -{ - s15 (fdi); - bytes_mfm_add (fdi, 0x4e, 22); - bytes_mfm_add (fdi, 0x00, 12); - s19 (fdi); -} - -/* end marker */ -static void sff(FDI *fdi) -{ -} - -typedef void (*decode_described_track_func)(FDI*); - -static decode_described_track_func decode_sectors_described_track[] = -{ - s00,s01,s02,s03,s04,dxx,dxx,dxx,s08,s09,s0a,s0b,s0c,s0d,dxx,dxx, /* 00-0F */ - s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s1a,s1b,s1c,s1d,dxx,dxx, /* 10-1F */ - s20,s21,s22,s23,s24,s25,s26,s27,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 20-2F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 30-3F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 40-4F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 50-5F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 60-6F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 70-7F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 80-8F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 90-9F */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* A0-AF */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* B0-BF */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* C0-CF */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* D0-DF */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* E0-EF */ - dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,sff /* F0-FF */ -}; - -static void track_amiga (struct fdi *fdi, int first_sector, int max_sector) -{ - int i; - - bit_add (fdi, 0); - bit_drop_next (fdi); - for (i = 0; i < max_sector; i++) { - amiga_sector_header (fdi, 0, 0, first_sector, max_sector - i); - amiga_data (fdi, fdi->track_src + first_sector * 512); - first_sector++; - if (first_sector >= max_sector) first_sector = 0; - } - bytes_mfm_add (fdi, 0, 260); /* gap */ -} -static void track_atari_st (struct fdi *fdi, int max_sector) -{ - int i, gap3 = 0; - uae_u8 *p = fdi->track_src; - - switch (max_sector) - { - case 9: - gap3 = 40; - break; - case 10: - gap3 = 24; - break; - } - s15 (fdi); - for (i = 0; i < max_sector; i++) { - byte_mfm_add (fdi, 0x4e); - byte_mfm_add (fdi, 0x4e); - ibm_sector_header (fdi, 0, 0, fdi->current_track, 1); - ibm_data (fdi, p + i * 512, 0, 512); - bytes_mfm_add (fdi, 0x4e, gap3); - } - bytes_mfm_add (fdi, 0x4e, 660 - gap3); - fdi->track_src += fdi->track_len * 256; -} -static void track_pc (struct fdi *fdi, int max_sector) -{ - int i, gap3; - uae_u8 *p = fdi->track_src; - - switch (max_sector) - { - case 8: - gap3 = 116; - break; - case 9: - gap3 = 54; - break; - default: - gap3 = 100; /* fixme */ - break; - } - s11 (fdi); - for (i = 0; i < max_sector; i++) { - byte_mfm_add (fdi, 0x4e); - byte_mfm_add (fdi, 0x4e); - ibm_sector_header (fdi, 0, 0, fdi->current_track, 1); - ibm_data (fdi, p + i * 512, 0, 512); - bytes_mfm_add (fdi, 0x4e, gap3); - } - bytes_mfm_add (fdi, 0x4e, 600 - gap3); - fdi->track_src += fdi->track_len * 256; -} - -/* amiga dd */ -static void track_amiga_dd (struct fdi *fdi) -{ - uae_u8 *p = fdi->track_src; - track_amiga (fdi, fdi->track_len >> 4, 11); - fdi->track_src = p + (fdi->track_len & 15) * 512; -} -/* amiga hd */ -static void track_amiga_hd (struct fdi *fdi) -{ - uae_u8 *p = fdi->track_src; - track_amiga (fdi, 0, 22); - fdi->track_src = p + fdi->track_len * 256; -} -/* atari st 9 sector */ -static void track_atari_st_9 (struct fdi *fdi) -{ - track_atari_st (fdi, 9); -} -/* atari st 10 sector */ -static void track_atari_st_10 (struct fdi *fdi) -{ - track_atari_st (fdi, 10); -} -/* pc 8 sector */ -static void track_pc_8 (struct fdi *fdi) -{ - track_pc (fdi, 8); -} -/* pc 9 sector */ -static void track_pc_9 (struct fdi *fdi) -{ - track_pc (fdi, 9); -} -/* pc 15 sector */ -static void track_pc_15 (struct fdi *fdi) -{ - track_pc (fdi, 15); -} -/* pc 18 sector */ -static void track_pc_18 (struct fdi *fdi) -{ - track_pc (fdi, 18); -} -/* pc 36 sector */ -static void track_pc_36 (struct fdi *fdi) -{ - track_pc (fdi, 36); -} - -typedef void (*decode_normal_track_func)(FDI*); - -static decode_normal_track_func decode_normal_track[] = -{ - track_empty, /* 0 */ - track_amiga_dd, track_amiga_hd, /* 1-2 */ - track_atari_st_9, track_atari_st_10, /* 3-4 */ - track_pc_8, track_pc_9, track_pc_15, track_pc_18, track_pc_36, /* 5-9 */ - zxx,zxx,zxx,zxx,zxx /* A-F */ -}; - -static void fix_mfm_sync (FDI *fdi) -{ - int i, pos, off1, off2, off3, mask1, mask2, mask3; - - for (i = 0; i < fdi->mfmsync_offset; i++) { - pos = fdi->mfmsync_buffer[i]; - off1 = (pos - 1) >> 3; - off2 = (pos + 1) >> 3; - off3 = pos >> 3; - mask1 = 1 << (7 - ((pos - 1) & 7)); - mask2 = 1 << (7 - ((pos + 1) & 7)); - mask3 = 1 << (7 - (pos & 7)); - if (!(fdi->track_dst[off1] & mask1) && !(fdi->track_dst[off2] & mask2)) - fdi->track_dst[off3] |= mask3; - else - fdi->track_dst[off3] &= ~mask3; - } -} - -static int handle_sectors_described_track (FDI *fdi) -{ - int oldout; - uae_u8 *start_src = fdi->track_src ; - fdi->encoding_type = *fdi->track_src++; - fdi->index_offset = get_u32(fdi->track_src); - fdi->index_offset >>= 8; - fdi->track_src += 3; - fdi2raw_log("sectors_described, index offset: %d\n",fdi->index_offset); - - do { - fdi->track_type = *fdi->track_src++; - fdi2raw_log("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type); - oldout = fdi->out; - decode_sectors_described_track[fdi->track_type](fdi); - fdi2raw_log(" %d\n", fdi->out - oldout); - oldout = fdi->out; - if (fdi->out < 0 || fdi->err) { - fdi2raw_log("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out); - return -1; - } - if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) { - fdi2raw_log("source buffer overrun, previous type: %02.2X\n", fdi->track_type); - return -1; - } - } while (fdi->track_type != 0xff); - fdi2raw_log("\n"); - fix_mfm_sync (fdi); - return fdi->out; -} - -static uae_u8 *fdi_decompress (int pulses, uae_u8 *sizep, uae_u8 *src, int *dofree) -{ - uae_u32 size = get_u24 (sizep); - uae_u32 *dst2; - int len = size & 0x3fffff; - uae_u8 *dst; - int mode = size >> 22, i; - - *dofree = 0; - if (mode == 0 && pulses * 2 > len) - mode = 1; - if (mode == 0) { - dst2 = (uae_u32*)src; - dst = src; - for (i = 0; i < pulses; i++) { - *dst2++ = get_u32 (src); - src += 4; - } - } else if (mode == 1) { - dst = fdi_malloc (pulses *4); - *dofree = 1; - fdi_decode (src, pulses, dst); - } else { - dst = 0; - } - return dst; -} - -static void dumpstream(int track, uae_u8 *stream, int len) -{ -#if 0 - char name[100]; - FILE *f; - - sprintf (name, "track_%d.raw", track); - f = fopen(name, "wb"); - fwrite (stream, 1, len * 4, f); - fclose (f); -#endif -} - -static int bitoffset; - -STATIC_INLINE void addbit (uae_u8 *p, int bit) -{ - int off1 = bitoffset / 8; - int off2 = bitoffset % 8; - p[off1] |= bit << (7 - off2); - bitoffset++; -} - - -struct pulse_sample { - uint32_t size; - int number_of_bits; -}; - - -#define FDI_MAX_ARRAY 10 /* change this value as you want */ -static int pulse_limitval = 15; /* tolerance of 15% */ -static struct pulse_sample psarray[FDI_MAX_ARRAY]; -static int array_index; -static unsigned long total; -static int totaldiv; - -static void init_array(uint32_t standard_MFM_2_bit_cell_size, int nb_of_bits) -{ - int i; - - for (i = 0; i < FDI_MAX_ARRAY; i++) { - psarray[i].size = standard_MFM_2_bit_cell_size; /* That is (total track length / 50000) for Amiga double density */ - total += psarray[i].size; - psarray[i].number_of_bits = nb_of_bits; - totaldiv += psarray[i].number_of_bits; - } - array_index = 0; -} - -#if 0 - -static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int *indexoffsetp, int pulses, int mfm) -{ - uint32_t adjust; - uint32_t adjusted_pulse; - uint32_t standard_MFM_2_bit_cell_size = totalavg / 50000; - uint32_t standard_MFM_8_bit_cell_size = totalavg / 12500; - int real_size, i, j, eodat, outstep; - int indexoffset = *indexoffsetp; - uae_u8 *d = fdi->track_dst_buffer; - uae_u16 *pt = fdi->track_dst_buffer_timing; - uae_u32 ref_pulse, pulse; - - /* detects a long-enough stable pulse coming just after another stable pulse */ - i = 1; - while ( (i < pulses) && ( (idx[i] < maxidx) - || (idx[i - 1] < maxidx) - || (avgp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) ) - i++; - if (i == pulses) { - fdi2raw_log("No stable and long-enough pulse in track.\n"); - return; - } - i--; - eodat = i; - adjust = 0; - total = 0; - totaldiv = 0; - init_array(standard_MFM_2_bit_cell_size, 2); - bitoffset = 0; - ref_pulse = 0; - outstep = 0; - while (outstep < 2) { - - /* calculates the current average bitrate from previous decoded data */ - uae_u32 avg_size = (total << 3) / totaldiv; /* this is the new average size for one MFM bit */ - /* uae_u32 avg_size = (uae_u32)((((float)total)*8.0) / ((float)totaldiv)); */ - /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */ - if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) || - (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) { - avg_size = standard_MFM_8_bit_cell_size; - } - /* this is to prevent the average value from going too far - * from the theoretical value, otherwise it could progressively go to (2 * - * real value), or (real value / 2), etc. */ - - /* gets the next long-enough pulse (this may require more than one pulse) */ - pulse = 0; - while (pulse < ((avg_size / 4) - (avg_size / 16))) { - int indx; - i++; - if (i >= pulses) - i = 0; - indx = idx[i]; - if (rand() <= (indx * RAND_MAX) / maxidx) { - pulse += avgp[i] - ref_pulse; - if (indx >= maxidx) - ref_pulse = 0; - else - ref_pulse = avgp[i]; - } - if (i == eodat) - outstep++; - if (outstep == 1 && indexoffset == i) - *indexoffsetp = bitoffset; - } - - /* gets the size in bits from the pulse width, considering the current average bitrate */ - adjusted_pulse = pulse; - real_size = 0; - while (adjusted_pulse >= avg_size) { - real_size += 4; - adjusted_pulse -= avg_size / 2; - } - adjusted_pulse <<= 3; - while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) { - real_size += 2; - adjusted_pulse -= avg_size * 2; - } - if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) { - if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) { - if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4))) - real_size += 3; - else - real_size += 4; - } else - real_size += 4; - } else { - if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) { - real_size += 3; - } else { - if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) { - if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4))) - real_size += 2; - else - real_size += 3; - } else - real_size += 2; - } - } - - if (outstep == 1) { - for (j = real_size; j > 1; j--) - addbit (d, 0); - addbit (d, 1); - for (j = 0; j < real_size; j++) - *pt++ = (uae_u16)(pulse / real_size); - } - - /* prepares for the next pulse */ - adjust = ((real_size * avg_size)/8) - pulse; - total -= psarray[array_index].size; - totaldiv -= psarray[array_index].number_of_bits; - psarray[array_index].size = pulse; - psarray[array_index].number_of_bits = real_size; - total += pulse; - totaldiv += real_size; - array_index++; - if (array_index >= FDI_MAX_ARRAY) - array_index = 0; - } - - fdi->out = bitoffset; -} - -#else - -static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int *indexoffsetp, int pulses, int mfm) -{ - uint32_t adjust; - uint32_t adjusted_pulse; - uint32_t standard_MFM_2_bit_cell_size = totalavg / 50000; - uint32_t standard_MFM_8_bit_cell_size = totalavg / 12500; - int real_size, i, j, nexti, eodat, outstep, randval; - int indexoffset = *indexoffsetp; - uae_u8 *d = fdi->track_dst_buffer; - uae_u16 *pt = fdi->track_dst_buffer_timing; - uae_u32 ref_pulse, pulse; - long jitter; - - /* detects a long-enough stable pulse coming just after another stable pulse */ - i = 1; - while ( (i < pulses) && ( (idx[i] < maxidx) - || (idx[i - 1] < maxidx) - || (minp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) ) - i++; - if (i == pulses) { - fdi2raw_log("FDI: No stable and long-enough pulse in track.\n"); - return; - } - nexti = i; - eodat = i; - i--; - adjust = 0; - total = 0; - totaldiv = 0; - init_array(standard_MFM_2_bit_cell_size, 1 + mfm); - bitoffset = 0; - ref_pulse = 0; - jitter = 0; - outstep = -1; - while (outstep < 2) { - - /* calculates the current average bitrate from previous decoded data */ - uae_u32 avg_size = (total << (2 + mfm)) / totaldiv; /* this is the new average size for one MFM bit */ - /* uae_u32 avg_size = (uae_u32)((((float)total)*((float)(mfm+1))*4.0) / ((float)totaldiv)); */ - /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */ - if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) || - (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) { - avg_size = standard_MFM_8_bit_cell_size; - } - /* this is to prevent the average value from going too far - * from the theoretical value, otherwise it could progressively go to (2 * - * real value), or (real value / 2), etc. */ - - /* gets the next long-enough pulse (this may require more than one pulse) */ - pulse = 0; - while (pulse < ((avg_size / 4) - (avg_size / 16))) { - uae_u32 avg_pulse, min_pulse, max_pulse; - i++; - if (i >= pulses) - i = 0; - if (i == nexti) { - do { - nexti++; - if (nexti >= pulses) - nexti = 0; - } while (idx[nexti] < maxidx); - } - if (idx[i] >= maxidx) { /* stable pulse */ - avg_pulse = avgp[i] - jitter; - min_pulse = minp[i]; - max_pulse = maxp[i]; - if (jitter >= 0) - max_pulse -= jitter; - else - min_pulse -= jitter; - if ((maxp[nexti] - avgp[nexti]) < (avg_pulse - min_pulse)) - min_pulse = avg_pulse - (maxp[nexti] - avgp[nexti]); - if ((avgp[nexti] - minp[nexti]) < (max_pulse - avg_pulse)) - max_pulse = avg_pulse + (avgp[nexti] - minp[nexti]); - if (min_pulse < ref_pulse) - min_pulse = ref_pulse; - randval = rand(); - if (randval < (RAND_MAX / 2)) { - if (randval > (RAND_MAX / 4)) { - if (randval <= (((3LL*RAND_MAX) / 8))) - randval = (2 * randval) - (RAND_MAX /4); - else - randval = (4 * randval) - RAND_MAX; - } - jitter = 0 - (randval * (avg_pulse - min_pulse)) / RAND_MAX; - } else { - randval -= RAND_MAX / 2; - if (randval > (RAND_MAX / 4)) { - if (randval <= (((3LL*RAND_MAX) / 8))) - randval = (2 * randval) - (RAND_MAX /4); - else - randval = (4 * randval) - RAND_MAX; - } - jitter = (randval * (max_pulse - avg_pulse)) / RAND_MAX; - } - avg_pulse += jitter; - if ((avg_pulse < min_pulse) || (avg_pulse > max_pulse)) { - fdi2raw_log("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse); - fdi2raw_log("FDI: avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n", - avgp[i], avgp[nexti], minp[i], minp[nexti], maxp[i], maxp[nexti], jitter, i, nexti); - } - if (avg_pulse < ref_pulse) - fdi2raw_log("FDI: avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse); - pulse += avg_pulse - ref_pulse; - ref_pulse = 0; - if (i == eodat) - outstep++; - } else if (rand() <= ((idx[i] * RAND_MAX) / maxidx)) { - avg_pulse = avgp[i]; - min_pulse = minp[i]; - max_pulse = maxp[i]; - randval = rand(); - if (randval < (RAND_MAX / 2)) { - if (randval > (RAND_MAX / 4)) { - if (randval <= (((3LL*RAND_MAX) / 8))) - randval = (2 * randval) - (RAND_MAX /4); - else - randval = (4 * randval) - RAND_MAX; - } - avg_pulse -= (randval * (avg_pulse - min_pulse)) / RAND_MAX; - } else { - randval -= RAND_MAX / 2; - if (randval > (RAND_MAX / 4)) { - if (randval <= (((3LL*RAND_MAX) / 8))) - randval = (2 * randval) - (RAND_MAX /4); - else - randval = (4 * randval) - RAND_MAX; - } - avg_pulse += (randval * (max_pulse - avg_pulse)) / RAND_MAX; - } - if ((avg_pulse > ref_pulse) && (avg_pulse < (avgp[nexti] - jitter))) { - pulse += avg_pulse - ref_pulse; - ref_pulse = avg_pulse; - } - } - if (outstep == 1 && indexoffset == i) - *indexoffsetp = bitoffset; - } - - /* gets the size in bits from the pulse width, considering the current average bitrate */ - adjusted_pulse = pulse; - real_size = 0; - if (mfm) { - while (adjusted_pulse >= avg_size) { - real_size += 4; - adjusted_pulse -= avg_size / 2; - } - adjusted_pulse <<= 3; - while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) { - real_size += 2; - adjusted_pulse -= avg_size * 2; - } - if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) { - if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) { - if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4))) - real_size += 3; - else - real_size += 4; - } else - real_size += 4; - } else { - if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) { - real_size += 3; - } else { - if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) { - if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4))) - real_size += 2; - else - real_size += 3; - } else - real_size += 2; - } - } - } else { - while (adjusted_pulse >= (2*avg_size)) - { - real_size+=4; - adjusted_pulse-=avg_size; - } - adjusted_pulse<<=2; - while (adjusted_pulse >= ((avg_size*3)+(avg_size/4))) - { - real_size+=2; - adjusted_pulse-=avg_size*2; - } - if (adjusted_pulse >= ((avg_size*2)+(avg_size/4))) - { - if (adjusted_pulse <= ((avg_size*3)-(avg_size/4))) - { - if (((adjusted_pulse>>1)-adjust) < (avg_size+(avg_size/4))) - real_size+=2; - else - real_size+=3; - } - else - real_size+=3; - } - else - { - if (adjusted_pulse > ((avg_size*2)-(avg_size/4))) - real_size+=2; - else - { - if (adjusted_pulse >= (avg_size+(avg_size/4))) - { - if (((adjusted_pulse>>1)-adjust) <= (avg_size-(avg_size/4))) - real_size++; - else - real_size+=2; - } - else - real_size++; - } - } - } - - /* after one pass to correctly initialize the average bitrate, outputs the bits */ - if (outstep == 1) { - for (j = real_size; j > 1; j--) - addbit (d, 0); - addbit (d, 1); - for (j = 0; j < real_size; j++) - *pt++ = (uae_u16)(pulse / real_size); - } - - /* prepares for the next pulse */ - adjust = ((real_size * avg_size) / (4 << mfm)) - pulse; - total -= psarray[array_index].size; - totaldiv -= psarray[array_index].number_of_bits; - psarray[array_index].size = pulse; - psarray[array_index].number_of_bits = real_size; - total += pulse; - totaldiv += real_size; - array_index++; - if (array_index >= FDI_MAX_ARRAY) - array_index = 0; - } - - fdi->out = bitoffset; -} - -#endif - -static void fdi2_celltiming (FDI *fdi, uint32_t totalavg, int bitoffset, uae_u16 *out) -{ - uae_u16 *pt2, *pt; - double avg_bit_len; - int i; - - avg_bit_len = (double)totalavg / (double)bitoffset; - pt2 = fdi->track_dst_buffer_timing; - pt = out; - for (i = 0; i < bitoffset / 8; i++) { - double v = (pt2[0] + pt2[1] + pt2[2] + pt2[3] + pt2[4] + pt2[5] + pt2[6] + pt2[7]) / 8.0; - v = 1000.0 * v / avg_bit_len; - *pt++ = (uae_u16)v; - pt2 += 8; - } - *pt++ = out[0]; - *pt = out[0]; -} - -static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache) -{ - uae_u8 *p1; - uae_u32 *p2; - uae_u32 *avgp, *minp = 0, *maxp = 0; - uae_u8 *idxp = 0; - uae_u32 maxidx, totalavg, weakbits; - int i, j, len, pulses, indexoffset; - int avg_free, min_free = 0, max_free = 0, idx_free; - int idx_off1 = 0, idx_off2 = 0, idx_off3 = 0; - - p1 = fdi->track_src; - pulses = get_u32 (p1); - if (!pulses) - return -1; - p1 += 4; - len = 12; - avgp = (uae_u32*)fdi_decompress (pulses, p1 + 0, p1 + len, &avg_free); - dumpstream(track, (uae_u8*)avgp, pulses); - len += get_u24 (p1 + 0) & 0x3fffff; - if (!avgp) - return -1; - if (get_u24 (p1 + 3) && get_u24 (p1 + 6)) { - minp = (uae_u32*)fdi_decompress (pulses, p1 + 3, p1 + len, &min_free); - len += get_u24 (p1 + 3) & 0x3fffff; - maxp = (uae_u32*)fdi_decompress (pulses, p1 + 6, p1 + len, &max_free); - len += get_u24 (p1 + 6) & 0x3fffff; - /* Computes the real min and max values */ - for (i = 0; i < pulses; i++) { - maxp[i] = avgp[i] + minp[i] - maxp[i]; - minp[i] = avgp[i] - minp[i]; - } - } else { - minp = avgp; - maxp = avgp; - } - if (get_u24 (p1 + 9)) { - idx_off1 = 0; - idx_off2 = 1; - idx_off3 = 2; - idxp = fdi_decompress (pulses, p1 + 9, p1 + len, &idx_free); - if (idx_free) { - if (idxp[0] == 0 && idxp[1] == 0) { - idx_off1 = 2; - idx_off2 = 3; - } else { - idx_off1 = 1; - idx_off2 = 0; - } - idx_off3 = 4; - } - } else { - idxp = fdi_malloc (pulses * 2); - idx_free = 1; - for (i = 0; i < pulses; i++) { - idxp[i * 2 + 0] = 2; - idxp[i * 2 + 1] = 0; - } - idxp[0] = 1; - idxp[1] = 1; - } - - maxidx = 0; - indexoffset = 0; - p1 = idxp; - for (i = 0; i < pulses; i++) { - if ((uint32_t)p1[idx_off1] + (uint32_t)p1[idx_off2] > maxidx) - maxidx = p1[idx_off1] + p1[idx_off2]; - p1 += idx_off3; - } - p1 = idxp; - for (i = 0; (i < pulses) && (p1[idx_off2] != 0); i++) /* falling edge, replace with idx_off1 for rising edge */ - p1 += idx_off3; - if (i < pulses) { - j = i; - do { - i++; - p1 += idx_off3; - if (i >= pulses) { - i = 0; - p1 = idxp; - } - } while ((i != j) && (p1[idx_off2] == 0)); /* falling edge, replace with idx_off1 for rising edge */ - if (i != j) /* index pulse detected */ - { - while ((i != j) && (p1[idx_off1] > p1[idx_off2])) { /* falling edge, replace with "<" for rising edge */ - i++; - p1 += idx_off3; - if (i >= pulses) { - i = 0; - p1 = idxp; - } - } - if (i != j) - indexoffset = i; /* index position detected */ - } - } - p1 = idxp; - p2 = avgp; - totalavg = 0; - weakbits = 0; - for (i = 0; i < pulses; i++) { - uint32_t sum = p1[idx_off1] + p1[idx_off2]; - if (sum >= maxidx) { - totalavg += *p2; - } else { - weakbits++; - } - p2++; - p1 += idx_off3; - idxp[i] = sum; - } - len = totalavg / 100000; - /* fdi2raw_log("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n", - totalavg, indexoffset, maxidx, weakbits, len); */ - cache->avgp = avgp; - cache->idxp = idxp; - cache->minp = minp; - cache->maxp = maxp; - cache->avg_free = avg_free; - cache->idx_free = idx_free; - cache->min_free = min_free; - cache->max_free = max_free; - cache->totalavg = totalavg; - cache->pulses = pulses; - cache->maxidx = maxidx; - cache->indexoffset = indexoffset; - cache->weakbits = weakbits; - cache->lowlevel = 1; - - return 1; -} - -static unsigned char fdiid[]={"Formatted Disk Image file"}; -static int bit_rate_table[16] = { 125,150,250,300,500,1000 }; - -void fdi2raw_header_free (FDI *fdi) -{ - int i; - - fdi_free (fdi->mfmsync_buffer); - fdi_free (fdi->track_src_buffer); - fdi_free (fdi->track_dst_buffer); - fdi_free (fdi->track_dst_buffer_timing); - for (i = 0; i < MAX_TRACKS; i++) { - struct fdi_cache *c = &fdi->cache[i]; - if (c->idx_free) - fdi_free (c->idxp); - if (c->avg_free) - fdi_free (c->avgp); - if (c->min_free) - fdi_free (c->minp); - if (c->max_free) - fdi_free (c->maxp); - } - fdi_free (fdi); - fdi2raw_log("FREE: memory allocated %d\n", fdi_allocated); -} - -int fdi2raw_get_last_track (FDI *fdi) -{ - return fdi->last_track; -} - -int fdi2raw_get_num_sector (FDI *fdi) -{ - if (fdi->header[152] == 0x02) - return 22; - return 11; -} - -int fdi2raw_get_last_head (FDI *fdi) -{ - return fdi->last_head; -} - -int fdi2raw_get_rotation (FDI *fdi) -{ - return fdi->rotation_speed; -} - -int fdi2raw_get_bit_rate (FDI *fdi) -{ - return fdi->bit_rate; -} - -int fdi2raw_get_type (FDI *fdi) -{ - return fdi->disk_type; -} - -int fdi2raw_get_write_protect (FDI *fdi) -{ - return fdi->write_protect; -} - -int fdi2raw_get_tpi (FDI *fdi) -{ - return fdi->header[148]; -} - -FDI *fdi2raw_header(FILE *f) -{ - int i, offset, oldseek; - uae_u8 type, size; - FDI *fdi; - - fdi2raw_log("ALLOC: memory allocated %d\n", fdi_allocated); - fdi = fdi_malloc(sizeof(FDI)); - memset (fdi, 0, sizeof (FDI)); - fdi->file = f; - oldseek = ftell (fdi->file); - fseek (fdi->file, 0, SEEK_SET); - fread (fdi->header, 2048, 1, fdi->file); - fseek (fdi->file, oldseek, SEEK_SET); - if (memcmp (fdiid, fdi->header, strlen ((char *)fdiid)) ) { - fdi_free(fdi); - return NULL; - } - if ((fdi->header[140] != 1 && fdi->header[140] != 2) || (fdi->header[141] != 0 && !(fdi->header[140]==2 && fdi->header[141]==1))) { - fdi_free(fdi); - return NULL; - } - - fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int)); - fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER); - fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER); - fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER); - - fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1; - fdi->last_track *= fdi->header[144] + 1; - if (fdi->last_track > MAX_TRACKS) - fdi->last_track = MAX_TRACKS; - fdi->last_head = fdi->header[144]; - fdi->disk_type = fdi->header[145]; - fdi->rotation_speed = fdi->header[146] + 128; - fdi->write_protect = fdi->header[147] & 1; - fdi2raw_log("FDI version %d.%d\n", fdi->header[140], fdi->header[141]); - fdi2raw_log("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed); - - offset = 512; - i = fdi->last_track; - if (i > 180) { - offset += 512; - i -= 180; - while (i > 256) { - offset += 512; - i -= 256; - } - } - for (i = 0; i < fdi->last_track; i++) { - fdi->track_offsets[i] = offset; - type = fdi->header[152 + i * 2]; - size = fdi->header[152 + i * 2 + 1]; - if (type == 1) - offset += (size & 15) * 512; - else if ((type & 0xc0) == 0x80) - offset += (((type & 0x3f) << 8) | size) * 256; - else - offset += size * 256; - } - fdi->track_offsets[i] = offset; - - return fdi; -} - - -int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev, int mfm) -{ - struct fdi_cache *cache = &fdi->cache[track]; - int len, i, idx; - - memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER); - idx = cache->indexoffset; - fdi2_decode (fdi, cache->totalavg, - cache->avgp, cache->minp, cache->maxp, cache->idxp, - cache->maxidx, &idx, cache->pulses, mfm); - /* fdi2raw_log("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n", - track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset); */ - len = fdi->out; - if (cache->weakbits >= 10 && multirev) - *multirev = 1; - *tracklength = len; - - for (i = 0; i < (len + 15) / (2 * 8); i++) { - uae_u8 *data = fdi->track_dst_buffer + i * 2; - *mfmbuf++ = 256 * *data + *(data + 1); - } - fdi2_celltiming (fdi, cache->totalavg, len, tracktiming); - if (indexoffsetp) - *indexoffsetp = idx; - return 1; -} - -int fdi2raw_loadrevolution (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm) -{ - return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, 0, 0, mfm); -} - -int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev, int mfm) -{ - uae_u8 *p; - int outlen, i; - struct fdi_cache *cache = &fdi->cache[track]; - - if (cache->lowlevel) - return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm); - - fdi->err = 0; - fdi->track_src_len = fdi->track_offsets[track + 1] - fdi->track_offsets[track]; - fseek (fdi->file, fdi->track_offsets[track], SEEK_SET); - fread (fdi->track_src_buffer, fdi->track_src_len, 1, fdi->file); - memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER); - fdi->track_dst_buffer_timing[0] = 0; - - fdi->current_track = track; - fdi->track_src = fdi->track_src_buffer; - fdi->track_dst = fdi->track_dst_buffer; - p = fdi->header + 152 + fdi->current_track * 2; - fdi->track_type = *p++; - fdi->track_len = *p++; - fdi->bit_rate = 0; - fdi->out = 0; - fdi->mfmsync_offset = 0; - - if ((fdi->track_type & 0xf0) == 0xf0 || (fdi->track_type & 0xf0) == 0xe0) - fdi->bit_rate = bit_rate_table[fdi->track_type & 0x0f]; - else - fdi->bit_rate = 250; - - /* fdi2raw_log("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n", - fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); */ - - if ((fdi->track_type & 0xc0) == 0x80) { - - outlen = decode_lowlevel_track (fdi, track, cache); - - } else if ((fdi->track_type & 0xf0) == 0xf0) { - - outlen = decode_raw_track (fdi); - - } else if ((fdi->track_type & 0xf0) == 0xe0) { - - outlen = handle_sectors_described_track (fdi); - - } else if ((fdi->track_type & 0xf0)) { - - zxx (fdi); - outlen = -1; - - } else if (fdi->track_type < 0x10) { - - decode_normal_track[fdi->track_type](fdi); - fix_mfm_sync (fdi); - outlen = fdi->out; - - } else { - - zxx (fdi); - outlen = -1; - - } - - if (fdi->err) - return 0; - - if (outlen > 0) { - if (cache->lowlevel) - return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm); - *tracklength = fdi->out; - for (i = 0; i < ((*tracklength) + 15) / (2 * 8); i++) { - uae_u8 *data = fdi->track_dst_buffer + i * 2; - *mfmbuf++ = 256 * *data + *(data + 1); - } - } - return outlen; -} - diff --git a/src - Cópia/floppy/fdi2raw.h b/src - Cópia/floppy/fdi2raw.h deleted file mode 100644 index 3c93ae2df..000000000 --- a/src - Cópia/floppy/fdi2raw.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 FDI floppy file format. - * - * Version: @(#)fdi2raw.h 1.0.1 2018/02/14 - * - * Authors: Toni Wilen, - * and Vincent Joguin, - * Thomas Harte, - * - * Copyright 2001-2004 Toni Wilen. - * Copyright 2001-2004 Vincent Joguin. - * Copyright 2001 Thomas Harte. - * - * 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 __FDI2RAW_H -#define __FDI2RAW_H - -#define uae_u8 uint8_t -#define uae_u16 uint16_t -#define uae_u32 uint32_t - -#include -typedef struct fdi FDI; - -#ifdef __cplusplus -extern "C" { -#endif - -extern int fdi2raw_loadtrack (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffset, int *multirev, int mfm); - -extern int fdi2raw_loadrevolution (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm); - -extern FDI *fdi2raw_header(FILE *f); -extern void fdi2raw_header_free (FDI *); -extern int fdi2raw_get_last_track(FDI *); -extern int fdi2raw_get_num_sector (FDI *); -extern int fdi2raw_get_last_head(FDI *); -extern int fdi2raw_get_type (FDI *); -extern int fdi2raw_get_bit_rate (FDI *); -extern int fdi2raw_get_rotation (FDI *); -extern int fdi2raw_get_write_protect (FDI *); -extern int fdi2raw_get_tpi (FDI *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src - Cópia/floppy/lzf/Changes b/src - Cópia/floppy/lzf/Changes deleted file mode 100644 index 93bd4cb6d..000000000 --- a/src - Cópia/floppy/lzf/Changes +++ /dev/null @@ -1,136 +0,0 @@ -3.6 Mon Feb 7 17:37:31 CET 2011 - - fixed hash calculation in C♯ version (Tiago Freitas Leal). - - unroll copy for small sizes, use memcpy for larger sizes, - greatly speeding up decompression in most cases. - - finally disable rep movsb - it's a big loss on modern intel cpus, - and only a small win on amd cpus. - - improve C++ compatibility of the code. - - slightly improve compressor speed. - - halved memory requirements for compressor on 64 bit architectures, - which can improve the speed quite a bit on older cpus. - -3.5 Fri May 1 02:28:42 CEST 2009 - - lzf_compress did sometimes write one octet past the given output - buffer (analyzed and nice testcase by Salvatore Sanfilippo). - -3.4 Tue Sep 2 06:45:00 CEST 2008 - - the fix from 3.3 introduced a compression bug, which is fixed in - this release (which explains the mysterious prerelease...). Thanks - once more to Clément Calmels. - -3.3 Mon Aug 25 03:17:42 CEST 2008 - - lzf_compress could access memory after the given input buffer - when outputting back references. reported with nice testcase - by Clément Calmels. - -3.2 Fri May 9 18:52:23 CEST 2008 - - include a workaround for failing POSIX and real-world compliance - on 64 bit windows (microsoft claims to support POSIX, but is far - from it). (bug found and analysed nicely by John Lilley). - -3.1 Fri Nov 30 11:33:04 CET 2007 - - IMPORTANT BUGFIX: a too long final literal run would corrupt data - in the encoder (this was introduced in 3.0 only, earlier versions - are safe). - -3.0 Tue Nov 13 22:13:09 CET 2007 - - switched to 2-clause bsd with "GPL v2 or any later version" option. - - speed up compression by ~10-15% in common cases - by some manual unrolling. - - import some compiler tricks from JSON::XS, for further speed-ups. - - tune hash functions depending on ULTRA_FAST or VERY_FAST settings. - - for typical binary data (e.g. /bin/bash, memory dumps, - canterbury corpus etc.), speed is now comparable to fastlz, but - with better compression ratio. with ULTRA_FAST, it's typically - 3-15% faster than fastlz while still maintaining a similar ratio. - (amd64 and core 2 duo, ymmv). thanks a lot for the competition :) - - undo inline assembly in compressor, it is no longer helpful. - - no changes to the decompressor. - - use a HLOG of 16 by default now (formerly 15). - -2.1 Fri Nov 2 13:34:42 CET 2007 - - switched to a 2-clause bsd license with GPL exception. - - get rid of memcpy. - - tentatively use rep movsb on x86 and x86_64 (gcc only) for a - moderate speed improvement. - - applied patch by Kein-Hong Man to maske lzf.c compile under - the crippled mingw32 environment. - -2.0 Fri Feb 16 23:11:18 CET 2007 - - replaced lzf demo by industrial-strength lzf utility with behaviour - similar other compression utilities. Thanks for Stefan Traby for - rewriting it! - - fix state arg prototype. - -1.7 Wed Sep 27 17:29:15 CEST 2006 - - remove bogus "unlzf" patch. - note to self: never accept well-meant patches. - - make lzf more robust in presence of padding bytes or sudden eof. - -1.6 Fri Jul 7 17:31:26 CEST 2006 - - the lzf example utility will now uncompress if invoked - as "unlzf" (patch by Scott Feeney). - - add CHECK_INPUT option that adds more checks for input - data validity. - - help applications that do not pass in the correct length - (such as php) by returning either EINVAL or E2BIG. - - default HLOG size is now 15 (cpu caches have increased). - - documentation fixes. - -1.51 Thu Apr 14 22:15:46 CEST 2005 - - incorporated C♯ implementation of both the en- and decoder, - written by "Oren J. Maurice". - You can find it in the cs/ subdirectory. - - make FRST, NEXT IDX overridable if lzf_c.c is directly included - in the code. - -1.5 Tue Mar 8 20:23:23 CET 2005 - - incorporated improvements by Adam D. Moss, - which includes a new VERY_FAST mode which is - a bit slower than ULTRA_FAST but much better, - and enabled it as default. - -1.401 Thu Mar 3 18:00:52 CET 2005 - - use cstring in c++, not string.h. - - change of contact address. - -1.4 Wed Dec 15 08:08:49 CET 2004 - - very very slight tuning of the hashing function. - -1.3 Thu Mar 25 15:41:17 CET 2004 - - changed license of lzf core code to explicitly allow - relicensing under the GPLv2. - - added VPATH support as suggested by Björn Eriksson. - -1.2 Mon Dec 29 13:47:28 CET 2003 - - avoid spurious memory accesses after the to-be-compressed - memory region. originally reported by Michal Zalewski. - - flip LZF_STACK_ARG meaning (to be correct). - -1.1 Tue Dec 23 05:48:32 CET 2003 - - removed #warn directive, it's not worth the hassle. - - add LZF_STACK_ARG and AVOID_ERRNO configurations - for embedded systems. - - make it compile cleanly as c++. - - some small documentation and code fixes. - -1.0 Sun Nov 17 12:37:37 CET 2002 - - slightly better compression ratio, almost unmeasurably - slower. - - some documentation fixes. - -0.4 Thu Jun 13 14:11:10 CEST 2002 - - typoe fix. - - lzf demo program now properly decompresses small files. - - fix another 64 bit issue, found by Laurent Deniel. - -0.3 Tue Jan 16 13:21:14 CET 2001 - - fix silly beginners 32/64 bit mistake. - -0.2 Thu Jan 4 05:56:42 CET 2001 - - now totally independent of autoconfig, for - easy inclusion into other programs. - - much better fine-tuning, faster and better than 0.1. - -0.1 2000 - - initial release. diff --git a/src - Cópia/floppy/lzf/LICENSE b/src - Cópia/floppy/lzf/LICENSE deleted file mode 100644 index ee54ff717..000000000 --- a/src - Cópia/floppy/lzf/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2000-2009 Marc Alexander Lehmann - -Redistribution and use in source and binary forms, with or without modifica- -tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- -CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- -CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- -ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - -Alternatively, the following files carry an additional notice that -explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c -lzf_d.c - diff --git a/src - Cópia/floppy/lzf/Makefile.in b/src - Cópia/floppy/lzf/Makefile.in deleted file mode 100644 index 3c87d62de..000000000 --- a/src - Cópia/floppy/lzf/Makefile.in +++ /dev/null @@ -1,66 +0,0 @@ -VERSION = 3.6 - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -bindir = @bindir@ -includedir = @includedir@ - -VPATH = @srcdir@ - -CC = @CC@ -CPPFLAGS = -I. @CPPFLAGS@ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ -RANLIB = @RANLIB@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -all: Makefile lzf - -clean: - -rm -f *.o *.a lzf bench - -lzf_c.o: lzf_c.c lzfP.h - -lzf_d.o: lzf_d.c lzfP.h - -lzf.o: lzf.c - -lzf: lzf.o liblzf.a - -lzfP.h: lzf.h config.h - -liblzf.a: lzf_c.o lzf_d.o - rm -f $@ - $(AR) rc $@ $^ - $(RANLIB) $@ - -install: all - $(INSTALL) -d $(bindir) - $(INSTALL) -m 755 lzf $(bindir) - $(INSTALL) -d $(includedir) - $(INSTALL_DATA) lzf.h $(includedir) - $(INSTALL) -d $(libdir) - $(INSTALL_DATA) liblzf.a $(libdir) - -dist: - mkdir liblzf-$(VERSION) - tar c LICENSE README Makefile.in config.h.in \ - configure configure.ac install-sh \ - cs/README cs/CLZF.cs \ - lzf.h lzfP.h lzf_c.c lzf_d.c \ - crc32.h lzf.c Changes \ - | tar xpC liblzf-$(VERSION) - -chown -R root.root liblzf-$(VERSION) - chmod -R u=rwX,go=rX liblzf-$(VERSION) - tar cvf - liblzf-$(VERSION) | gzip -9 >liblzf-$(VERSION).tar.gz - rm -rf liblzf-$(VERSION) - ls -l liblzf-$(VERSION).tar.gz - -Makefile: Makefile.in - ./config.status - -bench: Makefile liblzf.a bench.c - $(CC) $(CPPFLAGS) $(CFLAGS) -g -o bench bench.c -L. -llzf - diff --git a/src - Cópia/floppy/lzf/README b/src - Cópia/floppy/lzf/README deleted file mode 100644 index 0734ebe06..000000000 --- a/src - Cópia/floppy/lzf/README +++ /dev/null @@ -1,29 +0,0 @@ -DESCRIPTION - LZF is an extremely fast (not that much slower than a pure memcpy) - compression algorithm. It is ideal for applications where you want to - save *some* space but not at the cost of speed. It is ideal for - repetitive data as well. The module is self-contained and very small. - - It's written in ISO-C with no external dependencies other than what - C provides and can easily be #include'd into your code, no makefile - changes or library builds requires. - - A C♯ implementation without external dependencies is available, too. - - I do not know for certain whether any patents in any countries apply - to this algorithm, but at the moment it is believed that it is free - from any patents. More importantly, it is also free to use in every - software package (see LICENSE). - - See the lzf.h file for details on how the functions in this - mini-library are to be used. - - NOTE: This package contains a very bare-bones command-line utility - which is neither optimized for speed nor for compression. This library - is really intended to be used inside larger programs. - -AUTHOR - This library was written by Marc Lehmann (See also - http://software.schmorp.de/pkg/liblzf). - - diff --git a/src - Cópia/floppy/lzf/config.h b/src - Cópia/floppy/lzf/config.h deleted file mode 100644 index 5fd69c6bd..000000000 --- a/src - Cópia/floppy/lzf/config.h +++ /dev/null @@ -1,16 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* The number of bytes in a int. */ -#undef SIZEOF_INT - -/* The number of bytes in a long. */ -#undef SIZEOF_LONG - -/* The number of bytes in a short. */ -#undef SIZEOF_SHORT diff --git a/src - Cópia/floppy/lzf/configure b/src - Cópia/floppy/lzf/configure deleted file mode 100644 index 7a3a2b25c..000000000 --- a/src - Cópia/floppy/lzf/configure +++ /dev/null @@ -1,7871 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60. -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell autoconf@gnu.org about your system, - echo including any error possibly output before this - echo message -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" -else - as_executable_p=: -fi -rm -f conf$$.file - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="lzfP.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDINT_H -# include -#endif -#if HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL -PATH_SEPARATOR -PACKAGE_NAME -PACKAGE_TARNAME -PACKAGE_VERSION -PACKAGE_STRING -PACKAGE_BUGREPORT -exec_prefix -prefix -program_transform_name -bindir -sbindir -libexecdir -datarootdir -datadir -sysconfdir -sharedstatedir -localstatedir -includedir -oldincludedir -docdir -infodir -htmldir -dvidir -pdfdir -psdir -libdir -localedir -mandir -DEFS -ECHO_C -ECHO_N -ECHO_T -LIBS -build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CC -EXEEXT -OBJEXT -RANLIB -INSTALL_PROGRAM -INSTALL_SCRIPT -INSTALL_DATA -CPP -GREP -EGREP -LIBOBJS -LTLIBOBJS' -ac_subst_files='' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval enable_$ac_feature=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval enable_$ac_feature=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval with_$ac_package=\$ac_optarg ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval with_$ac_package=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute directory names. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { echo "$as_me: error: Working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$0" || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-largefile omit support for large files - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -configure -generated by GNU Autoconf 2.60 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.60. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -n "$CONFIG_SITE"; then - set x "$CONFIG_SITE" -elif test "x$prefix" != xNONE; then - set x "$prefix/share/config.site" "$prefix/etc/config.site" -else - set x "$ac_default_prefix/share/config.site" \ - "$ac_default_prefix/etc/config.site" -fi -shift -for ac_site_file -do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_config_headers="$ac_config_headers config.h" - - - -cat >>confdefs.h <<\_ACEOF -#define _GNU_SOURCE 1 -_ACEOF - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } - -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Check whether --enable-largefile was given. -if test "${enable_largefile+set}" = set; then - enableval=$enable_largefile; -fi - -if test "$enable_largefile" != no; then - - { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 -echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_largefile_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - CC="$CC -n32" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_largefile_CC=' -n32'; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 -echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_file_offset_bits+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - while :; do - ac_cv_sys_file_offset_bits=no - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_file_offset_bits=64; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - break -done -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 -echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } -if test "$ac_cv_sys_file_offset_bits" != no; then - -cat >>confdefs.h <<_ACEOF -#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits -_ACEOF - -fi -rm -f conftest* - { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 -echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_large_files+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - while :; do - ac_cv_sys_large_files=no - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_large_files=1; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - break -done -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 -echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } -if test "$ac_cv_sys_large_files" != no; then - -cat >>confdefs.h <<_ACEOF -#define _LARGE_FILES $ac_cv_sys_large_files -_ACEOF - -fi -rm -f conftest* -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done -IFS=$as_save_IFS - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Extract the first word of "grep ggrep" to use in msg output -if test -z "$GREP"; then -set dummy grep ggrep; ac_prog_name=$2 -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_GREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue - # Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_GREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -GREP="$ac_cv_path_GREP" -if test -z "$GREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_GREP=$GREP -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -echo "${ECHO_T}$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - # Extract the first word of "egrep" to use in msg output -if test -z "$EGREP"; then -set dummy egrep; ac_prog_name=$2 -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_EGREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue - # Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_EGREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -EGREP="$ac_cv_path_EGREP" -if test -z "$EGREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_EGREP=$EGREP -fi - - - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -{ echo "$as_me:$LINENO: checking for short" >&5 -echo $ECHO_N "checking for short... $ECHO_C" >&6; } -if test "${ac_cv_type_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef short ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_short=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_short=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 -echo "${ECHO_T}$ac_cv_type_short" >&6; } - -{ echo "$as_me:$LINENO: checking size of short" >&5 -echo $ECHO_N "checking size of short... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_short" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_short=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (short) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_short=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (short) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_short=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 -echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SHORT $ac_cv_sizeof_short -_ACEOF - - -{ echo "$as_me:$LINENO: checking for int" >&5 -echo $ECHO_N "checking for int... $ECHO_C" >&6; } -if test "${ac_cv_type_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef int ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_int=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 -echo "${ECHO_T}$ac_cv_type_int" >&6; } - -{ echo "$as_me:$LINENO: checking size of int" >&5 -echo $ECHO_N "checking size of int... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_int" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_int=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - -{ echo "$as_me:$LINENO: checking for long" >&5 -echo $ECHO_N "checking for long... $ECHO_C" >&6; } -if test "${ac_cv_type_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef long ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_long=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 -echo "${ECHO_T}$ac_cv_type_long" >&6; } - -{ echo "$as_me:$LINENO: checking size of long" >&5 -echo $ECHO_N "checking size of long... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_long" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_long=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (long) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_long=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (long) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_long=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 -echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - - -{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset x; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - ccp = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !x[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_const=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6; } -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6; } - - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - - -for ac_header in getopt.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_func in getopt_long -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -if test "$GCC" = yes; then - CFLAGS="$CFLAGS -O3 -funroll-all-loops" -else - { echo "$as_me:$LINENO: result: no gcc" >&5 -echo "${ECHO_T}no gcc" >&6; } -fi - -ac_config_files="$ac_config_files Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { echo "$as_me:$LINENO: updating cache $cache_file" >&5 -echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" -else - as_executable_p=: -fi -rm -f conf$$.file - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.60. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.60, - with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2006 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - { echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=$SHELL - export CONFIG_SHELL - exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - -_ACEOF - - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -SHELL!$SHELL$ac_delim -PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim -PACKAGE_NAME!$PACKAGE_NAME$ac_delim -PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim -PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim -PACKAGE_STRING!$PACKAGE_STRING$ac_delim -PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim -exec_prefix!$exec_prefix$ac_delim -prefix!$prefix$ac_delim -program_transform_name!$program_transform_name$ac_delim -bindir!$bindir$ac_delim -sbindir!$sbindir$ac_delim -libexecdir!$libexecdir$ac_delim -datarootdir!$datarootdir$ac_delim -datadir!$datadir$ac_delim -sysconfdir!$sysconfdir$ac_delim -sharedstatedir!$sharedstatedir$ac_delim -localstatedir!$localstatedir$ac_delim -includedir!$includedir$ac_delim -oldincludedir!$oldincludedir$ac_delim -docdir!$docdir$ac_delim -infodir!$infodir$ac_delim -htmldir!$htmldir$ac_delim -dvidir!$dvidir$ac_delim -pdfdir!$pdfdir$ac_delim -psdir!$psdir$ac_delim -libdir!$libdir$ac_delim -localedir!$localedir$ac_delim -mandir!$mandir$ac_delim -DEFS!$DEFS$ac_delim -ECHO_C!$ECHO_C$ac_delim -ECHO_N!$ECHO_N$ac_delim -ECHO_T!$ECHO_T$ac_delim -LIBS!$LIBS$ac_delim -build_alias!$build_alias$ac_delim -host_alias!$host_alias$ac_delim -target_alias!$target_alias$ac_delim -CC!$CC$ac_delim -CFLAGS!$CFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -RANLIB!$RANLIB$ac_delim -INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim -INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim -INSTALL_DATA!$INSTALL_DATA$ac_delim -CPP!$CPP$ac_delim -GREP!$GREP$ac_delim -EGREP!$EGREP$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g -CEOF$ac_eof -_ACEOF - - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF -fi # test -n "$CONFIG_FILES" - - -for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - ac_file_inputs="$ac_file_inputs $ac_f" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - fi - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -case `sed -n '/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' $ac_file_inputs` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac - ;; - :H) - # - # CONFIG_HEADER - # -_ACEOF - -# Transform confdefs.h into a sed script `conftest.defines', that -# substitutes the proper values into config.h.in to produce config.h. -rm -f conftest.defines conftest.tail -# First, append a space to every undef/define line, to ease matching. -echo 's/$/ /' >conftest.defines -# Then, protect against being on the right side of a sed subst, or in -# an unquoted here document, in config.status. If some macros were -# called several times there might be several #defines for the same -# symbol, which is useless. But do not sort them, since the last -# AC_DEFINE must be honored. -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where -# NAME is the cpp macro being defined, VALUE is the value it is being given. -# PARAMS is the parameter list in the macro definition--in most cases, it's -# just an empty string. -ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' -ac_dB='\\)[ (].*,\\1define\\2' -ac_dC=' ' -ac_dD=' ,' - -uniq confdefs.h | - sed -n ' - t rset - :rset - s/^[ ]*#[ ]*define[ ][ ]*// - t ok - d - :ok - s/[\\&,]/\\&/g - s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p - s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p - ' >>conftest.defines - -# Remove the space that was appended to ease matching. -# Then replace #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -# (The regexp can be short, since the line contains either #define or #undef.) -echo 's/ $// -s,^[ #]*u.*,/* & */,' >>conftest.defines - -# Break up conftest.defines: -ac_max_sed_lines=50 - -# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" -# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" -# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" -# et cetera. -ac_in='$ac_file_inputs' -ac_out='"$tmp/out1"' -ac_nxt='"$tmp/out2"' - -while : -do - # Write a here document: - cat >>$CONFIG_STATUS <<_ACEOF - # First, check the format of the line: - cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def -/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def -b -:def -_ACEOF - sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS - ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in - sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail - grep . conftest.tail >/dev/null || break - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines conftest.tail - -echo "ac_result=$ac_in" >>$CONFIG_STATUS -cat >>$CONFIG_STATUS <<\_ACEOF - if test x"$ac_file" != x-; then - echo "/* $configure_input */" >"$tmp/config.h" - cat "$ac_result" >>"$tmp/config.h" - if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f $ac_file - mv "$tmp/config.h" $ac_file - fi - else - echo "/* $configure_input */" - cat "$ac_result" - fi - rm -f "$tmp/out12" - ;; - - - esac - -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/src - Cópia/floppy/lzf/configure.ac b/src - Cópia/floppy/lzf/configure.ac deleted file mode 100644 index 58316a01b..000000000 --- a/src - Cópia/floppy/lzf/configure.ac +++ /dev/null @@ -1,25 +0,0 @@ -AC_INIT -AC_CONFIG_SRCDIR([lzfP.h]) - -AC_CONFIG_HEADER(config.h) - -AC_GNU_SOURCE -AC_SYS_LARGEFILE -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_INSTALL -AC_HEADER_STDC - -AC_C_CONST -AC_C_INLINE -AC_CHECK_HEADERS(getopt.h) -AC_CHECK_FUNCS(getopt_long) - -if test "$GCC" = yes; then - CFLAGS="$CFLAGS -O3 -funroll-all-loops" -else - AC_MSG_RESULT(no gcc) -fi - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/src - Cópia/floppy/lzf/crc32.h b/src - Cópia/floppy/lzf/crc32.h deleted file mode 100644 index cf8f6d409..000000000 --- a/src - Cópia/floppy/lzf/crc32.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef CRC32_H -#define CRC32_H - -/* crc32 0xdebb20e3 table and supplementary functions. */ - -static const u32 crc_32_tab[] = -{ - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dL -}; - -#define crc32(crc,byte) (crc_32_tab[(u8)(crc) ^ (u8)(byte)] ^ ((crc) >> 8)) - -#endif - diff --git a/src - Cópia/floppy/lzf/install-sh b/src - Cópia/floppy/lzf/install-sh deleted file mode 100644 index e9de23842..000000000 --- a/src - Cópia/floppy/lzf/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/src - Cópia/floppy/lzf/lzf.c b/src - Cópia/floppy/lzf/lzf.c deleted file mode 100644 index bedfdb6fe..000000000 --- a/src - Cópia/floppy/lzf/lzf.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2006 Stefan Traby - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lzf.h" - -#ifdef HAVE_GETOPT_H -# include -#endif - -#define BLOCKSIZE (1024 * 64 - 1) -#define MAX_BLOCKSIZE BLOCKSIZE - -typedef unsigned char u8; - -static off_t nr_read, nr_written; - -static const char *imagename; -static enum { compress, uncompress, lzcat } mode = compress; -static int verbose = 0; -static int force = 0; -static long blocksize = BLOCKSIZE; - -#ifdef HAVE_GETOPT_LONG - - struct option longopts[] = { - {"compress", 0, 0, 'c'}, - {"decompress", 0, 0, 'd'}, - {"uncompress", 0, 0, 'd'}, - {"force", 0, 0, 'f'}, - {"help", 0, 0, 'h'}, - {"verbose", 0, 0, 'v'}, - {"blocksize", 1, 0, 'b'}, - {0, 0, 0, 0} - }; - - static const char *opt = - "-c --compress compress\n" - "-d --decompress decompress\n" - "-f --force force overwrite of output file\n" - "-h --help give this help\n" "-v --verbose verbose mode\n" "-b # --blocksize # set blocksize\n" "\n"; - -#else - - static const char *opt = - "-c compress\n" - "-d decompress\n" - "-f force overwrite of output file\n" - "-h give this help\n" - "-v verbose mode\n" - "-b # set blocksize\n" - "\n"; - -#endif - -static void -usage (int rc) -{ - fprintf (stderr, "\n" - "lzf, a very lightweight compression/decompression utility written by Stefan Traby.\n" - "uses liblzf written by Marc Lehmann You can find more info at\n" - "http://liblzf.plan9.de/\n" - "\n" - "usage: lzf [-dufhvb] [file ...]\n" - " unlzf [file ...]\n" - " lzcat [file ...]\n" - "\n%s", - opt); - - exit (rc); -} - -static inline ssize_t -rread (int fd, void *buf, size_t len) -{ - ssize_t rc = 0, offset = 0; - char *p = buf; - - while (len && (rc = read (fd, &p[offset], len)) > 0) - { - offset += rc; - len -= rc; - } - - nr_read += offset; - - if (rc < 0) - return rc; - - return offset; -} - -/* returns 0 if all written else -1 */ -static inline ssize_t -wwrite (int fd, void *buf, size_t len) -{ - ssize_t rc; - char *b = buf; - size_t l = len; - - while (l) - { - rc = write (fd, b, l); - if (rc < 0) - { - fprintf (stderr, "%s: write error: ", imagename); - perror (""); - return -1; - } - - l -= rc; - b += rc; - } - - nr_written += len; - return 0; -} - -/* - * Anatomy: an lzf file consists of any number of blocks in the following format: - * - * \x00 EOF (optional) - * "ZV\0" 2-byte-usize - * "ZV\1" 2-byte-csize 2-byte-usize - * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI) - */ - - -#define TYPE0_HDR_SIZE 5 -#define TYPE1_HDR_SIZE 7 -#define MAX_HDR_SIZE 7 -#define MIN_HDR_SIZE 5 - -static int -compress_fd (int from, int to) -{ - ssize_t us, cs, len; - u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 *header; - - nr_read = nr_written = 0; - while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0) - { - cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us); - if (cs) - { - header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE]; - header[0] = 'Z'; - header[1] = 'V'; - header[2] = 1; - header[3] = cs >> 8; - header[4] = cs & 0xff; - header[5] = us >> 8; - header[6] = us & 0xff; - len = cs + TYPE1_HDR_SIZE; - } - else - { // write uncompressed - header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE]; - header[0] = 'Z'; - header[1] = 'V'; - header[2] = 0; - header[3] = us >> 8; - header[4] = us & 0xff; - len = us + TYPE0_HDR_SIZE; - } - - if (wwrite (to, header, len) == -1) - return -1; - } - - return 0; -} - -static int -uncompress_fd (int from, int to) -{ - u8 header[MAX_HDR_SIZE]; - u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 *p; - int l, rd; - ssize_t rc, cs, us, bytes, over = 0; - - nr_read = nr_written = 0; - while (1) - { - rc = rread (from, header + over, MAX_HDR_SIZE - over); - if (rc < 0) - { - fprintf (stderr, "%s: read error: ", imagename); - perror (""); - return -1; - } - - rc += over; - over = 0; - if (!rc || header[0] == 0) - return 0; - - if (rc < MIN_HDR_SIZE || header[0] != 'Z' || header[1] != 'V') - { - fprintf (stderr, "%s: invalid data stream - magic not found or short header\n", imagename); - return -1; - } - - switch (header[2]) - { - case 0: - cs = -1; - us = (header[3] << 8) | header[4]; - p = &header[TYPE0_HDR_SIZE]; - break; - case 1: - if (rc < TYPE1_HDR_SIZE) - { - goto short_read; - } - cs = (header[3] << 8) | header[4]; - us = (header[5] << 8) | header[6]; - p = &header[TYPE1_HDR_SIZE]; - break; - default: - fprintf (stderr, "%s: unknown blocktype\n", imagename); - return -1; - } - - bytes = cs == -1 ? us : cs; - l = &header[rc] - p; - - if (l > 0) - memcpy (buf1, p, l); - - if (l > bytes) - { - over = l - bytes; - memmove (header, &p[bytes], over); - } - - p = &buf1[l]; - rd = bytes - l; - if (rd > 0) - if ((rc = rread (from, p, rd)) != rd) - goto short_read; - - if (cs == -1) - { - if (wwrite (to, buf1, us)) - return -1; - } - else - { - if (lzf_decompress (buf1, cs, buf2, us) != us) - { - fprintf (stderr, "%s: decompress: invalid stream - data corrupted\n", imagename); - return -1; - } - - if (wwrite (to, buf2, us)) - return -1; - } - } - - return 0; - -short_read: - fprintf (stderr, "%s: short data\n", imagename); - return -1; -} - -static int -open_out (const char *name) -{ - int fd; - int m = O_EXCL; - - if (force) - m = 0; - - fd = open (name, O_CREAT | O_WRONLY | O_TRUNC | m, 600); -#if defined(__MINGW32__) - _setmode(fd, _O_BINARY); -#endif - return fd; -} - -static int -compose_name (const char *fname, char *oname) -{ - char *p; - - if (mode == compress) - { - if (strlen (fname) > PATH_MAX - 4) - { - fprintf (stderr, "%s: %s.lzf: name too long", imagename, fname); - return -1; - } - - strcpy (oname, fname); - strcat (oname, ".lzf"); - } - else - { - if (strlen (fname) > PATH_MAX) - { - fprintf (stderr, "%s: %s: name too long\n", imagename, fname); - return -1; - } - - strcpy (oname, fname); - p = &oname[strlen (oname)] - 4; - if (p < oname || strcmp (p, ".lzf")) - { - fprintf (stderr, "%s: %s: unknown suffix\n", imagename, fname); - return -1; - } - - *p = 0; - } - - return 0; -} - -static int -run_file (const char *fname) -{ - int fd, fd2; - int rc; - struct stat mystat; - char oname[PATH_MAX + 1]; - - if (mode != lzcat) - if (compose_name (fname, oname)) - return -1; - -#if !defined(__MINGW32__) - rc = lstat (fname, &mystat); -#else - rc = stat (fname, &mystat); -#endif - fd = open (fname, O_RDONLY); -#if defined(__MINGW32__) - _setmode(fd, _O_BINARY); -#endif - if (rc || fd == -1) - { - fprintf (stderr, "%s: %s: ", imagename, fname); - perror (""); - return -1; - } - - if (!S_ISREG (mystat.st_mode)) - { - fprintf (stderr, "%s: %s: not a regular file.\n", imagename, fname); - close (fd); - return -1; - } - - if (mode == lzcat) - { - rc = uncompress_fd (fd, 1); - close (fd); - return rc; - } - - fd2 = open_out (oname); - if (fd2 == -1) - { - fprintf (stderr, "%s: %s: ", imagename, oname); - perror (""); - close (fd); - return -1; - } - - if (mode == compress) - { - rc = compress_fd (fd, fd2); - if (!rc && verbose) - fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", - fname, nr_read == 0 ? 0 : 100.0 - nr_written / ((double) nr_read / 100.0), oname); - } - else - { - rc = uncompress_fd (fd, fd2); - if (!rc && verbose) - fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", - fname, nr_written == 0 ? 0 : 100.0 - nr_read / ((double) nr_written / 100.0), oname); - } - -#if !defined(__MINGW32__) - fchmod (fd2, mystat.st_mode); -#else - chmod (oname, mystat.st_mode); -#endif - close (fd); - close (fd2); - - if (!rc) - unlink (fname); - - return rc; -} - -int -main (int argc, char *argv[]) -{ - char *p = argv[0]; - int optc; - int rc = 0; - - errno = 0; - p = getenv ("LZF_BLOCKSIZE"); - if (p) - { - blocksize = strtoul (p, 0, 0); - if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) - blocksize = BLOCKSIZE; - } - - p = strrchr (argv[0], '/'); - imagename = p ? ++p : argv[0]; - - if (!strncmp (imagename, "un", 2) || !strncmp (imagename, "de", 2)) - mode = uncompress; - - if (strstr (imagename, "cat")) - mode = lzcat; - -#ifdef HAVE_GETOPT_LONG - while ((optc = getopt_long (argc, argv, "cdfhvb:", longopts, 0)) != -1) -#else - while ((optc = getopt (argc, argv, "cdfhvb:")) != -1) -#endif - { - switch (optc) - { - case 'c': - mode = compress; - break; - case 'd': - mode = uncompress; - break; - case 'f': - force = 1; - break; - case 'h': - usage (0); - break; - case 'v': - verbose = 1; - break; - case 'b': - errno = 0; - blocksize = strtoul (optarg, 0, 0); - if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) - blocksize = BLOCKSIZE; - break; - default: - usage (1); - break; - } - } - - if (optind == argc) - { // stdin stdout - if (!force) - { - if ((mode == uncompress || mode == lzcat) && isatty (0)) - { - fprintf (stderr, "%s: compressed data not read from a terminal. Use -f to force decompression.\n", imagename); - exit (1); - } - if (mode == compress && isatty (1)) - { - fprintf (stderr, "%s: compressed data not written to a terminal. Use -f to force compression.\n", imagename); - exit (1); - } - } - - if (mode == compress) - rc = compress_fd (0, 1); - else - rc = uncompress_fd (0, 1); - - exit (rc ? 1 : 0); - } - - while (optind < argc) - rc |= run_file (argv[optind++]); - - exit (rc ? 1 : 0); -} - diff --git a/src - Cópia/floppy/lzf/lzf.h b/src - Cópia/floppy/lzf/lzf.h deleted file mode 100644 index 919b6e6be..000000000 --- a/src - Cópia/floppy/lzf/lzf.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2000-2008 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#ifndef LZF_H -#define LZF_H - -/*********************************************************************** -** -** lzf -- an extremely fast/free compression/decompression-method -** http://liblzf.plan9.de/ -** -** This algorithm is believed to be patent-free. -** -***********************************************************************/ - -#define LZF_VERSION 0x0105 /* 1.5, API version */ - -/* - * Compress in_len bytes stored at the memory block starting at - * in_data and write the result to out_data, up to a maximum length - * of out_len bytes. - * - * If the output buffer is not large enough or any error occurs return 0, - * otherwise return the number of bytes used, which might be considerably - * more than in_len (but less than 104% of the original size), so it - * makes sense to always use out_len == in_len - 1), to ensure _some_ - * compression, and store the data uncompressed otherwise (with a flag, of - * course. - * - * lzf_compress might use different algorithms on different systems and - * even different runs, thus might result in different compressed strings - * depending on the phase of the moon or similar factors. However, all - * these strings are architecture-independent and will result in the - * original data when decompressed using lzf_decompress. - * - * The buffers must not be overlapping. - * - * If the option LZF_STATE_ARG is enabled, an extra argument must be - * supplied which is not reflected in this header file. Refer to lzfP.h - * and lzf_c.c. - * - */ -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); - -/* - * Decompress data compressed with some version of the lzf_compress - * function and stored at location in_data and length in_len. The result - * will be stored at out_data up to a maximum of out_len characters. - * - * If the output buffer is not large enough to hold the decompressed - * data, a 0 is returned and errno is set to E2BIG. Otherwise the number - * of decompressed bytes (i.e. the original length of the data) is - * returned. - * - * If an error in the compressed data is detected, a zero is returned and - * errno is set to EINVAL. - * - * This function is very fast, about as fast as a copying loop. - */ -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); - -#endif - diff --git a/src - Cópia/floppy/lzf/lzfP.h b/src - Cópia/floppy/lzf/lzfP.h deleted file mode 100644 index 11c965ca3..000000000 --- a/src - Cópia/floppy/lzf/lzfP.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2000-2007 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#ifndef LZFP_h -#define LZFP_h - -#define STANDALONE 1 /* at the moment, this is ok. */ - -#ifndef STANDALONE -# include "lzf.h" -#endif - -/* - * Size of hashtable is (1 << HLOG) * sizeof (char *) - * decompression is independent of the hash table size - * the difference between 15 and 14 is very small - * for small blocks (and 14 is usually a bit faster). - * For a low-memory/faster configuration, use HLOG == 13; - * For best compression, use 15 or 16 (or more, up to 22). - */ -#ifndef HLOG -# define HLOG 16 -#endif - -/* - * Sacrifice very little compression quality in favour of compression speed. - * This gives almost the same compression as the default code, and is - * (very roughly) 15% faster. This is the preferred mode of operation. - */ -#ifndef VERY_FAST -# define VERY_FAST 1 -#endif - -/* - * Sacrifice some more compression quality in favour of compression speed. - * (roughly 1-2% worse compression for large blocks and - * 9-10% for small, redundant, blocks and >>20% better speed in both cases) - * In short: when in need for speed, enable this for binary data, - * possibly disable this for text data. - */ -#ifndef ULTRA_FAST -# define ULTRA_FAST 1 -#endif - -/* - * Unconditionally aligning does not cost very much, so do it if unsure - */ -#ifndef STRICT_ALIGN -# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) -#endif - -/* - * You may choose to pre-set the hash table (might be faster on some - * modern cpus and large (>>64k) blocks, and also makes compression - * deterministic/repeatable when the configuration otherwise is the same). - */ -#ifndef INIT_HTAB -# define INIT_HTAB 1 -#endif - -/* - * Avoid assigning values to errno variable? for some embedding purposes - * (linux kernel for example), this is necessary. NOTE: this breaks - * the documentation in lzf.h. Avoiding errno has no speed impact. - */ -#ifndef AVOID_ERRNO -# define AVOID_ERRNO 0 -#endif - -/* - * Whether to pass the LZF_STATE variable as argument, or allocate it - * on the stack. For small-stack environments, define this to 1. - * NOTE: this breaks the prototype in lzf.h. - */ -#ifndef LZF_STATE_ARG -# define LZF_STATE_ARG 0 -#endif - -/* - * Whether to add extra checks for input validity in lzf_decompress - * and return EINVAL if the input stream has been corrupted. This - * only shields against overflowing the input buffer and will not - * detect most corrupted streams. - * This check is not normally noticeable on modern hardware - * (<1% slowdown), but might slow down older cpus considerably. - */ -#ifndef CHECK_INPUT -# define CHECK_INPUT 1 -#endif - -/* - * Whether to store pointers or offsets inside the hash table. On - * 64 bit architetcures, pointers take up twice as much space, - * and might also be slower. Default is to autodetect. - */ -/*#define LZF_USER_OFFSETS autodetect */ - -/*****************************************************************************/ -/* nothing should be changed below */ - -#ifdef __cplusplus -# include -# include -using namespace std; -#else -# include -# include -#endif - -#ifndef LZF_USE_OFFSETS -# if defined(_WIN32) -# define LZF_USE_OFFSETS defined(_M_X64) -# else -# if __cplusplus > 199711L -# include -# else -# include -# endif -# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU) -# endif -#endif - -typedef unsigned char u8; - -#if LZF_USE_OFFSETS -# define LZF_HSLOT_BIAS ((const u8 *)in_data) - typedef unsigned int LZF_HSLOT; -#else -# define LZF_HSLOT_BIAS 0 - typedef const u8 *LZF_HSLOT; -#endif - -typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; - -#if !STRICT_ALIGN -/* for unaligned accesses we need a 16 bit datatype. */ -# if USHRT_MAX == 65535 - typedef unsigned short u16; -# elif UINT_MAX == 65535 - typedef unsigned int u16; -# else -# undef STRICT_ALIGN -# define STRICT_ALIGN 1 -# endif -#endif - -#if ULTRA_FAST -# undef VERY_FAST -#endif - -#endif - diff --git a/src - Cópia/floppy/lzf/lzf_c.c b/src - Cópia/floppy/lzf/lzf_c.c deleted file mode 100644 index 8ba4d0b84..000000000 --- a/src - Cópia/floppy/lzf/lzf_c.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2000-2010 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include - -#include "lzfP.h" - -#define HSIZE (1 << (HLOG)) - -/* - * don't play with this unless you benchmark! - * the data format is not dependent on the hash function. - * the hash function might seem strange, just believe me, - * it works ;) - */ -#ifndef FRST -# define FRST(p) (((p[0]) << 8) | p[1]) -# define NEXT(v,p) (((v) << 8) | p[2]) -# if ULTRA_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) -# elif VERY_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# else -# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# endif -#endif -/* - * IDX works because it is very similar to a multiplicative hash, e.g. - * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) - * the latter is also quite fast on newer CPUs, and compresses similarly. - * - * the next one is also quite good, albeit slow ;) - * (int)(cos(h & 0xffffff) * 1e6) - */ - -#if 0 -/* original lzv-like hash function, much worse and thus slower */ -# define FRST(p) (p[0] << 5) ^ p[1] -# define NEXT(v,p) ((v) << 5) ^ p[2] -# define IDX(h) ((h) & (HSIZE - 1)) -#endif - -#define MAX_LIT (1 << 5) -#define MAX_OFF (1 << 13) -#define MAX_REF ((1 << 8) + (1 << 3)) - -#if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -# define inline inline -#else -# define expect(expr,value) (expr) -# define inline static -#endif - -#define expect_false(expr) expect ((expr) != 0, 0) -#define expect_true(expr) expect ((expr) != 0, 1) - -/* - * compressed format - * - * 000LLLLL ; literal, L+1=1..33 octets - * LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset - * 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset - * - */ - -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len -#if LZF_STATE_ARG - , LZF_STATE htab -#endif - ) -{ -#if !LZF_STATE_ARG - LZF_STATE htab; -#endif - const u8 *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - const u8 *in_end = ip + in_len; - u8 *out_end = op + out_len; - const u8 *ref; - - /* off requires a type wide enough to hold a general pointer difference. - * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only - * works for differences within a single object). We also assume that no - * no bit pattern traps. Since the only platform that is both non-POSIX - * and fails to support both assumptions is windows 64 bit, we make a - * special workaround for it. - */ -#if defined(_WIN32) && defined(_M_X64) - uint64_t off; /* workaround for missing POSIX compliance */ -#else - unsigned long off; -#endif - unsigned int hval; - int lit; - - if (!in_len || !out_len) - return 0; - -#if INIT_HTAB - memset (htab, 0, sizeof (htab)); -#endif - - lit = 0; op++; /* start run */ - - hval = FRST (ip); - while (ip < in_end - 2) - { - LZF_HSLOT *hslot; - - hval = NEXT (hval, ip); - hslot = htab + IDX (hval); - ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS; - - if (1 -#if INIT_HTAB - && ref < ip /* the next test will actually take care of this, but this is faster */ -#endif - && (off = ip - ref - 1) < MAX_OFF - && ref > (u8 *)in_data - && ref[2] == ip[2] -#if STRICT_ALIGN - && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]) -#else - && *(u16 *)ref == *(u16 *)ip -#endif - ) - { - /* match found at *ref++ */ - unsigned int len = 2; - unsigned int maxlen = in_end - ip - len; - maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; - - if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */ - if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */ - return 0; - - op [- lit - 1] = lit - 1; /* stop run */ - op -= !lit; /* undo run if length is zero */ - - for (;;) - { - if (expect_true (maxlen > 16)) - { - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - } - - do - len++; - while (len < maxlen && ref[len] == ip[len]); - - break; - } - - len -= 2; /* len is now #octets - 1 */ - ip++; - - if (len < 7) - { - *op++ = (off >> 8) + (len << 5); - } - else - { - *op++ = (off >> 8) + ( 7 << 5); - *op++ = len - 7; - } - - *op++ = off; - - lit = 0; op++; /* start run */ - - ip += len + 1; - - if (expect_false (ip >= in_end - 2)) - break; - -#if ULTRA_FAST || VERY_FAST - --ip; -# if VERY_FAST && !ULTRA_FAST - --ip; -# endif - hval = FRST (ip); - - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - -# if VERY_FAST && !ULTRA_FAST - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; -# endif -#else - ip -= len + 1; - - do - { - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - } - while (len--); -#endif - } - else - { - /* one more literal byte we must copy */ - if (expect_false (op >= out_end)) - return 0; - - lit++; *op++ = *ip++; - - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } - } - } - - if (op + 3 > out_end) /* at most 3 bytes can be missing here */ - return 0; - - while (ip < in_end) - { - lit++; *op++ = *ip++; - - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } - } - - op [- lit - 1] = lit - 1; /* end run */ - op -= !lit; /* undo run if length is zero */ - - return op - (u8 *)out_data; -} - diff --git a/src - Cópia/floppy/lzf/lzf_d.c b/src - Cópia/floppy/lzf/lzf_d.c deleted file mode 100644 index 8433b8f1f..000000000 --- a/src - Cópia/floppy/lzf/lzf_d.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2000-2010 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include "lzfP.h" - -#if AVOID_ERRNO -# define SET_ERRNO(n) -#else -# include -# define SET_ERRNO(n) errno = (n) -#endif - -#if USE_REP_MOVSB /* small win on amd, big loss on intel */ -#if (__i386 || __amd64) && __GNUC__ >= 3 -# define lzf_movsb(dst, src, len) \ - asm ("rep movsb" \ - : "=D" (dst), "=S" (src), "=c" (len) \ - : "0" (dst), "1" (src), "2" (len)); -#endif -#endif - -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len) -{ - u8 const *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - u8 const *const in_end = ip + in_len; - u8 *const out_end = op + out_len; - - do - { - unsigned int ctrl = *ip++; - - if (ctrl < (1 << 5)) /* literal run */ - { - ctrl++; - - if (op + ctrl > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } - -#if CHECK_INPUT - if (ip + ctrl > in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - -#ifdef lzf_movsb - lzf_movsb (op, ip, ctrl); -#else - switch (ctrl) - { - case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++; - case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++; - case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++; - case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++; - case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++; - case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++; - case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++; - case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++; - } -#endif - } - else /* back reference */ - { - unsigned int len = ctrl >> 5; - - u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; - -#if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - if (len == 7) - { - len += *ip++; -#if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - } - - ref -= *ip++; - - if (op + len + 2 > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } - - if (ref < (u8 *)out_data) - { - SET_ERRNO (EINVAL); - return 0; - } - -#ifdef lzf_movsb - len += 2; - lzf_movsb (op, ref, len); -#else - switch (len) - { - default: - len += 2; - - if (op >= ref + len) - { - /* disjunct areas */ - memcpy (op, ref, len); - op += len; - } - else - { - /* overlapping, use octte by octte copying */ - do - *op++ = *ref++; - while (--len); - } - - break; - - case 9: *op++ = *ref++; - case 8: *op++ = *ref++; - case 7: *op++ = *ref++; - case 6: *op++ = *ref++; - case 5: *op++ = *ref++; - case 4: *op++ = *ref++; - case 3: *op++ = *ref++; - case 2: *op++ = *ref++; - case 1: *op++ = *ref++; - case 0: *op++ = *ref++; /* two octets more */ - *op++ = *ref++; - } -#endif - } - } - while (ip < in_end); - - return op - (u8 *)out_data; -} - diff --git a/src - Cópia/game/gameport.c b/src - Cópia/game/gameport.c deleted file mode 100644 index 53b9dac52..000000000 --- a/src - Cópia/game/gameport.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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. - * - * Implementation of a generic Game Port. - * - * Version: @(#)gameport.c 1.0.6 2018/04/29 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../machine/machine.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../io.h" -#include "../timer.h" -#include "gameport.h" -#include "joystick_ch_flightstick_pro.h" -#include "joystick_standard.h" -#include "joystick_sw_pad.h" -#include "joystick_tm_fcs.h" - - -typedef struct { - int64_t count; - int axis_nr; - struct _gameport_ *gameport; -} g_axis_t; - -typedef struct _gameport_ { - uint8_t state; - - g_axis_t axis[4]; - - const joystick_if_t *joystick; - void *joystick_dat; -} gameport_t; - - -int joystick_type; - - -static const joystick_if_t joystick_none = { - "No joystick", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - 0 -}; - - -static const joystick_if_t *joystick_list[] = { - &joystick_standard, - &joystick_standard_4button, - &joystick_standard_6button, - &joystick_standard_8button, - &joystick_ch_flightstick_pro, - &joystick_sw_pad, - &joystick_tm_fcs, - &joystick_none, - NULL -}; -static gameport_t *gameport_global = NULL; - - -char * -joystick_get_name(int js) -{ - if (! joystick_list[js]) - return(NULL); - return((char *)joystick_list[js]->name); -} - - -int -joystick_get_max_joysticks(int js) -{ - return(joystick_list[js]->max_joysticks); -} - - -int -joystick_get_axis_count(int js) -{ - return(joystick_list[js]->axis_count); -} - - -int -joystick_get_button_count(int js) -{ - return(joystick_list[js]->button_count); -} - - -int -joystick_get_pov_count(int js) -{ - return(joystick_list[js]->pov_count); -} - - -char * -joystick_get_axis_name(int js, int id) -{ - return((char *)joystick_list[js]->axis_names[id]); -} - - -char * -joystick_get_button_name(int js, int id) -{ - return((char *)joystick_list[js]->button_names[id]); -} - - -char * -joystick_get_pov_name(int js, int id) -{ - return (char *)joystick_list[js]->pov_names[id]; -} - - -static int -gameport_time(int axis) -{ - if (axis == AXIS_NOT_PRESENT) return(0); - - axis += 32768; - axis = (axis * 100) / 65; /*Axis now in ohms*/ - axis = (axis * 11) / 1000; - - return(TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/ -} - - -static void -gameport_write(uint16_t addr, uint8_t val, void *priv) -{ - gameport_t *p = (gameport_t *)priv; - - timer_clock(); - p->state |= 0x0f; - - p->axis[0].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 0)); - p->axis[1].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 1)); - p->axis[2].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 2)); - p->axis[3].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 3)); - - p->joystick->write(p->joystick_dat); - - cycles -= ISA_CYCLES(8); -} - - -static uint8_t -gameport_read(uint16_t addr, void *priv) -{ - gameport_t *p = (gameport_t *)priv; - uint8_t ret; - - timer_clock(); - ret = p->state | p->joystick->read(p->joystick_dat); - - cycles -= ISA_CYCLES(8); - - return(ret); -} - - -static void -timer_over(void *priv) -{ - g_axis_t *axis = (g_axis_t *)priv; - gameport_t *p = axis->gameport; - - p->state &= ~(1 << axis->axis_nr); - axis->count = 0; - - if (axis == &p->axis[0]) - p->joystick->a0_over(p->joystick_dat); -} - - -static void * -init_common(void) -{ - gameport_t *p = malloc(sizeof(gameport_t)); - - memset(p, 0x00, sizeof(gameport_t)); - - p->axis[0].gameport = p; - p->axis[1].gameport = p; - p->axis[2].gameport = p; - p->axis[3].gameport = p; - - p->axis[0].axis_nr = 0; - p->axis[1].axis_nr = 1; - p->axis[2].axis_nr = 2; - p->axis[3].axis_nr = 3; - - timer_add(timer_over, &p->axis[0].count, &p->axis[0].count, &p->axis[0]); - timer_add(timer_over, &p->axis[1].count, &p->axis[1].count, &p->axis[1]); - timer_add(timer_over, &p->axis[2].count, &p->axis[2].count, &p->axis[2]); - timer_add(timer_over, &p->axis[3].count, &p->axis[3].count, &p->axis[3]); - - p->joystick = joystick_list[joystick_type]; - p->joystick_dat = p->joystick->init(); - - gameport_global = p; - - return(p); -} - - -void -gameport_update_joystick_type(void) -{ - gameport_t *p = gameport_global; - - if (p != NULL) { - p->joystick->close(p->joystick_dat); - p->joystick = joystick_list[joystick_type]; - p->joystick_dat = p->joystick->init(); - } -} - - -static void * -gameport_init(const device_t *info) -{ - gameport_t *p = NULL; - - if (joystick_type == 7) { - p = NULL; - return(p); - } - - p = init_common(); - - io_sethandler(0x0200, 8, - gameport_read,NULL,NULL, gameport_write,NULL,NULL, p); - - return(p); -} - - -static void * -gameport_201_init(const device_t *info) -{ - gameport_t *p; - - if (joystick_type == 7) { - p = NULL; - return(p); - } - - p = init_common(); - - io_sethandler(0x0201, 1, - gameport_read,NULL,NULL, gameport_write,NULL,NULL, p); - - return(p); -} - - -static void -gameport_close(void *priv) -{ - gameport_t *p = (gameport_t *)priv; - - if (p == NULL) return; - - p->joystick->close(p->joystick_dat); - - gameport_global = NULL; - - free(p); -} - - -const device_t gameport_device = { - "Game port", - 0, 0, - gameport_init, - gameport_close, - NULL, NULL, NULL, - NULL -}; - -const device_t gameport_201_device = { - "Game port (port 201h only)", - 0, 0, - gameport_201_init, - gameport_close, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/game/gameport.h b/src - Cópia/game/gameport.h deleted file mode 100644 index 3db999646..000000000 --- a/src - Cópia/game/gameport.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 generic game port handlers. - * - * NOTE: This module needs a good cleanup someday. - * - * Version: @(#)gameport.h 1.0.3 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2017 Sarah Walker. - * - * 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 EMU_GAMEPORT_H -# define EMU_GAMEPORT_H - - -#define MAX_PLAT_JOYSTICKS 8 -#define MAX_JOYSTICKS 4 - -#define POV_X 0x80000000 -#define POV_Y 0x40000000 - -#define AXIS_NOT_PRESENT -99999 - -#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) - - -typedef struct { - char name[64]; - - int a[8]; - int b[32]; - int p[4]; - - struct { - char name[32]; - int id; - } axis[8]; - - struct { - char name[32]; - int id; - } button[32]; - - struct { - char name[32]; - int id; - } pov[4]; - - int nr_axes; - int nr_buttons; - int nr_povs; -} plat_joystick_t; - -typedef struct { - int axis[8]; - int button[32]; - int pov[4]; - - int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; -} joystick_t; - -typedef struct { - const char *name; - - void *(*init)(void); - void (*close)(void *p); - uint8_t (*read)(void *p); - void (*write)(void *p); - int (*read_axis)(void *p, int axis); - void (*a0_over)(void *p); - - int axis_count, - button_count, - pov_count; - int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; -} joystick_if_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef EMU_DEVICE_H -extern const device_t gameport_device; -extern const device_t gameport_201_device; -#endif - -extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -extern joystick_t joystick_state[MAX_JOYSTICKS]; -extern int joysticks_present; - -extern int joystick_type; - - -extern void joystick_init(void); -extern void joystick_close(void); -extern void joystick_process(void); - -extern char *joystick_get_name(int js); -extern int joystick_get_max_joysticks(int js); -extern int joystick_get_axis_count(int js); -extern int joystick_get_button_count(int js); -extern int joystick_get_pov_count(int js); -extern char *joystick_get_axis_name(int js, int id); -extern char *joystick_get_button_name(int js, int id); -extern char *joystick_get_pov_name(int js, int id); - -extern void gameport_update_joystick_type(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_GAMEPORT_H*/ diff --git a/src - Cópia/game/joystick_ch_flightstick_pro.c b/src - Cópia/game/joystick_ch_flightstick_pro.c deleted file mode 100644 index 062e753a6..000000000 --- a/src - Cópia/game/joystick_ch_flightstick_pro.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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. - * - * Implementation of the Flight Stick Pro. - * - * Version: @(#)flightstick_pro.c 1.0.4 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "gameport.h" -#include "joystick_standard.h" - - -static void *ch_flightstick_pro_init(void) -{ - return NULL; -} - -static void ch_flightstick_pro_close(void *p) -{ -} - -static uint8_t ch_flightstick_pro_read(void *p) -{ - uint8_t ret = 0xf0; - - if (JOYSTICK_PRESENT(0)) - { - if (joystick_state[0].button[0]) - ret &= ~0x10; - if (joystick_state[0].button[1]) - ret &= ~0x20; - if (joystick_state[0].button[2]) - ret &= ~0x40; - if (joystick_state[0].button[3]) - ret &= ~0x80; - if (joystick_state[0].pov[0] != -1) - { - if (joystick_state[0].pov[0] > 315 || joystick_state[0].pov[0] < 45) - ret &= ~0xf0; - else if (joystick_state[0].pov[0] >= 45 && joystick_state[0].pov[0] < 135) - ret &= ~0xb0; - else if (joystick_state[0].pov[0] >= 135 && joystick_state[0].pov[0] < 225) - ret &= ~0x70; - else if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) - ret &= ~0x30; - } - } - - return ret; -} - -static void ch_flightstick_pro_write(void *p) -{ -} - -static int ch_flightstick_pro_read_axis(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - switch (axis) - { - case 0: - return joystick_state[0].axis[0]; - case 1: - return joystick_state[0].axis[1]; - case 2: - return 0; - case 3: - return joystick_state[0].axis[2]; - default: - return 0; - } -} - -static void ch_flightstick_pro_a0_over(void *p) -{ -} - -const joystick_if_t joystick_ch_flightstick_pro = -{ - "CH Flightstick Pro", - ch_flightstick_pro_init, - ch_flightstick_pro_close, - ch_flightstick_pro_read, - ch_flightstick_pro_write, - ch_flightstick_pro_read_axis, - ch_flightstick_pro_a0_over, - 3, - 4, - 1, - 1, - {"X axis", "Y axis", "Throttle"}, - {"Button 1", "Button 2", "Button 3", "Button 4"}, - {"POV"} -}; diff --git a/src - Cópia/game/joystick_ch_flightstick_pro.h b/src - Cópia/game/joystick_ch_flightstick_pro.h deleted file mode 100644 index 7cbb71767..000000000 --- a/src - Cópia/game/joystick_ch_flightstick_pro.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 Flight Stick Pro driver. - * - * Version: @(#)joystick_ch_flightstickpro.h 1.0.2 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ - -extern const joystick_if_t joystick_ch_flightstick_pro; diff --git a/src - Cópia/game/joystick_standard.c b/src - Cópia/game/joystick_standard.c deleted file mode 100644 index f05634a9b..000000000 --- a/src - Cópia/game/joystick_standard.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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. - * - * Implementation of a standard joystick. - * - * Version: @(#)joystick_standard.c 1.0.4 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "gameport.h" -#include "joystick_standard.h" - - -static void *joystick_standard_init(void) -{ - return NULL; -} - -static void joystick_standard_close(void *p) -{ -} - -static uint8_t joystick_standard_read(void *p) -{ - uint8_t ret = 0xf0; - - if (JOYSTICK_PRESENT(0)) - { - if (joystick_state[0].button[0]) - ret &= ~0x10; - if (joystick_state[0].button[1]) - ret &= ~0x20; - } - if (JOYSTICK_PRESENT(1)) - { - if (joystick_state[1].button[0]) - ret &= ~0x40; - if (joystick_state[1].button[1]) - ret &= ~0x80; - } - - return ret; -} - -static uint8_t joystick_standard_read_4button(void *p) -{ - uint8_t ret = 0xf0; - - if (JOYSTICK_PRESENT(0)) - { - if (joystick_state[0].button[0]) - ret &= ~0x10; - if (joystick_state[0].button[1]) - ret &= ~0x20; - if (joystick_state[0].button[2]) - ret &= ~0x40; - if (joystick_state[0].button[3]) - ret &= ~0x80; - } - - return ret; -} - -static void joystick_standard_write(void *p) -{ -} - -static int joystick_standard_read_axis(void *p, int axis) -{ - switch (axis) - { - case 0: - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - return joystick_state[0].axis[0]; - case 1: - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - return joystick_state[0].axis[1]; - case 2: - if (!JOYSTICK_PRESENT(1)) - return AXIS_NOT_PRESENT; - return joystick_state[1].axis[0]; - case 3: - if (!JOYSTICK_PRESENT(1)) - return AXIS_NOT_PRESENT; - return joystick_state[1].axis[1]; - default: - return 0; - } -} - -static int joystick_standard_read_axis_4button(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - switch (axis) - { - case 0: - return joystick_state[0].axis[0]; - case 1: - return joystick_state[0].axis[1]; - case 2: - return 0; - case 3: - return 0; - default: - return 0; - } -} -static int joystick_standard_read_axis_6button(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - switch (axis) - { - case 0: - return joystick_state[0].axis[0]; - case 1: - return joystick_state[0].axis[1]; - case 2: - return joystick_state[0].button[4] ? -32767 : 32768; - case 3: - return joystick_state[0].button[5] ? -32767 : 32768; - default: - return 0; - } -} -static int joystick_standard_read_axis_8button(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - switch (axis) - { - case 0: - return joystick_state[0].axis[0]; - case 1: - return joystick_state[0].axis[1]; - case 2: - if (joystick_state[0].button[4]) - return -32767; - if (joystick_state[0].button[6]) - return 32768; - return 0; - case 3: - if (joystick_state[0].button[5]) - return -32767; - if (joystick_state[0].button[7]) - return 32768; - return 0; - default: - return 0; - } -} - -static void joystick_standard_a0_over(void *p) -{ -} - -const joystick_if_t joystick_standard = -{ - "Standard 2-button joystick(s)", - joystick_standard_init, - joystick_standard_close, - joystick_standard_read, - joystick_standard_write, - joystick_standard_read_axis, - joystick_standard_a0_over, - 2, - 2, - 0, - 2, - {"X axis", "Y axis"}, - {"Button 1", "Button 2"} -}; -const joystick_if_t joystick_standard_4button = -{ - "Standard 4-button joystick", - joystick_standard_init, - joystick_standard_close, - joystick_standard_read_4button, - joystick_standard_write, - joystick_standard_read_axis_4button, - joystick_standard_a0_over, - 2, - 4, - 0, - 1, - {"X axis", "Y axis"}, - {"Button 1", "Button 2", "Button 3", "Button 4"} -}; -const joystick_if_t joystick_standard_6button = -{ - "Standard 6-button joystick", - joystick_standard_init, - joystick_standard_close, - joystick_standard_read_4button, - joystick_standard_write, - joystick_standard_read_axis_6button, - joystick_standard_a0_over, - 2, - 6, - 0, - 1, - {"X axis", "Y axis"}, - {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} -}; -const joystick_if_t joystick_standard_8button = -{ - "Standard 8-button joystick", - joystick_standard_init, - joystick_standard_close, - joystick_standard_read_4button, - joystick_standard_write, - joystick_standard_read_axis_8button, - joystick_standard_a0_over, - 2, - 8, - 0, - 1, - {"X axis", "Y axis"}, - {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8"} -}; diff --git a/src - Cópia/game/joystick_standard.h b/src - Cópia/game/joystick_standard.h deleted file mode 100644 index 26b16998e..000000000 --- a/src - Cópia/game/joystick_standard.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 joystick driver. - * - * Version: @(#)joystick_standard.h 1.0.2 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ - -extern const joystick_if_t joystick_standard; -extern const joystick_if_t joystick_standard_4button; -extern const joystick_if_t joystick_standard_6button; -extern const joystick_if_t joystick_standard_8button; diff --git a/src - Cópia/game/joystick_sw_pad.c b/src - Cópia/game/joystick_sw_pad.c deleted file mode 100644 index feec60593..000000000 --- a/src - Cópia/game/joystick_sw_pad.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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. - * - * Implementation of a Side Winder GamePad. - * - * Notes: - Write to 0x201 starts packet transfer (5*N or 15*N bits) - * - Currently alternates between Mode A and Mode B (is there - * any way of actually controlling which is used?) - * - Windows 9x drivers require Mode B when more than 1 pad - * connected - * - Packet preceeded by high data (currently 50us), and - * followed by low data (currently 160us) - timings are - * probably wrong, but good enoughfor everything I've tried - * - Analog inputs are only used to time ID packet request. - * If A0 timing out is followed after ~64us by another 0x201 - * write then an ID packet is triggered - * - Sidewinder game pad ID is 'H0003' - * - ID is sent in Mode A (1 bit per clock), but data bit 2 - * must change during ID packet transfer, or Windows 9x - * drivers won't use Mode B. I don't know if it oscillates, - * mirrors the data transfer, or something else - the drivers - * only check that it changes at least 10 times during the - * transfer - * - Some DOS stuff will write to 0x201 while a packet is - * being transferred. This seems to be ignored. - * - * Version: @(#)sw_pad.c 1.0.5 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "gameport.h" -#include "joystick_sw_pad.h" - - -typedef struct -{ - int64_t poll_time; - int64_t poll_left; - int64_t poll_clock; - uint64_t poll_data; - int64_t poll_mode; - - int64_t trigger_time; - int64_t data_mode; -} sw_data; - -static void sw_timer_over(void *p) -{ - sw_data *sw = (sw_data *)p; - - while (sw->poll_time <= 0 && sw->poll_left) - { - sw->poll_clock = !sw->poll_clock; - - if (sw->poll_clock) - { - sw->poll_data >>= (sw->poll_mode ? 3 : 1); - sw->poll_left--; - } - - if (sw->poll_left == 1 && !sw->poll_clock) - sw->poll_time += TIMER_USEC * 160LL; - else if (sw->poll_left) - sw->poll_time += TIMER_USEC * 5; - else - sw->poll_time = 0; - } - - if (!sw->poll_left) - sw->poll_time = 0; -} - -static void sw_trigger_timer_over(void *p) -{ - sw_data *sw = (sw_data *)p; - - sw->trigger_time = 0; -} - -static int sw_parity(uint16_t data) -{ - int bits_set = 0; - - while (data) - { - bits_set++; - data &= (data - 1); - } - - return bits_set & 1; -} - -static void *sw_init(void) -{ - sw_data *sw = (sw_data *)malloc(sizeof(sw_data)); - memset(sw, 0, sizeof(sw_data)); - - timer_add(sw_timer_over, &sw->poll_time, &sw->poll_time, sw); - timer_add(sw_trigger_timer_over, &sw->trigger_time, &sw->trigger_time, sw); - - return sw; -} - -static void sw_close(void *p) -{ - sw_data *sw = (sw_data *)p; - - free(sw); -} - -static uint8_t sw_read(void *p) -{ - sw_data *sw = (sw_data *)p; - uint8_t temp = 0; - - if (!JOYSTICK_PRESENT(0)) - return 0xff; - - if (sw->poll_time) - { - if (sw->poll_clock) - temp |= 0x10; - - if (sw->poll_mode) - temp |= (sw->poll_data & 7) << 5; - else - { - temp |= ((sw->poll_data & 1) << 5) | 0xc0; - if (sw->poll_left > 31 && !(sw->poll_left & 1)) - temp &= ~0x80; - } - } - else - temp |= 0xf0; - - return temp; -} - -static void sw_write(void *p) -{ - sw_data *sw = (sw_data *)p; - int64_t time_since_last = sw->trigger_time / TIMER_USEC; - - if (!JOYSTICK_PRESENT(0)) - return; - - timer_process(); - - if (!sw->poll_left) - { - sw->poll_clock = 1; - sw->poll_time = TIMER_USEC * 50; - - if (time_since_last > 9900 && time_since_last < 9940) - { - sw->poll_mode = 0; - sw->poll_left = 49; - sw->poll_data = 0x2400ull | (0x1830ull << 15) | (0x19b0ull << 30); - } - else - { - int c; - - sw->poll_mode = sw->data_mode; - sw->data_mode = !sw->data_mode; - - if (sw->poll_mode) - { - sw->poll_left = 1; - sw->poll_data = 7; - } - else - { - sw->poll_left = 1; - sw->poll_data = 1; - } - - for (c = 0; c < 4; c++) - { - uint16_t data = 0x3fff; - int b; - - if (!JOYSTICK_PRESENT(c)) - break; - - if (joystick_state[c].axis[1] < -16383) - data &= ~1; - if (joystick_state[c].axis[1] > 16383) - data &= ~2; - if (joystick_state[c].axis[0] > 16383) - data &= ~4; - if (joystick_state[c].axis[0] < -16383) - data &= ~8; - - for (b = 0; b < 10; b++) - { - if (joystick_state[c].button[b]) - data &= ~(1 << (b + 4)); - } - - if (sw_parity(data)) - data |= 0x4000; - - if (sw->poll_mode) - { - sw->poll_left += 5; - sw->poll_data |= (data << (c*15 + 3)); - } - else - { - sw->poll_left += 15; - sw->poll_data |= (data << (c*15 + 1)); - } - } - } - } - - sw->trigger_time = 0; - - timer_update_outstanding(); -} - -static int sw_read_axis(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - return 0LL; /*No analogue support on Sidewinder game pad*/ -} - -static void sw_a0_over(void *p) -{ - sw_data *sw = (sw_data *)p; - - sw->trigger_time = TIMER_USEC * 10000; -} - -const joystick_if_t joystick_sw_pad = -{ - "Microsoft SideWinder Pad", - sw_init, - sw_close, - sw_read, - sw_write, - sw_read_axis, - sw_a0_over, - 2, - 10, - 0, - 4, - {"X axis", "Y axis"}, - {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"} -}; diff --git a/src - Cópia/game/joystick_sw_pad.h b/src - Cópia/game/joystick_sw_pad.h deleted file mode 100644 index 0cd4132a5..000000000 --- a/src - Cópia/game/joystick_sw_pad.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 Sidewinder Pro driver. - * - * Version: @(#)joystick_sw_pad.h 1.0.2 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ - -extern const joystick_if_t joystick_sw_pad; diff --git a/src - Cópia/game/joystick_tm_fcs.c b/src - Cópia/game/joystick_tm_fcs.c deleted file mode 100644 index 69fa19d2b..000000000 --- a/src - Cópia/game/joystick_tm_fcs.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - * - * Implementation of Thrust Master Flight Control System. - * - * Version: @(#)tm_fcs.c 1.0.3 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "gameport.h" -#include "joystick_standard.h" - - -static void *tm_fcs_init(void) -{ - return NULL; -} - -static void tm_fcs_close(void *p) -{ -} - -static uint8_t tm_fcs_read(void *p) -{ - uint8_t ret = 0xf0; - - if (JOYSTICK_PRESENT(0)) - { - if (joystick_state[0].button[0]) - ret &= ~0x10; - if (joystick_state[0].button[1]) - ret &= ~0x20; - if (joystick_state[0].button[2]) - ret &= ~0x40; - if (joystick_state[0].button[3]) - ret &= ~0x80; - } - - return ret; -} - -static void tm_fcs_write(void *p) -{ -} - -static int tm_fcs_read_axis(void *p, int axis) -{ - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; - - switch (axis) - { - case 0: - return joystick_state[0].axis[0]; - case 1: - return joystick_state[0].axis[1]; - case 2: - return 0; - case 3: - if (joystick_state[0].pov[0] == -1) - return 32767; - if (joystick_state[0].pov[0] > 315 || joystick_state[0].pov[0] < 45) - return -32768; - if (joystick_state[0].pov[0] >= 45 && joystick_state[0].pov[0] < 135) - return -16384; - if (joystick_state[0].pov[0] >= 135 && joystick_state[0].pov[0] < 225) - return 0; - if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) - return 16384; - return 0; - default: - return 0; - } -} - -static void tm_fcs_a0_over(void *p) -{ -} - -const joystick_if_t joystick_tm_fcs = -{ - "Thrustmaster Flight Control System", - tm_fcs_init, - tm_fcs_close, - tm_fcs_read, - tm_fcs_write, - tm_fcs_read_axis, - tm_fcs_a0_over, - 2, - 4, - 1, - 1, - {"X axis", "Y axis"}, - {"Button 1", "Button 2", "Button 3", "Button 4"}, - {"POV"} -}; diff --git a/src - Cópia/game/joystick_tm_fcs.h b/src - Cópia/game/joystick_tm_fcs.h deleted file mode 100644 index 7ada355ed..000000000 --- a/src - Cópia/game/joystick_tm_fcs.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 Flight Control System driver. - * - * Version: @(#)joystick_tm_fcs.h 1.0.2 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ - -extern const joystick_if_t joystick_tm_fcs; diff --git a/src - Cópia/gcc_check.sh b/src - Cópia/gcc_check.sh deleted file mode 100644 index cd6e1b509..000000000 --- a/src - Cópia/gcc_check.sh +++ /dev/null @@ -1 +0,0 @@ -gcc $1 -Wall -Wclobbered -Wbad-function-cast -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wmissing-parameter-type -Wold-style-declaration -Woverride-init -Wsign-compare -Wtype-limits -Wuninitialized -Wunknown-pragmas -pedantic -Werror -Wshadow diff --git a/src - Cópia/gcc_check_ioctl.sh b/src - Cópia/gcc_check_ioctl.sh deleted file mode 100644 index 934f0873f..000000000 --- a/src - Cópia/gcc_check_ioctl.sh +++ /dev/null @@ -1 +0,0 @@ -gcc $1 -Wall -Wclobbered -Wbad-function-cast -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wmissing-parameter-type -Wold-style-declaration -Woverride-init -Wsign-compare -Wtype-limits -Wuninitialized -Wunknown-pragmas -pedantic -Werror -Wshadow -DUSE_IOCTL diff --git a/src - Cópia/i82335.c b/src - Cópia/i82335.c deleted file mode 100644 index b0043a1a5..000000000 --- a/src - Cópia/i82335.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Intel 82335 SX emulation, used by the Phoenix 386 clone. */ - -#include -#include -#include -#include -#include "io.h" -#include "mem.h" - -typedef struct -{ - uint8_t reg_22; - uint8_t reg_23; -} i82335_t; - -i82335_t i82335; - -uint8_t i82335_read(uint16_t addr, void *priv); - -void i82335_write(uint16_t addr, uint8_t val, void *priv) -{ - int i = 0; - - int mem_write = 0; - - // pclog("i82335_write(%04X, %02X)\n", addr, val); - - switch (addr) - { - case 0x22: - if ((val ^ i82335.reg_22) & 1) - { - if (val & 1) - { - for (i = 0; i < 8; i++) - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - shadowbios = 1; - } - } - else - { - for (i = 0; i < 8; i++) - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - shadowbios = 0; - } - } - - flushmmucache(); - } - - i82335.reg_22 = val | 0xd8; - break; - case 0x23: - i82335.reg_23 = val; - - if ((val ^ i82335.reg_22) & 2) - { - if (val & 2) - { - for (i = 0; i < 8; i++) - { - mem_set_mem_state(0xc0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - shadowbios = 1; - } - } - else - { - for (i = 0; i < 8; i++) - { - mem_set_mem_state(0xc0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - shadowbios = 0; - } - } - } - - if ((val ^ i82335.reg_22) & 0xc) - { - if (val & 2) - { - for (i = 0; i < 8; i++) - { - mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | mem_write); - shadowbios = 1; - } - } - else - { - for (i = 0; i < 8; i++) - { - mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTERNAL; - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | mem_write); - shadowbios = 0; - } - } - } - - if ((val ^ i82335.reg_22) & 0xe) - { - flushmmucache(); - } - - if (val & 0x80) - { - io_removehandler(0x0022, 0x0001, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); - } - break; - } -} - -uint8_t i82335_read(uint16_t addr, void *priv) -{ - // pclog("i82335_read(%04X)\n", addr); - if (addr == 0x22) - { - return i82335.reg_22; - } - else if (addr == 0x23) - { - return i82335.reg_23; - } - else - { - return 0; - } -} - -void i82335_init() -{ - memset(&i82335, 0, sizeof(i82335_t)); - - i82335.reg_22 = 0xd8; - - io_sethandler(0x0022, 0x0014, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); -} diff --git a/src - Cópia/i82335.h b/src - Cópia/i82335.h deleted file mode 100644 index 7cb4c4ef3..000000000 --- a/src - Cópia/i82335.h +++ /dev/null @@ -1 +0,0 @@ -extern void i82335_init(void); diff --git a/src - Cópia/intel.c b/src - Cópia/intel.c deleted file mode 100644 index 327052780..000000000 --- a/src - Cópia/intel.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" -#include "mem.h" -#include "pit.h" -#include "timer.h" -#include "intel.h" - - -uint8_t batman_brdconfig(uint16_t port, void *p) -{ - switch (port) - { - case 0x73: - return 0xff; - case 0x75: - return 0xdf; - } - return 0; -} - -static uint16_t batman_timer_latch; -static int64_t batman_timer = 0; -static void batman_timer_over(void *p) -{ - batman_timer = 0; -} - -static void batman_timer_write(uint16_t addr, uint8_t val, void *p) -{ - if (addr & 1) - batman_timer_latch = (batman_timer_latch & 0xff) | (val << 8); - else - batman_timer_latch = (batman_timer_latch & 0xff00) | val; - batman_timer = batman_timer_latch * TIMER_USEC; -} - -static uint8_t batman_timer_read(uint16_t addr, void *p) -{ - uint16_t batman_timer_latch; - - cycles -= (int)PITCONST; - - timer_clock(); - - if (batman_timer < 0) - return 0; - - batman_timer_latch = batman_timer / TIMER_USEC; - - if (addr & 1) - return batman_timer_latch >> 8; - return batman_timer_latch & 0xff; -} - -void intel_batman_init() -{ - io_sethandler(0x0073, 0x0001, batman_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); - io_sethandler(0x0075, 0x0001, batman_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); - - io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL); - timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL); -} diff --git a/src - Cópia/intel.h b/src - Cópia/intel.h deleted file mode 100644 index d2603bcbd..000000000 --- a/src - Cópia/intel.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern void intel_batman_init(void); -extern void intel_endeavor_init(void); diff --git a/src - Cópia/intel_flash.c b/src - Cópia/intel_flash.c deleted file mode 100644 index a619212ac..000000000 --- a/src - Cópia/intel_flash.c +++ /dev/null @@ -1,327 +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. - * - * Implementation of the Intel 1 Mbit 8-bit flash devices. - * - * Version: @(#)intel_flash.c 1.0.16 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "device.h" -#include "mem.h" -#include "machine/machine.h" -#include "nvr.h" -#include "plat.h" - - -#define FLASH_IS_BXB 2 -#define FLASH_INVERT 1 - -#define BLOCK_MAIN 0 -#define BLOCK_DATA1 1 -#define BLOCK_DATA2 2 -#define BLOCK_BOOT 3 - -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; - uint8_t flash_id; - int invert_high_pin; - mem_mapping_t mapping[8], mapping_h[8]; - uint32_t block_start[4], block_end[4], block_len[4]; - uint8_t array[131072]; -} flash_t; - -static wchar_t flash_path[1024]; - -static uint8_t flash_read(uint32_t addr, void *p) -{ - flash_t *flash = (flash_t *)p; - if (flash->invert_high_pin) - addr ^= 0x10000; - addr &= 0x1ffff; - switch (flash->command) { - case CMD_READ_ARRAY: - default: - return flash->array[addr]; - - case CMD_IID: - if (addr & 1) - return flash->flash_id; - return 0x89; - - case CMD_READ_STATUS: - return flash->status; - } -} - -static uint16_t flash_readw(uint32_t addr, void *p) -{ - flash_t *flash = (flash_t *)p; - uint16_t *q; - addr &= 0x1ffff; - if (flash->invert_high_pin) addr ^= 0x10000; - q = (uint16_t *)&(flash->array[addr]); - return *q; -} - -static uint32_t flash_readl(uint32_t addr, void *p) -{ - flash_t *flash = (flash_t *)p; - uint32_t *q; - addr &= 0x1ffff; - if (flash->invert_high_pin) addr ^= 0x10000; - q = (uint32_t *)&(flash->array[addr]); - return *q; -} - -static void flash_write(uint32_t addr, uint8_t val, void *p) -{ - flash_t *flash = (flash_t *)p; - int i; - - if (flash->invert_high_pin) - addr ^= 0x10000; - addr &= 0x1ffff; - - switch (flash->command) { - case CMD_ERASE_SETUP: - if (val == CMD_ERASE_CONFIRM) { - for (i = 0; i < 3; i++) { - if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i])) - memset(&(flash->array[flash->block_start[i]]), 0xff, flash->block_len[i]); - } - - flash->status = 0x80; - } - flash->command = CMD_READ_STATUS; - break; - - case CMD_PROGRAM_SETUP: - case CMD_PROGRAM_SETUP_ALT: - if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) - flash->array[addr] = val; - flash->command = CMD_READ_STATUS; - flash->status = 0x80; - break; - - default: - flash->command = val; - switch (val) { - case CMD_CLEAR_STATUS: - flash->status = 0; - break; - } - } -} - -static void intel_flash_add_mappings(flash_t *flash) -{ - int i = 0; - - for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash); - } -} - -/* This is for boards which invert the high pin - the flash->array pointers need to pointer invertedly in order for INTERNAL writes to go to the right part of the array. */ -static void intel_flash_add_mappings_inverted(flash_t *flash) -{ - int i = 0; - - for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash); - } -} - -void *intel_flash_init(uint8_t type) -{ - FILE *f; - int i, l; - flash_t *flash; - wchar_t *machine_name; - wchar_t *flash_name; - - flash = malloc(sizeof(flash_t)); - memset(flash, 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); - - wcscpy(flash_path, flash_name); - - flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; - flash->invert_high_pin = (type & FLASH_INVERT); - - /* The block lengths are the same both flash types. */ - flash->block_len[BLOCK_MAIN] = 0x1c000; - flash->block_len[BLOCK_DATA1] = 0x01000; - flash->block_len[BLOCK_DATA2] = 0x01000; - flash->block_len[BLOCK_BOOT] = 0x02000; - - if (type & FLASH_IS_BXB) { /* 28F001BX-B */ - flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1ffff; - flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x03fff; - flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x04fff; - flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x01fff; - } else { /* 28F001BX-T */ - flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1bfff; - flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x1cfff; - flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x1dfff; - flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x1ffff; - } - - for (i = 0; i < 8; i++) { - mem_mapping_disable(&bios_mapping[i]); - mem_mapping_disable(&bios_high_mapping[i]); - } - - if (flash->invert_high_pin) { - memcpy(flash->array, rom + 65536, 65536); - memcpy(flash->array + 65536, rom, 65536); - } - else - memcpy(flash->array, rom, 131072); - - if (flash->invert_high_pin) - intel_flash_add_mappings_inverted(flash); - else - intel_flash_add_mappings(flash); - - flash->command = CMD_READ_ARRAY; - flash->status = 0; - - f = nvr_fopen(flash_path, L"rb"); - if (f) { - fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); - fread(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); - fclose(f); - } - - free(flash_name); - free(machine_name); - - return flash; -} - -void *intel_flash_bxb_ami_init() -{ - return intel_flash_init(FLASH_IS_BXB | FLASH_INVERT); -} - -/* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ -void *intel_flash_bxt_ami_init() -{ - return intel_flash_init(FLASH_INVERT); -} - -/* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ -void *intel_flash_bxt_init() -{ - return intel_flash_init(0); -} - -/* For Acer BIOS'es - Intel 28F001BXB. */ -void *intel_flash_bxb_init() -{ - return intel_flash_init(FLASH_IS_BXB); -} - -void intel_flash_close(void *p) -{ - FILE *f; - flash_t *flash = (flash_t *)p; - - f = nvr_fopen(flash_path, L"wb"); - fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); - fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); - fclose(f); - - free(flash); -} - - -const device_t intel_flash_bxt_ami_device = -{ - "Intel 28F001BXT Flash BIOS", - 0, 0, - intel_flash_bxt_ami_init, - intel_flash_close, - NULL, - NULL, NULL, NULL, NULL -}; - -const device_t intel_flash_bxb_ami_device = -{ - "Intel 28F001BXB Flash BIOS", - 0, 0, - intel_flash_bxb_ami_init, - intel_flash_close, - NULL, - NULL, NULL, NULL, NULL -}; - -const device_t intel_flash_bxt_device = -{ - "Intel 28F001BXT Flash BIOS", - 0, 0, - intel_flash_bxt_init, - intel_flash_close, - NULL, - NULL, NULL, NULL, NULL -}; - -const device_t intel_flash_bxb_device = -{ - "Intel 28F001BXB Flash BIOS", - 0, 0, - intel_flash_bxb_init, - intel_flash_close, - NULL, - NULL, NULL, NULL, NULL -}; diff --git a/src - Cópia/intel_flash.h b/src - Cópia/intel_flash.h deleted file mode 100644 index 241a07c02..000000000 --- a/src - Cópia/intel_flash.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 1 Mbit 8-bit flash devices. - * - * Version: @(#)intel_flash.h 1.0.1 2018/03/14 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -extern const device_t intel_flash_bxt_ami_device; -extern const device_t intel_flash_bxb_ami_device; -extern const device_t intel_flash_bxt_device; -extern const device_t intel_flash_bxb_device; diff --git a/src - Cópia/intel_piix.c b/src - Cópia/intel_piix.c deleted file mode 100644 index 43f8dd17b..000000000 --- a/src - Cópia/intel_piix.c +++ /dev/null @@ -1,916 +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. - * - * 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.17 2018/06/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "dma.h" -#include "io.h" -#include "device.h" -#include "keyboard.h" -#include "mem.h" -#include "pci.h" -#include "pic.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/zip.h" -#include "piix.h" - - -typedef struct -{ - uint8_t command, status, - ptr0; - uint32_t ptr, ptr_cur, - addr; - int count, eot; -} piix_busmaster_t; - -typedef struct -{ - int type; - uint8_t regs[256], regs_ide[256]; - piix_busmaster_t bm[2]; -} piix_t; - - -static uint8_t piix_bus_master_read(uint16_t port, void *priv); -static uint16_t piix_bus_master_readw(uint16_t port, void *priv); -static uint32_t piix_bus_master_readl(uint16_t port, void *priv); -static void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); -static void piix_bus_master_writew(uint16_t port, uint16_t val, void *priv); -static void piix_bus_master_writel(uint16_t port, uint32_t val, void *priv); - - -#ifdef ENABLE_PIIX_LOG -int piix_do_log = ENABLE_PIIX_LOG; -#endif - - -static void -piix_log(const char *format, ...) -{ -#ifdef ENABLE_PIIX_LOG - va_list ap; - - if (piix_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#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); - io_removehandler(old_base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_removehandler(old_base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - - if ((dev->regs_ide[0x04] & 1) && base) { - io_sethandler(base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_sethandler(base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - } -} - - -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 = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - if (func > 1) - return; - - 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(); - } - - 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)) - 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 (val & 0x80) { - if (dev->type == 3) - dma_alias_remove(); - else - dma_alias_remove_piix(); - } else - dma_alias_set(); - } - 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); - 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 (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; - } - - dev->regs[addr] = val; - } -} - - -static uint8_t -piix_read(int func, int addr, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ - return 0xff; - if (func > 1) - return 0xff; - - 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]; - } - - return 0; -} - - -static void -piix_bus_master_next_addr(piix_busmaster_t *dev) -{ - DMAPageRead(dev->ptr_cur, (uint8_t *)&(dev->addr), 4); - DMAPageRead(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4); - piix_log("PIIX Bus master DWORDs: %08X %08X\n", dev->addr, dev->count); - dev->eot = dev->count >> 31; - dev->count &= 0xfffe; - if (!dev->count) - dev->count = 65536; - dev->addr &= 0xfffffffe; - dev->ptr_cur += 8; -} - - -static void -piix_bus_master_write(uint16_t port, uint8_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - int channel = (port & 8) ? 1 : 0; - - piix_log("PIIX Bus master BYTE write: %04X %02X\n", port, val); - - switch (port & 7) { - case 0: - piix_log("PIIX Cmd : val = %02X, old = %02X\n", val, dev->command); - if ((val & 1) && !(dev->command & 1)) { /*Start*/ - piix_log("PIIX Bus Master start on channel %i\n", channel); - dev->ptr_cur = dev->ptr; - piix_bus_master_next_addr(dev); - dev->status |= 1; - } - if (!(val & 1) && (dev->command & 1)) { /*Stop*/ - piix_log("PIIX Bus Master stop on channel %i\n", channel); - dev->status &= ~1; - } - - dev->command = val; - break; - case 2: - piix_log("PIIX Status: val = %02X, old = %02X\n", val, dev->status); - dev->status &= 0x07; - dev->status |= (val & 0x60); - if (val & 0x04) - dev->status &= ~0x04; - if (val & 0x02) - dev->status &= ~0x02; - break; - case 4: - dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val; - break; - case 5: - dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8); - dev->ptr %= (mem_size * 1024); - break; - case 6: - dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; - case 7: - dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); - dev->ptr %= (mem_size * 1024); - break; - } -} - - -static void -piix_bus_master_writew(uint16_t port, uint16_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - piix_log("PIIX Bus master WORD write: %04X %04X\n", port, val); - - switch (port & 7) { - case 0: - case 2: - piix_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; - case 6: - dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; - } -} - - -static void -piix_bus_master_writel(uint16_t port, uint32_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - piix_log("PIIX Bus master DWORD write: %04X %08X\n", port, val); - - switch (port & 7) { - case 0: - case 2: - piix_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (val & 0xfffffffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; - } -} - - -static uint8_t -piix_bus_master_read(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: - ret = dev->command; - break; - case 2: - ret = dev->status & 0x67; - break; - case 4: - ret = dev->ptr0; - break; - case 5: - ret = dev->ptr >> 8; - break; - case 6: - ret = dev->ptr >> 16; - break; - case 7: - ret = dev->ptr >> 24; - break; - } - - piix_log("PIIX Bus master BYTE read : %04X %02X\n", port, ret); - - return ret; -} - - -static uint16_t -piix_bus_master_readw(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint16_t ret = 0xffff; - - switch (port & 7) { - case 0: - case 2: - ret = (uint16_t) piix_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xff00); - break; - case 6: - ret = dev->ptr >> 16; - break; - } - - piix_log("PIIX Bus master WORD read : %04X %04X\n", port, ret); - - return ret; -} - - -static uint32_t -piix_bus_master_readl(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint32_t ret = 0xffffffff; - - switch (port & 7) { - case 0: - case 2: - ret = (uint32_t) piix_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xffffff00); - break; - } - - piix_log("PIIX Bus master DWORD read : %04X %08X\n", port, ret); - - return ret; -} - - -static int -piix_bus_master_dma_op(int channel, uint8_t *data, int transfer_length, int out, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - char *sop; - - int force_end = 0, buffer_pos = 0; - - sop = out ? "Writ" : "Read"; - - if (!(dev->status & 1)) - return 2; /*DMA disabled*/ - - piix_log("PIIX Bus master %s: %i bytes\n", out ? "read" : "write", transfer_length); - - while (1) { - if (dev->count <= transfer_length) { - piix_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr); - if (out) - DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), dev->count); - else - DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), dev->count); - transfer_length -= dev->count; - buffer_pos += dev->count; - } else { - piix_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr); - if (out) - DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length); - else - DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length); - /* Increase addr and decrease count so that resumed transfers do not mess up. */ - dev->addr += transfer_length; - dev->count -= transfer_length; - transfer_length = 0; - force_end = 1; - } - - if (force_end) { - piix_log("Total transfer length smaller than sum of all blocks, partial block\n"); - dev->status &= ~2; - return 0; /* This block has exhausted the data to transfer and it was smaller than the count, break. */ - } else { - if (!transfer_length && !dev->eot) { - piix_log("Total transfer length smaller than sum of all blocks, full block\n"); - dev->status &= ~2; - return 0; /* We have exhausted the data to transfer but there's more blocks left, break. */ - } else if (transfer_length && dev->eot) { - piix_log("Total transfer length greater than sum of all blocks\n"); - dev->status |= 2; - return 1; /* There is data left to transfer but we have reached EOT - return with error. */ - } else if (dev->eot) { - piix_log("Regular EOT\n"); - dev->status &= ~3; - return 0; /* We have regularly reached EOT - clear status and break. */ - } else { - /* We have more to transfer and there are blocks left, get next block. */ - piix_bus_master_next_addr(dev); - } - } - } - return 0; -} - - -int -piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv) -{ - return piix_bus_master_dma_op(channel, data, transfer_length, 1, priv); -} - - -int -piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv) -{ - return piix_bus_master_dma_op(channel, data, transfer_length, 0, priv); -} - - -void -piix_bus_master_set_irq(int channel, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - dev->status &= ~4; - dev->status |= (channel >> 4); - - channel &= 0x01; - if (dev->status & 0x04) { - if (channel && pci_use_mirq(0)) - pci_set_mirq(0); - else - picint(1 << (14 + channel)); - } else { - if ((channel & 1) && pci_use_mirq(0)) - pci_clear_mirq(0); - else - picintc(1 << (14 + channel)); - } -} - - -static void -piix_bus_master_reset(piix_t *dev) -{ - uint8_t i; - - uint16_t old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - if (old_base) { - io_removehandler(old_base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_removehandler(old_base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - } - - for (i = 0; i < 2; i++) { - dev->bm[i].command = 0x00; - dev->bm[i].status = 0x00; - dev->bm[i].ptr = dev->bm[i].ptr_cur = 0x00000000; - dev->bm[i].addr = 0x00000000; - dev->bm[i].ptr0 = 0x00; - dev->bm[i].count = dev->bm[i].eot = 0x00000000; - } -} - - -static void -piix_reset_hard(void *priv) -{ - piix_t *piix = (piix_t *) priv; - - piix_bus_master_reset(piix); - - memset(piix->regs, 0, 256); - memset(piix->regs_ide, 0, 256); - - 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)*/ - } - 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)*/ - } - 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) - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - - ide_pri_disable(); - ide_sec_disable(); -} - - -static void -piix_reset(void *p) -{ - int i = 0; - - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) - cdrom_reset(cdrom[i]); - } - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - zip_reset(zip[i]); - } -} - - -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)); - memset(piix, 0, sizeof(piix_t)); - - device_add(&ide_pci_2ch_device); - - pci_add_card(7, piix_read, piix_write, piix); - - piix->type = info->local; - piix_reset_hard(piix); - - ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, - piix_bus_master_set_irq, - &piix->bm[0], &piix->bm[1]); - - port_92_reset(); - - port_92_add(); - - dma_alias_set(); - - pci_enable_mirq(0); - pci_enable_mirq(1); - - return piix; -} - - -const device_t piix_device = -{ - "Intel 82371FB (PIIX)", - DEVICE_PCI, - 1, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; - -const device_t piix_pb640_device = -{ - "Intel 82371FB (PIIX) (PB640)", - DEVICE_PCI, - 0x101, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; - -const device_t piix3_device = -{ - "Intel 82371SB (PIIX3)", - DEVICE_PCI, - 3, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src - Cópia/intel_piix4.c b/src - Cópia/intel_piix4.c deleted file mode 100644 index ed4b49335..000000000 --- a/src - Cópia/intel_piix4.c +++ /dev/null @@ -1,393 +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. - * - * Preliminary emulation of the Intel PIIX4 Xcelerator. - * - * PRD format : - * word 0 - base address - * word 1 - bits 1-15 = byte count, bit 31 = end of transfer - * - * Version: @(#)intel_piix4.c 1.0.3 2018/02/14 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "dma.h" -#include "io.h" -#include "device.h" -#include "keyboard.h" -#include "mem.h" -#include "pci.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "piix.h" - - -static uint8_t card_piix4[256], card_piix4_ide[256]; - - -static void piix4_write(int func, int addr, uint8_t val, void *priv) -{ - uint16_t old_base = (card_piix4_ide[0x20] & 0xf0) | (card_piix4_ide[0x21] << 8); - if (func > 1) - return; - - if (func == 1) /*IDE*/ - { - /* pclog("PIIX IDE write: %02X %02X\n", addr, val); */ - - switch (addr) - { - case 0x04: - card_piix4_ide[0x04] = (val & 5) | 2; - break; - case 0x07: - card_piix4_ide[0x07] = val & 0x3e; - break; - case 0x0d: - card_piix4_ide[0x0d] = val; - break; - - case 0x20: - card_piix4_ide[0x20] = (val & ~0x0f) | 1; - break; - case 0x21: - card_piix4_ide[0x21] = val; - break; - - case 0x40: - card_piix4_ide[0x40] = val; - break; - case 0x41: - if ((val ^ card_piix4_ide[0x41]) & 0x80) - { - ide_pri_disable(); - if (val & 0x80) - ide_pri_enable(); - } - card_piix4_ide[0x41] = val; - break; - case 0x42: - card_piix4_ide[0x42] = val; - break; - case 0x43: - if ((val ^ card_piix4_ide[0x43]) & 0x80) - { - ide_sec_disable(); - if (val & 0x80) - ide_sec_enable(); - } - card_piix4_ide[0x43] = val; - break; - case 0x44: - card_piix4_ide[0x44] = val; - break; - case 0x48: - card_piix4_ide[0x44] = val; - break; - case 0x4A: - card_piix4_ide[0x44] = val; - break; - case 0x4B: - card_piix4_ide[0x44] = val; - break; - } - if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ - { - uint16_t base = (card_piix4_ide[0x20] & 0xf0) | (card_piix4_ide[0x21] << 8); - io_removehandler(old_base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); - if (card_piix4_ide[0x04] & 1) - { - io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); - } - } - } - else - { - /* pclog("PIIX writing value %02X to register %02X\n", val, addr); */ - if ((addr >= 0x0f) && (addr < 0x4c)) - return; - - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x60: - /* pclog("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: - /* pclog("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: - /* pclog("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: - /* pclog("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; - } - if (addr == 0x4C) - { - if (!((val ^ card_piix4[addr]) & 0x80)) - { - card_piix4[addr] = val; - return; - } - - card_piix4[addr] = val; - if (val & 0x80) - { - dma_alias_remove(); - } - else - { - dma_alias_set(); - } - } - else if (addr == 0x4E) - { - keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); - card_piix4[addr] = val; - } - else - card_piix4[addr] = val; - } -} - -static uint8_t piix4_read(int func, int addr, void *priv) -{ - if (func > 1) - return 0xff; - - if (func == 1) /*IDE*/ - { - if (addr == 4) - { - return (card_piix4_ide[addr] & 5); - } - else if (addr == 5) - { - return 0; - } - else if (addr == 6) - { - return 0x80; - } - else if (addr == 7) - { - return card_piix4_ide[addr] & 0x3E; - } - else if (addr == 0xD) - { - return card_piix4_ide[addr] & 0xF0; - } - else if (addr == 0x20) - { - return (card_piix4_ide[addr] & 0xF0) | 1; - } - else if (addr == 0x22) - { - return 0; - } - else if (addr == 0x23) - { - return 0; - } - else if (addr == 0x41) - { - return card_piix4_ide[addr] & 0xF3; - } - else if (addr == 0x43) - { - return card_piix4_ide[addr] & 0xF3; - } - else if (addr == 0x48) - { - return card_piix4_ide[addr] & 0x0F; - } - else if (addr == 0x4A) - { - return card_piix4_ide[addr] & 0x33; - } - else if (addr == 0x4B) - { - return card_piix4_ide[addr] & 0x33; - } - else - { - return card_piix4_ide[addr]; - } - } - else - { - if ((addr & 0xFC) == 0x60) - { - return card_piix4[addr] & 0x8F; - } - if (addr == 4) - { - return (card_piix4[addr] & 0x08) | 7; - } - else if (addr == 5) - { - return card_piix4[addr] & 0x01; - } - else if (addr == 6) - { - return 0x80; - } - else if (addr == 7) - { - return (card_piix4[addr] & 0x78) | 0x02; - } - else if (addr == 0x4E) - { - return (card_piix4[addr] & 0xEF) | keyboard_at_get_mouse_scan(); - } - else if (addr == 0x4F) - { - return card_piix4[addr] & 0x06; - } - else if (addr == 0x69) - { - return card_piix4[addr] & 0xFE; - } - else if (addr == 0x6A) - { - return card_piix4[addr] & 0x80; - } - else if (addr == 0x6B) - { - return card_piix4[addr] & 0x80; - } - else if (addr == 0x76) - { - return (card_piix4[addr] & 0x87) | 0x08; - } - else if (addr == 0x77) - { - return (card_piix4[addr] & 0x87) | 0x08; - } - else if (addr == 0x80) - { - return card_piix4[addr] & 0x7F; - } - else if (addr == 0x82) - { - return card_piix4[addr] & 0x0F; - } - else if (addr == 0x91) - { - return card_piix4[addr] & 0xFC; - } - else if (addr == 0x92) - { - return card_piix4[addr] & 0xC0; - } - else if (addr == 0x94) - { - return card_piix4[addr] & 0xC0; - } - else if (addr == 0xB0) - { - return card_piix4[addr] & 0x7F; - } - else if (addr == 0xB1) - { - return card_piix4[addr] & 0xDF; - } - else if (addr == 0xB3) - { - return card_piix4[addr] & 0xFD; - } - else if (addr == 0xCB) - { - return card_piix4[addr] & 0x3D; - } - else - return card_piix4[addr]; - } - - return 0; -} - -void piix4_reset(void) -{ - memset(card_piix4, 0, 256); - memset(card_piix4_ide, 0, 256); - - card_piix4[0x00] = 0x86; card_piix4[0x01] = 0x80; /*Intel*/ - card_piix4[0x02] = 0x10; card_piix4[0x03] = 0x71; /*82371AB (PIIX4)*/ - card_piix4[0x04] = 0x07; card_piix4[0x05] = 0x00; - card_piix4[0x06] = 0x80; card_piix4[0x07] = 0x02; - card_piix4[0x08] = 0x00; /*A0 stepping*/ - card_piix4[0x09] = 0x00; card_piix4[0x0a] = 0x01; card_piix4[0x0b] = 0x06; - card_piix4[0x0e] = 0x80; /*Multi-function device*/ - card_piix4[0x4c] = 0x4d; - card_piix4[0x4e] = 0x03; - card_piix4[0x60] = card_piix4[0x61] = card_piix4[0x62] = card_piix4[0x63] = 0x80; - card_piix4[0x64] = 0x10; - card_piix4[0x69] = 0x02; - card_piix4[0x76] = card_piix4[0x77] = 0x04; - card_piix4[0xcb] = 0x21; - - card_piix4_ide[0x00] = 0x86; card_piix4_ide[0x01] = 0x80; /*Intel*/ - card_piix4_ide[0x02] = 0x11; card_piix4_ide[0x03] = 0x71; /*82371AB (PIIX)*/ - card_piix4_ide[0x04] = 0x07; card_piix4_ide[0x05] = 0x00; - card_piix4_ide[0x06] = 0x80; card_piix4_ide[0x07] = 0x02; - card_piix4_ide[0x08] = 0x00; - card_piix4_ide[0x09] = 0x80; card_piix4_ide[0x0a] = 0x01; card_piix4_ide[0x0b] = 0x01; - card_piix4_ide[0x0d] = 0x00; - card_piix4_ide[0x0e] = 0x00; - card_piix4_ide[0x20] = 0x01; card_piix4_ide[0x21] = card_piix4_ide[0x22] = card_piix4_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix4_ide[0x40] = card_piix4_ide[0x42] = 0x00; - card_piix4_ide[0x41] = card_piix4_ide[0x43] = 0x80; -} - -void piix4_init(int card) -{ - device_add(&ide_pci_2ch_device); - - pci_add_card(card, piix4_read, piix4_write, NULL); - - piix4_reset(); - - ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, piix_bus_master_set_irq); - - port_92_reset(); - - port_92_add(); - - dma_alias_set(); - - pci_reset_handler.pci_set_reset = piix4_reset; -} diff --git a/src - Cópia/intel_sio.c b/src - Cópia/intel_sio.c deleted file mode 100644 index 69c35fa78..000000000 --- a/src - Cópia/intel_sio.c +++ /dev/null @@ -1,207 +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. - * - * Emulation of Intel System I/O PCI chip. - * - * Version: @(#)intel_sio.c 1.0.8 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "device.h" -#include "cpu/cpu.h" -#include "io.h" -#include "dma.h" -#include "mem.h" -#include "pci.h" -#include "intel_sio.h" - - -typedef struct -{ - uint8_t regs[256]; -} sio_t; - - -static void -sio_write(int func, int addr, uint8_t val, void *priv) -{ - sio_t *dev = (sio_t *) priv; - - if (func > 0) - return; - - if (addr >= 0x0f && addr < 0x4c) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x08; - val |= 0x07; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x40: - if (!((val ^ dev->regs[addr]) & 0x40)) - return; - - if (val & 0x40) - dma_alias_remove(); - else - dma_alias_set(); - break; - - case 0x4f: - if (!((val ^ dev->regs[addr]) & 0x40)) - return; - - if (val & 0x40) - port_92_add(); - else - port_92_remove(); - - case 0x60: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x61: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x62: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x63: - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - } - dev->regs[addr] = val; -} - - -static uint8_t -sio_read(int func, int addr, void *priv) -{ - sio_t *dev = (sio_t *) priv; - uint8_t ret; - - ret = 0xff; - - if (func == 0) - ret = dev->regs[addr]; - - return ret; -} - - -static void -sio_reset(void *priv) -{ - sio_t *dev = (sio_t *) priv; - - memset(dev->regs, 0, 256); - - dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/ - dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/ - dev->regs[0x04] = 0x07; dev->regs[0x05] = 0x00; - dev->regs[0x06] = 0x00; dev->regs[0x07] = 0x02; - dev->regs[0x08] = 0x03; /*A0 stepping*/ - - dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00; - dev->regs[0x42] = 0x04; dev->regs[0x43] = 0x00; - dev->regs[0x44] = 0x20; dev->regs[0x45] = 0x10; - dev->regs[0x46] = 0x0f; dev->regs[0x47] = 0x00; - dev->regs[0x48] = 0x01; dev->regs[0x49] = 0x10; - dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f; - dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40; - dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f; - dev->regs[0x54] = 0x00; dev->regs[0x55] = 0x00; dev->regs[0x56] = 0x00; - dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80; - dev->regs[0x80] = 0x78; dev->regs[0x81] = 0x00; - dev->regs[0xa0] = 0x08; - dev->regs[0xa8] = 0x0f; - - 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); -} - - -static void -sio_close(void *p) -{ - sio_t *sio = (sio_t *)p; - - free(sio); -} - - -static void -*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); - - sio_reset(sio); - - port_92_reset(); - - port_92_add(); - - dma_alias_set(); - - return sio; -} - - -const device_t sio_device = -{ - "Intel 82378IB (SIO)", - DEVICE_PCI, - 0, - sio_init, - sio_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src - Cópia/intel_sio.h b/src - Cópia/intel_sio.h deleted file mode 100644 index b1976b9b2..000000000 --- a/src - Cópia/intel_sio.h +++ /dev/null @@ -1,17 +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. - * - * Emulation of Intel System I/O PCI chip. - * - * Version: @(#)sio.h 1.0.3 2018/03/26 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t sio_device; diff --git a/src - Cópia/io.c b/src - Cópia/io.c deleted file mode 100644 index 8a8b5b6d2..000000000 --- a/src - Cópia/io.c +++ /dev/null @@ -1,415 +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. - * - * Implement I/O ports and their operations. - * - * Version: @(#)io.c 1.0.4 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "io.h" -#include "cpu/cpu.h" - - -#define NPORTS 65536 /* PC/AT supports 64K ports */ - - -typedef struct _io_ { - uint8_t (*inb)(uint16_t addr, void *priv); - uint16_t (*inw)(uint16_t addr, void *priv); - uint32_t (*inl)(uint16_t addr, void *priv); - - void (*outb)(uint16_t addr, uint8_t val, void *priv); - void (*outw)(uint16_t addr, uint16_t val, void *priv); - void (*outl)(uint16_t addr, uint32_t val, void *priv); - - void *priv; - - struct _io_ *prev, *next; -} io_t; - -int initialized = 0; -io_t *io[NPORTS], *io_last[NPORTS]; - - -#ifdef ENABLE_IO_LOG -int io_do_log = ENABLE_IO_LOG; -#endif - - -#ifdef ENABLE_IO_LOG -static void -io_log(const char *format, ...) -{ -#ifdef ENABLE_IO_LOG - va_list ap; - - if (io_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} -#endif - - -#ifdef ENABLE_IO_LOG -static uint8_t null_inb(uint16_t addr, void *priv) { io_log("IO: read(%04x)\n"); return(0xff); } -static uint16_t null_inw(uint16_t addr, void *priv) { io_log("IO: readw(%04x)\n"); return(0xffff); } -static uint32_t null_inl(uint16_t addr, void *priv) { io_log("IO: readl(%04x)\n"); return(0xffffffff); } -static void null_outb(uint16_t addr, uint8_t val, void *priv) { io_log("IO: write(%04x, %02x)\n", val); } -static void null_outw(uint16_t addr, uint16_t val, void *priv) { io_log("IO: writew(%04x, %04x)\n", val); } -static void null_outl(uint16_t addr, uint32_t val, void *priv) { io_log("IO: writel(%04x, %08lx)\n", val); } -#endif - - -void -io_init(void) -{ - int c; - io_t *p, *q; - - if (!initialized) { - for (c=0; cprev; - free(p); - p = q; - } - p = NULL; - } - -#ifdef ENABLE_IO_LOG - /* io[c] should be the only handler, pointing at the NULL catch handler. */ - p = (io_t *) malloc(sizeof(io_t)); - memset(p, 0, sizeof(io_t)); - io[c] = io_last[c] = p; - p->next = NULL; - p->prev = NULL; - p->inb = null_inb; - p->outb = null_outb; - p->inw = null_inw; - p->outw = null_outw; - p->inl = null_inl; - p->outl = null_outl; - p->priv = NULL; -#else - /* io[c] should be NULL. */ - io[c] = io_last[c] = NULL; -#endif - } -} - - -void -io_sethandler(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv) -{ - int c; - io_t *p, *q = NULL; - - for (c = 0; c < size; c++) { - p = io_last[base + c]; - q = (io_t *) malloc(sizeof(io_t)); - memset(q, 0, sizeof(io_t)); - if (p) { - p->next = q; - q->prev = p; - } else { - io[base + c] = q; - q->prev = NULL; - } - - q->inb = inb; - q->inw = inw; - q->inl = inl; - - q->outb = outb; - q->outw = outw; - q->outl = outl; - - q->priv = priv; - q->next = NULL; - - io_last[base + c] = q; - } -} - - -void -io_removehandler(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv) -{ - int c; - io_t *p; - - for (c = 0; c < size; c++) { - p = io[base + c]; - if (!p) - continue; - while(p) { - if ((p->inb == inb) && (p->inw == inw) && - (p->inl == inl) && (p->outb == outb) && - (p->outw == outw) && (p->outl == outl) && - (p->priv == priv)) { - if (p->prev) - p->prev->next = p->next; - else - io[base + c] = p->next; - if (p->next) - p->next->prev = p->prev; - else - io_last[base + c] = p->prev; - free(p); - p = NULL; - break; - } - p = p->next; - } - } -} - - -#ifdef PC98 -void -io_sethandler_interleaved(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv) -{ - int c; - io_t *p, *q; - - size <<= 2; - for (c=0; cnext = q; - q->prev = p; - } else { - io[base + c] = q; - q->prev = NULL; - } - - q->inb = inb; - q->inw = inw; - q->inl = inl; - - q->outb = outb; - q->outw = outw; - q->outl = outl; - - q->priv = priv; - } -} - - -void -io_removehandler_interleaved(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv) -{ - int c; - io_t *p; - - size <<= 2; - for (c = 0; c < size; c += 2) { - p = io[base + c]; - if (!p) - return; - while(p) { - if ((p->inb == inb) && (p->inw == inw) && - (p->inl == inl) && (p->outb == outb) && - (p->outw == outw) && (p->outl == outl) && - (p->priv == priv)) { - if (p->prev) - p->prev->next = p->next; - if (p->next) - p->next->prev = p->prev; - free(p); - break; - } - p = p->next; - } - } -} -#endif - - -uint8_t -inb(uint16_t port) -{ - uint8_t r = 0xff; - io_t *p; - - p = io[port]; - if (p) { - while(p) { - if (p->inb) - r &= p->inb(port, p->priv); - p = p->next; - } - } - -#ifdef ENABLE_IO_LOG - if (CS == IO_TRACE) - io_log("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, r); -#endif - - return(r); -} - - -void -outb(uint16_t port, uint8_t val) -{ - io_t *p; - - if (io[port]) { - p = io[port]; - while(p) { - if (p->outb) - p->outb(port, val, p->priv); - p = p->next; - } - } - -#ifdef ENABLE_IO_LOG - if (CS == IO_TRACE) - io_log("IOTRACE(%04X): outb(%04x,%02x)\n", IO_TRACE, port, val); -#endif - return; -} - - -uint16_t -inw(uint16_t port) -{ - io_t *p; - - p = io[port]; - if (p) { - while(p) { - if (p->inw) - return p->inw(port, p->priv); - p = p->next; - } - } - - return(inb(port) | (inb(port + 1) << 8)); -} - - -void -outw(uint16_t port, uint16_t val) -{ - io_t *p; - - p = io[port]; - if (p) { - while(p) { - if (p->outw) { - p->outw(port, val, p->priv); - return; - } - p = p->next; - } - } - - outb(port,val); - outb(port+1,val>>8); - - return; -} - - -uint32_t -inl(uint16_t port) -{ - io_t *p; - - p = io[port]; - if (p) { - while(p) { - if (p->inl) - return p->inl(port, p->priv); - p = p->next; - } - } - - return(inw(port) | (inw(port + 2) << 16)); -} - - -void -outl(uint16_t port, uint32_t val) -{ - io_t *p; - - p = io[port]; - if (p) { - while(p) { - if (p->outl) { - p->outl(port, val, p->priv); - return; - } - p = p->next; - } - } - - outw(port, val); - outw(port + 2, val >> 16); - - return; -} diff --git a/src - Cópia/io.h b/src - Cópia/io.h deleted file mode 100644 index 43b23c00d..000000000 --- a/src - Cópia/io.h +++ /dev/null @@ -1,72 +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. - * - * Definitions for the I/O handler. - * - * Version: @(#)io.h 1.0.1 2017/12/16 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_IO_H -# define EMU_IO_H - - -extern void io_init(void); - -extern void io_sethandler(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv); - -extern void io_removehandler(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv); - -#ifdef PC98 -extern void io_sethandler_interleaved(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv); - -extern void io_removehandler_interleaved(uint16_t base, int size, - uint8_t (*inb)(uint16_t addr, void *priv), - uint16_t (*inw)(uint16_t addr, void *priv), - uint32_t (*inl)(uint16_t addr, void *priv), - void (*outb)(uint16_t addr, uint8_t val, void *priv), - void (*outw)(uint16_t addr, uint16_t val, void *priv), - void (*outl)(uint16_t addr, uint32_t val, void *priv), - void *priv); -#endif - -extern uint8_t inb(uint16_t port); -extern void outb(uint16_t port, uint8_t val); -extern uint16_t inw(uint16_t port); -extern void outw(uint16_t port, uint16_t val); -extern uint32_t inl(uint16_t port); -extern void outl(uint16_t port, uint32_t val); - - -#endif /*EMU_IO_H*/ diff --git a/src - Cópia/keyboard.c b/src - Cópia/keyboard.c deleted file mode 100644 index 55fea6571..000000000 --- a/src - Cópia/keyboard.c +++ /dev/null @@ -1,331 +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. - * - * General keyboard driver interface. - * - * Version: @(#)keyboard.c 1.0.15 2018/03/19 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2015-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "86box.h" -#include "machine/machine.h" -#include "keyboard.h" - - -int64_t keyboard_delay; -int keyboard_scan; -void (*keyboard_send)(uint16_t val); - - -static int recv_key[512]; /* keyboard input buffer */ -static int oldkey[512]; -#if 0 -static int keydelay[512]; -#endif -static scancode *scan_table; /* scancode table for keyboard */ - -static uint8_t caps_lock = 0; -static uint8_t num_lock = 0; -static uint8_t scroll_lock = 0; -static uint8_t shift = 0; - - -void -keyboard_init(void) -{ - memset(recv_key, 0x00, sizeof(recv_key)); - - keyboard_scan = 1; - keyboard_delay = 0; - scan_table = NULL; - - memset(keyboard_set3_flags, 0x00, sizeof(keyboard_set3_flags)); - keyboard_set3_all_repeat = 0; - keyboard_set3_all_break = 0; -} - - -void -keyboard_set_table(const scancode *ptr) -{ - scan_table = (scancode *) ptr; -} - - -static uint8_t -fake_shift_needed(uint16_t scan) -{ - switch(scan) { - case 0x147: - case 0x148: - case 0x149: - case 0x14a: - case 0x14d: - case 0x14f: - case 0x150: - case 0x151: - case 0x152: - case 0x153: - return 1; - default: - return 0; - } -} - - -void -key_process(uint16_t scan, int down) -{ - scancode *codes = scan_table; - int c; - - if (! keyboard_scan) return; - - oldkey[scan] = down; - if (down && codes[scan].mk[0] == -1) - return; - - if (!down && codes[scan].brk[0] == -1) - return; - - if (AT && ((keyboard_mode & 3) == 3)) { - if (!keyboard_set3_all_break && !down && !(keyboard_set3_flags[codes[scan].mk[0]] & 2)) - return; - } - - c = 0; - if (down) { - /* Send the special code indicating an opening fake shift might be needed. */ - if (fake_shift_needed(scan)) - keyboard_send(0x100); - while (codes[scan].mk[c] != -1) - keyboard_send(codes[scan].mk[c++]); - } else { - while (codes[scan].brk[c] != -1) - keyboard_send(codes[scan].brk[c++]); - /* Send the special code indicating a closing fake shift might be needed. */ - if (fake_shift_needed(scan)) - keyboard_send(0x101); - } -} - - -/* Handle a keystroke event from the UI layer. */ -void -keyboard_input(int down, uint16_t scan) -{ - /* Translate E0 xx scan codes to 01xx because we use 512-byte arrays for states - and scan code sets. */ - if ((scan >> 8) == 0xe0) { - scan &= 0x00ff; - scan |= 0x0100; /* extended key code */ - } else if ((scan >> 8) != 0x01) - scan &= 0x00ff; /* we can receive a scan code whose upper byte is 0x01, - this means we're the Win32 version running on windows - that already sends us preprocessed scan codes, which - means we then use the scan code as is, and need to - make sure we do not accidentally strip that upper byte */ - - if (recv_key[scan & 0x1ff] ^ down) { - if (down) { - switch(scan & 0x1ff) { - case 0x01c: /* Left Ctrl */ - shift |= 0x01; - break; - case 0x11c: /* Right Ctrl */ - shift |= 0x10; - break; - case 0x02a: /* Left Shift */ - shift |= 0x02; - break; - case 0x036: /* Right Shift */ - shift |= 0x20; - break; - case 0x038: /* Left Alt */ - shift |= 0x03; - break; - case 0x138: /* Right Alt */ - shift |= 0x30; - break; - } - } else { - switch(scan & 0x1ff) { - case 0x01c: /* Left Ctrl */ - shift &= ~0x01; - break; - case 0x11c: /* Right Ctrl */ - shift &= ~0x10; - break; - case 0x02a: /* Left Shift */ - shift &= ~0x02; - break; - case 0x036: /* Right Shift */ - shift &= ~0x20; - break; - case 0x038: /* Left Alt */ - shift &= ~0x03; - break; - case 0x138: /* Right Alt */ - shift &= ~0x30; - break; - case 0x03a: /* Caps Lock */ - caps_lock ^= 1; - break; - case 0x045: - num_lock ^= 1; - break; - case 0x046: - scroll_lock ^= 1; - break; - } - } - } - - /* NOTE: Shouldn't this be some sort of bit shift? An array of 8 unsigned 64-bit integers - should be enough. */ - /* recv_key[scan >> 6] |= ((uint64_t) down << ((uint64_t) scan & 0x3fLL)); */ - - /* pclog("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */ - recv_key[scan & 0x1ff] = down; - - key_process(scan & 0x1ff, down); -} - - -static uint8_t -keyboard_do_break(uint16_t scan) -{ - scancode *codes = scan_table; - - if (AT && ((keyboard_mode & 3) == 3)) { - if (!keyboard_set3_all_break && - !recv_key[scan] && - !(keyboard_set3_flags[codes[scan].mk[0]] & 2)) - return 0; - else - return 1; - } else - return 1; -} - - -/* Also called by the emulated keyboard controller to update the states of - Caps Lock, Num Lock, and Scroll Lock when receving the "Set keyboard LEDs" - command. */ -void -keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl) -{ - caps_lock = cl; - num_lock = nl; - scroll_lock = sl; -} - - -uint8_t -keyboard_get_shift(void) -{ - return shift; -} - - -void -keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) -{ - if (cl) - *cl = caps_lock; - if (nl) - *nl = num_lock; - if (sl) - *sl = scroll_lock; -} - - -/* Called by the UI to update the states of Caps Lock, Num Lock, and Scroll Lock. */ -void -keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl) -{ - scancode *codes = scan_table; - - int i; - - if (caps_lock != cl) { - i = 0; - while (codes[0x03a].mk[i] != -1) - keyboard_send(codes[0x03a].mk[i++]); - if (keyboard_do_break(0x03a)) { - i = 0; - while (codes[0x03a].brk[i] != -1) - keyboard_send(codes[0x03a].brk[i++]); - } - } - - if (num_lock != nl) { - i = 0; - while (codes[0x045].mk[i] != -1) - keyboard_send(codes[0x045].mk[i++]); - if (keyboard_do_break(0x045)) { - i = 0; - while (codes[0x045].brk[i] != -1) - keyboard_send(codes[0x045].brk[i++]); - } - } - - if (scroll_lock != sl) { - i = 0; - while (codes[0x046].mk[i] != -1) - keyboard_send(codes[0x046].mk[i++]); - if (keyboard_do_break(0x046)) { - i = 0; - while (codes[0x046].brk[i] != -1) - keyboard_send(codes[0x046].brk[i++]); - } - } - - keyboard_update_states(cl, nl, sl); -} - - -int -keyboard_recv(uint16_t key) -{ - return recv_key[key]; -} - - -/* Do we have Control-Alt-PgDn in the keyboard buffer? */ -int -keyboard_isfsexit(void) -{ - return( (recv_key[0x01D] || recv_key[0x11D]) && - (recv_key[0x038] || recv_key[0x138]) && - (recv_key[0x051] || recv_key[0x151]) ); -} - - -/* Do we have F8-F12 in the keyboard buffer? */ -int -keyboard_ismsexit(void) -{ -#ifdef _WIN32 - /* Windows: F8+F12 */ - return( recv_key[0x042] && recv_key[0x058] ); -#else - /* WxWidgets cannot do two regular keys.. CTRL+END */ - return( (recv_key[0x01D] || recv_key[0x11D]) && (recv_key[0x04F] || recv_key[0x14F]) ); -#endif -} diff --git a/src - Cópia/keyboard.h b/src - Cópia/keyboard.h deleted file mode 100644 index e4c846b7d..000000000 --- a/src - Cópia/keyboard.h +++ /dev/null @@ -1,103 +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. - * - * Definitions for the keyboard interface. - * - * Version: @(#)keyboard.h 1.0.15 2018/03/26 - * - * 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. - */ -#ifndef EMU_KEYBOARD_H -# define EMU_KEYBOARD_H - - -typedef struct { - int mk[9]; - int brk[9]; -} scancode; - - -#define STATE_SHIFT_MASK 0x22 -#define STATE_RSHIFT 0x20 -#define STATE_LSHIFT 0x02 - -#define FAKE_LSHIFT_ON 0x100 -#define FAKE_LSHIFT_OFF 0x101 -#define LSHIFT_ON 0x102 -#define LSHIFT_OFF 0x103 -#define RSHIFT_ON 0x104 -#define RSHIFT_OFF 0x105 - - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint8_t keyboard_mode; -extern int keyboard_scan; -extern int64_t keyboard_delay; - -extern void (*keyboard_send)(uint16_t val); -extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)); - -extern const scancode scancode_xt[512]; - -extern uint8_t keyboard_set3_flags[512]; -extern uint8_t keyboard_set3_all_repeat; -extern uint8_t keyboard_set3_all_break; -extern int mouse_queue_start, mouse_queue_end; -extern int mouse_scan; - -#ifdef EMU_DEVICE_H -extern const device_t keyboard_xt_device; -extern const device_t keyboard_tandy_device; -extern const device_t keyboard_at_device; -extern const device_t keyboard_at_ami_device; -extern const device_t keyboard_at_toshiba_device; -extern const device_t keyboard_ps2_device; -extern const device_t keyboard_ps2_ami_device; -extern const device_t keyboard_ps2_mca_device; -extern const device_t keyboard_ps2_mca_2_device; -extern const device_t keyboard_ps2_quadtel_device; -extern const device_t keyboard_ps2_pci_device; -extern const device_t keyboard_ps2_ami_pci_device; -#endif - -extern void keyboard_init(void); -extern void keyboard_close(void); -extern void keyboard_set_table(const scancode *ptr); -extern void keyboard_poll_host(void); -extern void keyboard_process(void); -extern uint16_t keyboard_convert(int ch); -extern void keyboard_input(int down, uint16_t scan); -extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl); -extern uint8_t keyboard_get_shift(void); -extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl); -extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl); -extern int keyboard_recv(uint16_t key); -extern int keyboard_isfsexit(void); -extern int keyboard_ismsexit(void); - -extern void keyboard_at_adddata_keyboard_raw(uint8_t val); -extern void keyboard_at_adddata_mouse(uint8_t val); -extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *); -extern uint8_t keyboard_at_get_mouse_scan(void); -extern void keyboard_at_set_mouse_scan(uint8_t val); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_KEYBOARD_H*/ diff --git a/src - Cópia/keyboard_at.c b/src - Cópia/keyboard_at.c deleted file mode 100644 index 5a738592f..000000000 --- a/src - Cópia/keyboard_at.c +++ /dev/null @@ -1,2109 +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. - * - * Intel 8042 (AT keyboard controller) emulation. - * - * Version: @(#)keyboard_at.c 1.0.37 2018/05/25 - * - * 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. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "io.h" -#include "pic.h" -#include "pit.h" -#include "ppi.h" -#include "mem.h" -#include "rom.h" -#include "device.h" -#include "timer.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 "keyboard.h" - - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_MFULL 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - -#define PS2_REFRESH_TIME (16LL * TIMER_USEC) - -#define CCB_UNUSED 0x80 -#define CCB_TRANSLATE 0x40 -#define CCB_PCMODE 0x20 -#define CCB_ENABLEKBD 0x10 -#define CCB_IGNORELOCK 0x08 -#define CCB_SYSTEM 0x04 -#define CCB_ENABLEMINT 0x02 -#define CCB_ENABLEKINT 0x01 - -#define CCB_MASK 0x68 -#define MODE_MASK 0x6C - -#define KBC_TYPE_ISA 0x00 -#define KBC_TYPE_PS2_1 0x01 -#define KBC_TYPE_PS2_2 0x02 -#define KBC_TYPE_MASK 0x03 - -#define KBC_VEN_GENERIC 0x00 -#define KBC_VEN_AMI 0x04 -#define KBC_VEN_IBM_MCA 0x08 -#define KBC_VEN_QUADTEL 0x0C -#define KBC_VEN_TOSHIBA 0x10 -#define KBC_VEN_MASK 0x1C - -typedef struct { - int initialized; - int want60, - wantirq, - wantirq12; - uint8_t command; - uint8_t status; - uint8_t mem[0x100]; - uint8_t out; - int out_new, out_delayed; - uint8_t secr_phase; - uint8_t mem_addr; - - uint8_t input_port, - output_port; - - uint8_t old_output_port; - - uint8_t key_command; - int key_wantdata; - - int last_irq; - - uint8_t last_scan_code; - - int dtrans; - int first_write; - - int64_t refresh_time; - int refresh; - - uint32_t flags; - uint8_t output_locked; - - int64_t pulse_cb; - uint8_t ami_stat; - - uint8_t (*write60_ven)(void *p, uint8_t val); - uint8_t (*write64_ven)(void *p, uint8_t val); -} atkbd_t; - - -/* bit 0 = repeat, bit 1 = makes break code? */ -uint8_t keyboard_set3_flags[512]; -uint8_t keyboard_set3_all_repeat; -uint8_t keyboard_set3_all_break; - -/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ -uint8_t keyboard_mode = 0x42; - -#ifdef ENABLE_KEYBOARD_AT_LOG -int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; -#endif - -int mouse_queue_start = 0, - mouse_queue_end = 0; - - -static uint8_t key_ctrl_queue[16]; -static int key_ctrl_queue_start = 0, - key_ctrl_queue_end = 0; -static uint8_t key_queue[16]; -static int key_queue_start = 0, - key_queue_end = 0; -static uint8_t mouse_queue[16]; -static void (*mouse_write)(uint8_t val, void *priv) = NULL; -static void *mouse_p = NULL; -static uint8_t sc_or = 0; -static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK - - -/* Non-translated to translated scan codes. */ -static const uint8_t nont_to_t[256] = { - 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, - 0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59, - 0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, - 0x66, 0x71, 0x2C, 0x1F, 0x1E, 0x11, 0x03, 0x5B, - 0x67, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, 0x5C, - 0x68, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, 0x5D, - 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5E, - 0x6A, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5F, - 0x6B, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, 0x60, - 0x6C, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, 0x61, - 0x6D, 0x73, 0x28, 0x74, 0x1A, 0x0D, 0x62, 0x6E, - 0x3A, 0x36, 0x1C, 0x1B, 0x75, 0x2B, 0x63, 0x76, - 0x55, 0x56, 0x77, 0x78, 0x79, 0x7A, 0x0E, 0x7B, - 0x7C, 0x4F, 0x7D, 0x4B, 0x47, 0x7E, 0x7F, 0x6F, - 0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, - 0x57, 0x4E, 0x51, 0x4A, 0x37, 0x49, 0x46, 0x54, - 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, - 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF -}; - -static const scancode scancode_set1[512] = { - { { -1},{ -1} }, { { 0x01,-1},{ 0x81,-1} }, { { 0x02,-1},{ 0x82,-1} }, { { 0x03,-1},{ 0x83,-1} }, /*000*/ - { { 0x04,-1},{ 0x84,-1} }, { { 0x05,-1},{ 0x85,-1} }, { { 0x06,-1},{ 0x86,-1} }, { { 0x07,-1},{ 0x87,-1} }, /*004*/ - { { 0x08,-1},{ 0x88,-1} }, { { 0x09,-1},{ 0x89,-1} }, { { 0x0a,-1},{ 0x8a,-1} }, { { 0x0b,-1},{ 0x8b,-1} }, /*008*/ - { { 0x0c,-1},{ 0x8c,-1} }, { { 0x0d,-1},{ 0x8d,-1} }, { { 0x0e,-1},{ 0x8e,-1} }, { { 0x0f,-1},{ 0x8f,-1} }, /*00c*/ - { { 0x10,-1},{ 0x90,-1} }, { { 0x11,-1},{ 0x91,-1} }, { { 0x12,-1},{ 0x92,-1} }, { { 0x13,-1},{ 0x93,-1} }, /*010*/ - { { 0x14,-1},{ 0x94,-1} }, { { 0x15,-1},{ 0x95,-1} }, { { 0x16,-1},{ 0x96,-1} }, { { 0x17,-1},{ 0x97,-1} }, /*014*/ - { { 0x18,-1},{ 0x98,-1} }, { { 0x19,-1},{ 0x99,-1} }, { { 0x1a,-1},{ 0x9a,-1} }, { { 0x1b,-1},{ 0x9b,-1} }, /*018*/ - { { 0x1c,-1},{ 0x9c,-1} }, { { 0x1d,-1},{ 0x9d,-1} }, { { 0x1e,-1},{ 0x9e,-1} }, { { 0x1f,-1},{ 0x9f,-1} }, /*01c*/ - { { 0x20,-1},{ 0xa0,-1} }, { { 0x21,-1},{ 0xa1,-1} }, { { 0x22,-1},{ 0xa2,-1} }, { { 0x23,-1},{ 0xa3,-1} }, /*020*/ - { { 0x24,-1},{ 0xa4,-1} }, { { 0x25,-1},{ 0xa5,-1} }, { { 0x26,-1},{ 0xa6,-1} }, { { 0x27,-1},{ 0xa7,-1} }, /*024*/ - { { 0x28,-1},{ 0xa8,-1} }, { { 0x29,-1},{ 0xa9,-1} }, { { 0x2a,-1},{ 0xaa,-1} }, { { 0x2b,-1},{ 0xab,-1} }, /*028*/ - { { 0x2c,-1},{ 0xac,-1} }, { { 0x2d,-1},{ 0xad,-1} }, { { 0x2e,-1},{ 0xae,-1} }, { { 0x2f,-1},{ 0xaf,-1} }, /*02c*/ - { { 0x30,-1},{ 0xb0,-1} }, { { 0x31,-1},{ 0xb1,-1} }, { { 0x32,-1},{ 0xb2,-1} }, { { 0x33,-1},{ 0xb3,-1} }, /*030*/ - { { 0x34,-1},{ 0xb4,-1} }, { { 0x35,-1},{ 0xb5,-1} }, { { 0x36,-1},{ 0xb6,-1} }, { { 0x37,-1},{ 0xb7,-1} }, /*034*/ - { { 0x38,-1},{ 0xb8,-1} }, { { 0x39,-1},{ 0xb9,-1} }, { { 0x3a,-1},{ 0xba,-1} }, { { 0x3b,-1},{ 0xbb,-1} }, /*038*/ - { { 0x3c,-1},{ 0xbc,-1} }, { { 0x3d,-1},{ 0xbd,-1} }, { { 0x3e,-1},{ 0xbe,-1} }, { { 0x3f,-1},{ 0xbf,-1} }, /*03c*/ - { { 0x40,-1},{ 0xc0,-1} }, { { 0x41,-1},{ 0xc1,-1} }, { { 0x42,-1},{ 0xc2,-1} }, { { 0x43,-1},{ 0xc3,-1} }, /*040*/ - { { 0x44,-1},{ 0xc4,-1} }, { { 0x45,-1},{ 0xc5,-1} }, { { 0x46,-1},{ 0xc6,-1} }, { { 0x47,-1},{ 0xc7,-1} }, /*044*/ - { { 0x48,-1},{ 0xc8,-1} }, { { 0x49,-1},{ 0xc9,-1} }, { { 0x4a,-1},{ 0xca,-1} }, { { 0x4b,-1},{ 0xcb,-1} }, /*048*/ - { { 0x4c,-1},{ 0xcc,-1} }, { { 0x4d,-1},{ 0xcd,-1} }, { { 0x4e,-1},{ 0xce,-1} }, { { 0x4f,-1},{ 0xcf,-1} }, /*04c*/ - { { 0x50,-1},{ 0xd0,-1} }, { { 0x51,-1},{ 0xd1,-1} }, { { 0x52,-1},{ 0xd2,-1} }, { { 0x53,-1},{ 0xd3,-1} }, /*050*/ - { { 0x54,-1},{ 0xd4,-1} }, { { 0x55,-1},{ 0xd5,-1} }, { { 0x56,-1},{ 0xd6,-1} }, { { 0x57,-1},{ 0xd7,-1} }, /*054*/ - { { 0x58,-1},{ 0xd8,-1} }, { { 0x59,-1},{ 0xd9,-1} }, { { 0x5a,-1},{ 0xda,-1} }, { { 0x5b,-1},{ 0xdb,-1} }, /*058*/ - { { 0x5c,-1},{ 0xdc,-1} }, { { 0x5d,-1},{ 0xdd,-1} }, { { 0x5e,-1},{ 0xde,-1} }, { { 0x5f,-1},{ 0xdf,-1} }, /*05c*/ - { { 0x60,-1},{ 0xe0,-1} }, { { 0x61,-1},{ 0xe1,-1} }, { { 0x62,-1},{ 0xe2,-1} }, { { 0x63,-1},{ 0xe3,-1} }, /*060*/ - { { 0x64,-1},{ 0xe4,-1} }, { { 0x65,-1},{ 0xe5,-1} }, { { 0x66,-1},{ 0xe6,-1} }, { { 0x67,-1},{ 0xe7,-1} }, /*064*/ - { { 0x68,-1},{ 0xe8,-1} }, { { 0x69,-1},{ 0xe9,-1} }, { { 0x6a,-1},{ 0xea,-1} }, { { 0x6b,-1},{ 0xeb,-1} }, /*068*/ - { { 0x6c,-1},{ 0xec,-1} }, { { 0x6d,-1},{ 0xed,-1} }, { { 0x6e,-1},{ 0xee,-1} }, { { 0x6f,-1},{ 0xef,-1} }, /*06c*/ - { { 0x70,-1},{ 0xf0,-1} }, { { 0x71,-1},{ 0xf1,-1} }, { { 0x72,-1},{ 0xf2,-1} }, { { 0x73,-1},{ 0xf3,-1} }, /*070*/ - { { 0x74,-1},{ 0xf4,-1} }, { { 0x75,-1},{ 0xf5,-1} }, { { 0x76,-1},{ 0xf6,-1} }, { { 0x77,-1},{ 0xf7,-1} }, /*074*/ - { { 0x78,-1},{ 0xf8,-1} }, { { 0x79,-1},{ 0xf9,-1} }, { { 0x7a,-1},{ 0xfa,-1} }, { { 0x7b,-1},{ 0xfb,-1} }, /*078*/ - { { 0x7c,-1},{ 0xfc,-1} }, { { 0x7d,-1},{ 0xfd,-1} }, { { 0x7e,-1},{ 0xfe,-1} }, { { 0x7f,-1},{ 0xff,-1} }, /*07c*/ - - { { 0x80,-1},{ -1} }, { { 0x81,-1},{ -1} }, { { 0x82,-1},{ -1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ -1} }, { { 0x86,-1},{ -1} }, { { 0x87,-1},{ -1} }, /*084*/ - { { 0x88,-1},{ -1} }, { { 0x89,-1},{ -1} }, { { 0x8a,-1},{ -1} }, { { 0x8b,-1},{ -1} }, /*088*/ - { { 0x8c,-1},{ -1} }, { { 0x8d,-1},{ -1} }, { { 0x8e,-1},{ -1} }, { { 0x8f,-1},{ -1} }, /*08c*/ - { { 0x90,-1},{ -1} }, { { 0x91,-1},{ -1} }, { { 0x92,-1},{ -1} }, { { 0x93,-1},{ -1} }, /*090*/ - { { 0x94,-1},{ -1} }, { { 0x95,-1},{ -1} }, { { 0x96,-1},{ -1} }, { { 0x97,-1},{ -1} }, /*094*/ - { { 0x98,-1},{ -1} }, { { 0x99,-1},{ -1} }, { { 0x9a,-1},{ -1} }, { { 0x9b,-1},{ -1} }, /*098*/ - { { 0x9c,-1},{ -1} }, { { 0x9d,-1},{ -1} }, { { 0x9e,-1},{ -1} }, { { 0x9f,-1},{ -1} }, /*09c*/ - { { 0xa0,-1},{ -1} }, { { 0xa1,-1},{ -1} }, { { 0xa2,-1},{ -1} }, { { 0xa3,-1},{ -1} }, /*0a0*/ - { { 0xa4,-1},{ -1} }, { { 0xa5,-1},{ -1} }, { { 0xa6,-1},{ -1} }, { { 0xa7,-1},{ -1} }, /*0a4*/ - { { 0xa8,-1},{ -1} }, { { 0xa9,-1},{ -1} }, { { 0xaa,-1},{ -1} }, { { 0xab,-1},{ -1} }, /*0a8*/ - { { 0xac,-1},{ -1} }, { { 0xad,-1},{ -1} }, { { 0xae,-1},{ -1} }, { { 0xaf,-1},{ -1} }, /*0ac*/ - { { 0xb0,-1},{ -1} }, { { 0xb1,-1},{ -1} }, { { 0xb2,-1},{ -1} }, { { 0xb3,-1},{ -1} }, /*0b0*/ - { { 0xb4,-1},{ -1} }, { { 0xb5,-1},{ -1} }, { { 0xb6,-1},{ -1} }, { { 0xb7,-1},{ -1} }, /*0b4*/ - { { 0xb8,-1},{ -1} }, { { 0xb9,-1},{ -1} }, { { 0xba,-1},{ -1} }, { { 0xbb,-1},{ -1} }, /*0b8*/ - { { 0xbc,-1},{ -1} }, { { 0xbd,-1},{ -1} }, { { 0xbe,-1},{ -1} }, { { 0xbf,-1},{ -1} }, /*0bc*/ - { { 0xc0,-1},{ -1} }, { { 0xc1,-1},{ -1} }, { { 0xc2,-1},{ -1} }, { { 0xc3,-1},{ -1} }, /*0c0*/ - { { 0xc4,-1},{ -1} }, { { 0xc5,-1},{ -1} }, { { 0xc6,-1},{ -1} }, { { 0xc7,-1},{ -1} }, /*0c4*/ - { { 0xc8,-1},{ -1} }, { { 0xc9,-1},{ -1} }, { { 0xca,-1},{ -1} }, { { 0xcb,-1},{ -1} }, /*0c8*/ - { { 0xcc,-1},{ -1} }, { { 0xcd,-1},{ -1} }, { { 0xce,-1},{ -1} }, { { 0xcf,-1},{ -1} }, /*0cc*/ - { { 0xd0,-1},{ -1} }, { { 0xd1,-1},{ -1} }, { { 0xd2,-1},{ -1} }, { { 0xd3,-1},{ -1} }, /*0d0*/ - { { 0xd4,-1},{ -1} }, { { 0xd5,-1},{ -1} }, { { 0xd6,-1},{ -1} }, { { 0xd7,-1},{ -1} }, /*0d4*/ - { { 0xd8,-1},{ -1} }, { { 0xd9,-1},{ -1} }, { { 0xda,-1},{ -1} }, { { 0xdb,-1},{ -1} }, /*0d8*/ - { { 0xdc,-1},{ -1} }, { { 0xdd,-1},{ -1} }, { { 0xde,-1},{ -1} }, { { 0xdf,-1},{ -1} }, /*0dc*/ - { { 0xe0,-1},{ -1} }, { { 0xe1,-1},{ -1} }, { { 0xe2,-1},{ -1} }, { { 0xe3,-1},{ -1} }, /*0e0*/ - { { 0xe4,-1},{ -1} }, { { 0xe5,-1},{ -1} }, { { 0xe6,-1},{ -1} }, { { 0xe7,-1},{ -1} }, /*0e4*/ - { { 0xe8,-1},{ -1} }, { { 0xe9,-1},{ -1} }, { { 0xea,-1},{ -1} }, { { 0xeb,-1},{ -1} }, /*0e8*/ - { { 0xec,-1},{ -1} }, { { 0xed,-1},{ -1} }, { { 0xee,-1},{ -1} }, { { 0xef,-1},{ -1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ -1} }, { { 0xf2,-1},{ -1} }, { { 0xf3,-1},{ -1} }, /*0f0*/ - { { 0xf4,-1},{ -1} }, { { 0xf5,-1},{ -1} }, { { 0xf6,-1},{ -1} }, { { 0xf7,-1},{ -1} }, /*0f4*/ - { { 0xf8,-1},{ -1} }, { { 0xf9,-1},{ -1} }, { { 0xfa,-1},{ -1} }, { { 0xfb,-1},{ -1} }, /*0f8*/ - { { 0xfc,-1},{ -1} }, { { 0xfd,-1},{ -1} }, { { 0xfe,-1},{ -1} }, { { 0xff,-1},{ -1} }, /*0fc*/ - - { {0xe1,0x1d,-1},{0xe1, 0x9d,-1} }, { {0xe0,0x01,-1},{0xe0, 0x81,-1} }, { {0xe0,0x02,-1},{0xe0, 0x82,-1} }, { {0xe0,0x03,-1},{0xe0, 0x83,-1} }, /*100*/ - { {0xe0,0x04,-1},{0xe0, 0x84,-1} }, { {0xe0,0x05,-1},{0xe0, 0x85,-1} }, { {0xe0,0x06,-1},{0xe0, 0x86,-1} }, { {0xe0,0x07,-1},{0xe0, 0x87,-1} }, /*104*/ - { {0xe0,0x08,-1},{0xe0, 0x88,-1} }, { {0xe0,0x09,-1},{0xe0, 0x89,-1} }, { {0xe0,0x0a,-1},{0xe0, 0x8a,-1} }, { {0xe0,0x0b,-1},{0xe0, 0x8b,-1} }, /*108*/ - { {0xe0,0x0c,-1},{0xe0, 0x8c,-1} }, { { -1},{ -1} }, { {0xe0,0x0e,-1},{0xe0, 0x8e,-1} }, { {0xe0,0x0f,-1},{0xe0, 0x8f,-1} }, /*10c*/ - { {0xe0,0x10,-1},{0xe0, 0x90,-1} }, { {0xe0,0x11,-1},{0xe0, 0x91,-1} }, { {0xe0,0x12,-1},{0xe0, 0x92,-1} }, { {0xe0,0x13,-1},{0xe0, 0x93,-1} }, /*110*/ - { {0xe0,0x14,-1},{0xe0, 0x94,-1} }, { {0xe0,0x15,-1},{0xe0, 0x95,-1} }, { {0xe0,0x16,-1},{0xe0, 0x96,-1} }, { {0xe0,0x17,-1},{0xe0, 0x97,-1} }, /*114*/ - { {0xe0,0x18,-1},{0xe0, 0x98,-1} }, { {0xe0,0x19,-1},{0xe0, 0x99,-1} }, { {0xe0,0x1a,-1},{0xe0, 0x9a,-1} }, { {0xe0,0x1b,-1},{0xe0, 0x9b,-1} }, /*118*/ - { {0xe0,0x1c,-1},{0xe0, 0x9c,-1} }, { {0xe0,0x1d,-1},{0xe0, 0x9d,-1} }, { {0xe0,0x1e,-1},{0xe0, 0x9e,-1} }, { {0xe0,0x1f,-1},{0xe0, 0x9f,-1} }, /*11c*/ - { {0xe0,0x20,-1},{0xe0, 0xa0,-1} }, { {0xe0,0x21,-1},{0xe0, 0xa1,-1} }, { {0xe0,0x22,-1},{0xe0, 0xa2,-1} }, { {0xe0,0x23,-1},{0xe0, 0xa3,-1} }, /*120*/ - { {0xe0,0x24,-1},{0xe0, 0xa4,-1} }, { {0xe0,0x25,-1},{0xe0, 0xa5,-1} }, { {0xe0,0x26,-1},{0xe0, 0xa6,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x2c,-1},{0xe0, 0xac,-1} }, { {0xe0,0x2d,-1},{0xe0, 0xad,-1} }, { {0xe0,0x2e,-1},{0xe0, 0xae,-1} }, { {0xe0,0x2f,-1},{0xe0, 0xaf,-1} }, /*12c*/ - { {0xe0,0x30,-1},{0xe0, 0xb0,-1} }, { {0xe0,0x31,-1},{0xe0, 0xb1,-1} }, { {0xe0,0x32,-1},{0xe0, 0xb2,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x34,-1},{0xe0, 0xb4,-1} }, { {0xe0,0x35,-1},{0xe0, 0xb5,-1} }, { { -1},{ -1} }, { {0xe0,0x37,-1},{0xe0, 0xb7,-1} }, /*134*/ - { {0xe0,0x38,-1},{0xe0, 0xb8,-1} }, { { -1},{ -1} }, { {0xe0,0x3a,-1},{0xe0, 0xba,-1} }, { {0xe0,0x3b,-1},{0xe0, 0xbb,-1} }, /*138*/ - { {0xe0,0x3c,-1},{0xe0, 0xbc,-1} }, { {0xe0,0x3d,-1},{0xe0, 0xbd,-1} }, { {0xe0,0x3e,-1},{0xe0, 0xbe,-1} }, { {0xe0,0x3f,-1},{0xe0, 0xbf,-1} }, /*13c*/ - { {0xe0,0x40,-1},{0xe0, 0xc0,-1} }, { {0xe0,0x41,-1},{0xe0, 0xc1,-1} }, { {0xe0,0x42,-1},{0xe0, 0xc2,-1} }, { {0xe0,0x43,-1},{0xe0, 0xc3,-1} }, /*140*/ - { {0xe0,0x44,-1},{0xe0, 0xc4,-1} }, { { -1},{ -1} }, { {0xe0,0x46,-1},{0xe0, 0xc6,-1} }, { {0xe0,0x47,-1},{0xe0, 0xc7,-1} }, /*144*/ - { {0xe0,0x48,-1},{0xe0, 0xc8,-1} }, { {0xe0,0x49,-1},{0xe0, 0xc9,-1} }, { { -1},{ -1} }, { {0xe0,0x4b,-1},{0xe0, 0xcb,-1} }, /*148*/ - { {0xe0,0x4c,-1},{0xe0, 0xcc,-1} }, { {0xe0,0x4d,-1},{0xe0, 0xcd,-1} }, { {0xe0,0x4e,-1},{0xe0, 0xce,-1} }, { {0xe0,0x4f,-1},{0xe0, 0xcf,-1} }, /*14c*/ - { {0xe0,0x50,-1},{0xe0, 0xd0,-1} }, { {0xe0,0x51,-1},{0xe0, 0xd1,-1} }, { {0xe0,0x52,-1},{0xe0, 0xd2,-1} }, { {0xe0,0x53,-1},{0xe0, 0xd3,-1} }, /*150*/ - { { -1},{ -1} }, { {0xe0,0x55,-1},{0xe0, 0xd5,-1} }, { { -1},{ -1} }, { {0xe0,0x57,-1},{0xe0, 0xd7,-1} }, /*154*/ - { {0xe0,0x58,-1},{0xe0, 0xd8,-1} }, { {0xe0,0x59,-1},{0xe0, 0xd9,-1} }, { {0xe0,0x5a,-1},{0xe0, 0xaa,-1} }, { {0xe0,0x5b,-1},{0xe0, 0xdb,-1} }, /*158*/ - { {0xe0,0x5c,-1},{0xe0, 0xdc,-1} }, { {0xe0,0x5d,-1},{0xe0, 0xdd,-1} }, { {0xe0,0x5e,-1},{0xe0, 0xee,-1} }, { {0xe0,0x5f,-1},{0xe0, 0xdf,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x61,-1},{0xe0, 0xe1,-1} }, { {0xe0,0x62,-1},{0xe0, 0xe2,-1} }, { {0xe0,0x63,-1},{0xe0, 0xe3,-1} }, /*160*/ - { {0xe0,0x64,-1},{0xe0, 0xe4,-1} }, { {0xe0,0x65,-1},{0xe0, 0xe5,-1} }, { {0xe0,0x66,-1},{0xe0, 0xe6,-1} }, { {0xe0,0x67,-1},{0xe0, 0xe7,-1} }, /*164*/ - { {0xe0,0x68,-1},{0xe0, 0xe8,-1} }, { {0xe0,0x69,-1},{0xe0, 0xe9,-1} }, { {0xe0,0x6a,-1},{0xe0, 0xea,-1} }, { {0xe0,0x6b,-1},{0xe0, 0xeb,-1} }, /*168*/ - { {0xe0,0x6c,-1},{0xe0, 0xec,-1} }, { {0xe0,0x6d,-1},{0xe0, 0xed,-1} }, { {0xe0,0x6e,-1},{0xe0, 0xee,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x70,-1},{0xe0, 0xf0,-1} }, { {0xe0,0x71,-1},{0xe0, 0xf1,-1} }, { {0xe0,0x72,-1},{0xe0, 0xf2,-1} }, { {0xe0,0x73,-1},{0xe0, 0xf3,-1} }, /*170*/ - { {0xe0,0x74,-1},{0xe0, 0xf4,-1} }, { {0xe0,0x75,-1},{0xe0, 0xf5,-1} }, { { -1},{ -1} }, { {0xe0,0x77,-1},{0xe0, 0xf7,-1} }, /*174*/ - { {0xe0,0x78,-1},{0xe0, 0xf8,-1} }, { {0xe0,0x79,-1},{0xe0, 0xf9,-1} }, { {0xe0,0x7a,-1},{0xe0, 0xfa,-1} }, { {0xe0,0x7b,-1},{0xe0, 0xfb,-1} }, /*178*/ - { {0xe0,0x7c,-1},{0xe0, 0xfc,-1} }, { {0xe0,0x7d,-1},{0xe0, 0xfd,-1} }, { {0xe0,0x7e,-1},{0xe0, 0xfe,-1} }, { {0xe0,0x7f,-1},{0xe0, 0xff,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{ -1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{ -1} }, { {0xe0,0xff,-1},{ -1} } /*1fc*/ -}; - -static const scancode scancode_set2[512] = { - { { -1},{ -1} }, { { 0x76,-1},{ 0xF0,0x76,-1} }, { { 0x16,-1},{ 0xF0,0x16,-1} }, { { 0x1E,-1},{ 0xF0,0x1E,-1} }, /*000*/ - { { 0x26,-1},{ 0xF0,0x26,-1} }, { { 0x25,-1},{ 0xF0,0x25,-1} }, { { 0x2E,-1},{ 0xF0,0x2E,-1} }, { { 0x36,-1},{ 0xF0,0x36,-1} }, /*004*/ - { { 0x3D,-1},{ 0xF0,0x3D,-1} }, { { 0x3E,-1},{ 0xF0,0x3E,-1} }, { { 0x46,-1},{ 0xF0,0x46,-1} }, { { 0x45,-1},{ 0xF0,0x45,-1} }, /*008*/ - { { 0x4E,-1},{ 0xF0,0x4E,-1} }, { { 0x55,-1},{ 0xF0,0x55,-1} }, { { 0x66,-1},{ 0xF0,0x66,-1} }, { { 0x0D,-1},{ 0xF0,0x0D,-1} }, /*00c*/ - { { 0x15,-1},{ 0xF0,0x15,-1} }, { { 0x1D,-1},{ 0xF0,0x1D,-1} }, { { 0x24,-1},{ 0xF0,0x24,-1} }, { { 0x2D,-1},{ 0xF0,0x2D,-1} }, /*010*/ - { { 0x2C,-1},{ 0xF0,0x2C,-1} }, { { 0x35,-1},{ 0xF0,0x35,-1} }, { { 0x3C,-1},{ 0xF0,0x3C,-1} }, { { 0x43,-1},{ 0xF0,0x43,-1} }, /*014*/ - { { 0x44,-1},{ 0xF0,0x44,-1} }, { { 0x4D,-1},{ 0xF0,0x4D,-1} }, { { 0x54,-1},{ 0xF0,0x54,-1} }, { { 0x5B,-1},{ 0xF0,0x5B,-1} }, /*018*/ - { { 0x5A,-1},{ 0xF0,0x5A,-1} }, { { 0x14,-1},{ 0xF0,0x14,-1} }, { { 0x1C,-1},{ 0xF0,0x1C,-1} }, { { 0x1B,-1},{ 0xF0,0x1B,-1} }, /*01c*/ - { { 0x23,-1},{ 0xF0,0x23,-1} }, { { 0x2B,-1},{ 0xF0,0x2B,-1} }, { { 0x34,-1},{ 0xF0,0x34,-1} }, { { 0x33,-1},{ 0xF0,0x33,-1} }, /*020*/ - { { 0x3B,-1},{ 0xF0,0x3B,-1} }, { { 0x42,-1},{ 0xF0,0x42,-1} }, { { 0x4B,-1},{ 0xF0,0x4B,-1} }, { { 0x4C,-1},{ 0xF0,0x4C,-1} }, /*024*/ - { { 0x52,-1},{ 0xF0,0x52,-1} }, { { 0x0E,-1},{ 0xF0,0x0E,-1} }, { { 0x12,-1},{ 0xF0,0x12,-1} }, { { 0x5D,-1},{ 0xF0,0x5D,-1} }, /*028*/ - { { 0x1A,-1},{ 0xF0,0x1A,-1} }, { { 0x22,-1},{ 0xF0,0x22,-1} }, { { 0x21,-1},{ 0xF0,0x21,-1} }, { { 0x2A,-1},{ 0xF0,0x2A,-1} }, /*02c*/ - { { 0x32,-1},{ 0xF0,0x32,-1} }, { { 0x31,-1},{ 0xF0,0x31,-1} }, { { 0x3A,-1},{ 0xF0,0x3A,-1} }, { { 0x41,-1},{ 0xF0,0x41,-1} }, /*030*/ - { { 0x49,-1},{ 0xF0,0x49,-1} }, { { 0x4A,-1},{ 0xF0,0x4A,-1} }, { { 0x59,-1},{ 0xF0,0x59,-1} }, { { 0x7C,-1},{ 0xF0,0x7C,-1} }, /*034*/ - { { 0x11,-1},{ 0xF0,0x11,-1} }, { { 0x29,-1},{ 0xF0,0x29,-1} }, { { 0x58,-1},{ 0xF0,0x58,-1} }, { { 0x05,-1},{ 0xF0,0x05,-1} }, /*038*/ - { { 0x06,-1},{ 0xF0,0x06,-1} }, { { 0x04,-1},{ 0xF0,0x04,-1} }, { { 0x0C,-1},{ 0xF0,0x0C,-1} }, { { 0x03,-1},{ 0xF0,0x03,-1} }, /*03c*/ - { { 0x0B,-1},{ 0xF0,0x0B,-1} }, { { 0x83,-1},{ 0xF0,0x83,-1} }, { { 0x0A,-1},{ 0xF0,0x0A,-1} }, { { 0x01,-1},{ 0xF0,0x01,-1} }, /*040*/ - { { 0x09,-1},{ 0xF0,0x09,-1} }, { { 0x77,-1},{ 0xF0,0x77,-1} }, { { 0x7E,-1},{ 0xF0,0x7E,-1} }, { { 0x6C,-1},{ 0xF0,0x6C,-1} }, /*044*/ - { { 0x75,-1},{ 0xF0,0x75,-1} }, { { 0x7D,-1},{ 0xF0,0x7D,-1} }, { { 0x7B,-1},{ 0xF0,0x7B,-1} }, { { 0x6B,-1},{ 0xF0,0x6B,-1} }, /*048*/ - { { 0x73,-1},{ 0xF0,0x73,-1} }, { { 0x74,-1},{ 0xF0,0x74,-1} }, { { 0x79,-1},{ 0xF0,0x79,-1} }, { { 0x69,-1},{ 0xF0,0x69,-1} }, /*04c*/ - { { 0x72,-1},{ 0xF0,0x72,-1} }, { { 0x7A,-1},{ 0xF0,0x7A,-1} }, { { 0x70,-1},{ 0xF0,0x70,-1} }, { { 0x71,-1},{ 0xF0,0x71,-1} }, /*050*/ - { { 0x84,-1},{ 0xF0,0x84,-1} }, { { 0x60,-1},{ 0xF0,0x60,-1} }, { { 0x61,-1},{ 0xF0,0x61,-1} }, { { 0x78,-1},{ 0xF0,0x78,-1} }, /*054*/ - { { 0x07,-1},{ 0xF0,0x07,-1} }, { { 0x0F,-1},{ 0xF0,0x0F,-1} }, { { 0x17,-1},{ 0xF0,0x17,-1} }, { { 0x1F,-1},{ 0xF0,0x1F,-1} }, /*058*/ - { { 0x27,-1},{ 0xF0,0x27,-1} }, { { 0x2F,-1},{ 0xF0,0x2F,-1} }, { { 0x37,-1},{ 0xF0,0x37,-1} }, { { 0x3F,-1},{ 0xF0,0x3F,-1} }, /*05c*/ - { { 0x47,-1},{ 0xF0,0x47,-1} }, { { 0x4F,-1},{ 0xF0,0x4F,-1} }, { { 0x56,-1},{ 0xF0,0x56,-1} }, { { 0x5E,-1},{ 0xF0,0x5E,-1} }, /*060*/ - { { 0x08,-1},{ 0xF0,0x08,-1} }, { { 0x10,-1},{ 0xF0,0x10,-1} }, { { 0x18,-1},{ 0xF0,0x18,-1} }, { { 0x20,-1},{ 0xF0,0x20,-1} }, /*064*/ - { { 0x28,-1},{ 0xF0,0x28,-1} }, { { 0x30,-1},{ 0xF0,0x30,-1} }, { { 0x38,-1},{ 0xF0,0x38,-1} }, { { 0x40,-1},{ 0xF0,0x40,-1} }, /*068*/ - { { 0x48,-1},{ 0xF0,0x48,-1} }, { { 0x50,-1},{ 0xF0,0x50,-1} }, { { 0x57,-1},{ 0xF0,0x57,-1} }, { { 0x6F,-1},{ 0xF0,0x6F,-1} }, /*06c*/ - { { 0x13,-1},{ 0xF0,0x13,-1} }, { { 0x19,-1},{ 0xF0,0x19,-1} }, { { 0x39,-1},{ 0xF0,0x39,-1} }, { { 0x51,-1},{ 0xF0,0x51,-1} }, /*070*/ - { { 0x53,-1},{ 0xF0,0x53,-1} }, { { 0x5C,-1},{ 0xF0,0x5C,-1} }, { { 0x5F,-1},{ 0xF0,0x5F,-1} }, { { 0x62,-1},{ 0xF0,0x62,-1} }, /*074*/ - { { 0x63,-1},{ 0xF0,0x63,-1} }, { { 0x64,-1},{ 0xF0,0x64,-1} }, { { 0x65,-1},{ 0xF0,0x65,-1} }, { { 0x67,-1},{ 0xF0,0x67,-1} }, /*078*/ - { { 0x68,-1},{ 0xF0,0x68,-1} }, { { 0x6A,-1},{ 0xF0,0x6A,-1} }, { { 0x6D,-1},{ 0xF0,0x6D,-1} }, { { 0x6E,-1},{ 0xF0,0x6E,-1} }, /*07c*/ - - { { 0x80,-1},{ 0xf0,0x80,-1} }, { { 0x81,-1},{ 0xf0,0x81,-1} }, { { 0x82,-1},{ 0xf0,0x82,-1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x54,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { 0x87,-1},{ 0xf0,0x87,-1} }, /*084*/ - { { 0x88,-1},{ 0xf0,0x88,-1} }, { { 0x89,-1},{ 0xf0,0x89,-1} }, { { 0x8a,-1},{ 0xf0,0x8a,-1} }, { { 0x8b,-1},{ 0xf0,0x8b,-1} }, /*088*/ - { { 0x8c,-1},{ 0xf0,0x8c,-1} }, { { 0x8d,-1},{ 0xf0,0x8d,-1} }, { { 0x8e,-1},{ 0xf0,0x8e,-1} }, { { 0x8f,-1},{ 0xf0,0x8f,-1} }, /*08c*/ - { { 0x90,-1},{ 0xf0,0x90,-1} }, { { 0x91,-1},{ 0xf0,0x91,-1} }, { { 0x92,-1},{ 0xf0,0x92,-1} }, { { 0x93,-1},{ 0xf0,0x93,-1} }, /*090*/ - { { 0x94,-1},{ 0xf0,0x94,-1} }, { { 0x95,-1},{ 0xf0,0x95,-1} }, { { 0x96,-1},{ 0xf0,0x96,-1} }, { { 0x97,-1},{ 0xf0,0x97,-1} }, /*094*/ - { { 0x98,-1},{ 0xf0,0x98,-1} }, { { 0x99,-1},{ 0xf0,0x99,-1} }, { { 0x9a,-1},{ 0xf0,0x9a,-1} }, { { 0x9b,-1},{ 0xf0,0x9b,-1} }, /*098*/ - { { 0x9c,-1},{ 0xf0,0x9c,-1} }, { { 0x9d,-1},{ 0xf0,0x9d,-1} }, { { 0x9e,-1},{ 0xf0,0x9e,-1} }, { { 0x9f,-1},{ 0xf0,0x9f,-1} }, /*09c*/ - { { 0xa0,-1},{ 0xf0,0xa0,-1} }, { { 0xa1,-1},{ 0xf0,0xa1,-1} }, { { 0xa2,-1},{ 0xf0,0xa2,-1} }, { { 0xa3,-1},{ 0xf0,0xa3,-1} }, /*0a0*/ - { { 0xa4,-1},{ 0xf0,0xa4,-1} }, { { 0xa5,-1},{ 0xf0,0xa5,-1} }, { { 0xa6,-1},{ 0xf0,0xa6,-1} }, { { 0xa7,-1},{ 0xf0,0xa7,-1} }, /*0a4*/ - { { 0xa8,-1},{ 0xf0,0xa8,-1} }, { { 0xa9,-1},{ 0xf0,0xa9,-1} }, { { 0xaa,-1},{ 0xf0,0xaa,-1} }, { { 0xab,-1},{ 0xf0,0xab,-1} }, /*0a8*/ - { { 0xac,-1},{ 0xf0,0xac,-1} }, { { 0xad,-1},{ 0xf0,0xad,-1} }, { { 0xae,-1},{ 0xf0,0xae,-1} }, { { 0xaf,-1},{ 0xf0,0xaf,-1} }, /*0ac*/ - { { 0xb0,-1},{ 0xf0,0xb0,-1} }, { { 0xb1,-1},{ 0xf0,0xb1,-1} }, { { 0xb2,-1},{ 0xf0,0xb2,-1} }, { { 0xb3,-1},{ 0xf0,0xb3,-1} }, /*0b0*/ - { { 0xb4,-1},{ 0xf0,0xb4,-1} }, { { 0xb5,-1},{ 0xf0,0xb5,-1} }, { { 0xb6,-1},{ 0xf0,0xb6,-1} }, { { 0xb7,-1},{ 0xf0,0xb7,-1} }, /*0b4*/ - { { 0xb8,-1},{ 0xf0,0xb8,-1} }, { { 0xb9,-1},{ 0xf0,0xb9,-1} }, { { 0xba,-1},{ 0xf0,0xba,-1} }, { { 0xbb,-1},{ 0xf0,0xbb,-1} }, /*0b8*/ - { { 0xbc,-1},{ 0xf0,0xbc,-1} }, { { 0xbd,-1},{ 0xf0,0xbd,-1} }, { { 0xbe,-1},{ 0xf0,0xbe,-1} }, { { 0xbf,-1},{ 0xf0,0xbf,-1} }, /*0bc*/ - { { 0xc0,-1},{ 0xf0,0xc0,-1} }, { { 0xc1,-1},{ 0xf0,0xc1,-1} }, { { 0xc2,-1},{ 0xf0,0xc2,-1} }, { { 0xc3,-1},{ 0xf0,0xc3,-1} }, /*0c0*/ - { { 0xc4,-1},{ 0xf0,0xc4,-1} }, { { 0xc5,-1},{ 0xf0,0xc5,-1} }, { { 0xc6,-1},{ 0xf0,0xc6,-1} }, { { 0xc7,-1},{ 0xf0,0xc7,-1} }, /*0c4*/ - { { 0xc8,-1},{ 0xf0,0xc8,-1} }, { { 0xc9,-1},{ 0xf0,0xc9,-1} }, { { 0xca,-1},{ 0xf0,0xca,-1} }, { { 0xcb,-1},{ 0xf0,0xcb,-1} }, /*0c8*/ - { { 0xcc,-1},{ 0xf0,0xcc,-1} }, { { 0xcd,-1},{ 0xf0,0xcd,-1} }, { { 0xce,-1},{ 0xf0,0xce,-1} }, { { 0xcf,-1},{ 0xf0,0xcf,-1} }, /*0cc*/ - { { 0xd0,-1},{ 0xf0,0xd0,-1} }, { { 0xd1,-1},{ 0xf0,0xd0,-1} }, { { 0xd2,-1},{ 0xf0,0xd2,-1} }, { { 0xd3,-1},{ 0xf0,0xd3,-1} }, /*0d0*/ - { { 0xd4,-1},{ 0xf0,0xd4,-1} }, { { 0xd5,-1},{ 0xf0,0xd5,-1} }, { { 0xd6,-1},{ 0xf0,0xd6,-1} }, { { 0xd7,-1},{ 0xf0,0xd7,-1} }, /*0d4*/ - { { 0xd8,-1},{ 0xf0,0xd8,-1} }, { { 0xd9,-1},{ 0xf0,0xd9,-1} }, { { 0xda,-1},{ 0xf0,0xda,-1} }, { { 0xdb,-1},{ 0xf0,0xdb,-1} }, /*0d8*/ - { { 0xdc,-1},{ 0xf0,0xdc,-1} }, { { 0xdd,-1},{ 0xf0,0xdd,-1} }, { { 0xde,-1},{ 0xf0,0xde,-1} }, { { 0xdf,-1},{ 0xf0,0xdf,-1} }, /*0dc*/ - { { 0xe0,-1},{ 0xf0,0xe0,-1} }, { { 0xe1,-1},{ 0xf0,0xe1,-1} }, { { 0xe2,-1},{ 0xf0,0xe2,-1} }, { { 0xe3,-1},{ 0xf0,0xe3,-1} }, /*0e0*/ - { { 0xe4,-1},{ 0xf0,0xe4,-1} }, { { 0xe5,-1},{ 0xf0,0xe5,-1} }, { { 0xe6,-1},{ 0xf0,0xe6,-1} }, { { 0xe7,-1},{ 0xf0,0xe7,-1} }, /*0e4*/ - { { 0xe8,-1},{ 0xf0,0xe8,-1} }, { { 0xe9,-1},{ 0xf0,0xe9,-1} }, { { 0xea,-1},{ 0xf0,0xea,-1} }, { { 0xeb,-1},{ 0xf0,0xeb,-1} }, /*0e8*/ - { { 0xec,-1},{ 0xf0,0xec,-1} }, { { 0xed,-1},{ 0xf0,0xed,-1} }, { { 0xee,-1},{ 0xf0,0xee,-1} }, { { 0xef,-1},{ 0xf0,0xef,-1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ 0xf0,0xf1,-1} }, { { 0xf2,-1},{ 0xf0,0xf2,-1} }, { { 0xf3,-1},{ 0xf0,0xf3,-1} }, /*0f0*/ - { { 0xf4,-1},{ 0xf0,0xf4,-1} }, { { 0xf5,-1},{ 0xf0,0xf5,-1} }, { { 0xf6,-1},{ 0xf0,0xf6,-1} }, { { 0xf7,-1},{ 0xf0,0xf7,-1} }, /*0f4*/ - { { 0xf8,-1},{ 0xf0,0xf8,-1} }, { { 0xf9,-1},{ 0xf0,0xf9,-1} }, { { 0xfa,-1},{ 0xf0,0xfa,-1} }, { { 0xfb,-1},{ 0xf0,0xfb,-1} }, /*0f8*/ - { { 0xfc,-1},{ 0xf0,0xfc,-1} }, { { 0xfd,-1},{ 0xf0,0xfd,-1} }, { { 0xfe,-1},{ 0xf0,0xfe,-1} }, { { 0xff,-1},{ 0xf0,0xff,-1} }, /*0fc*/ - - { {0xe1,0x14,-1},{0xe1,0xf0,0x14,-1} }, { {0xe0,0x76,-1},{0xe0,0xF0,0x76,-1} }, { {0xe0,0x16,-1},{0xe0,0xF0,0x16,-1} }, { {0xe0,0x1E,-1},{0xe0,0xF0,0x1E,-1} }, /*100*/ - { {0xe0,0x26,-1},{0xe0,0xF0,0x26,-1} }, { {0xe0,0x25,-1},{0xe0,0xF0,0x25,-1} }, { {0xe0,0x2E,-1},{0xe0,0xF0,0x2E,-1} }, { {0xe0,0x36,-1},{0xe0,0xF0,0x36,-1} }, /*104*/ - { {0xe0,0x3D,-1},{0xe0,0xF0,0x3D,-1} }, { {0xe0,0x3E,-1},{0xe0,0xF0,0x3E,-1} }, { {0xe0,0x46,-1},{0xe0,0xF0,0x46,-1} }, { {0xe0,0x45,-1},{0xe0,0xF0,0x45,-1} }, /*108*/ - { {0xe0,0x4E,-1},{0xe0,0xF0,0x4E,-1} }, { { -1},{ -1} }, { {0xe0,0x66,-1},{0xe0,0xF0,0x66,-1} }, { {0xe0,0x0D,-1},{0xe0,0xF0,0x0D,-1} }, /*10c*/ - { {0xe0,0x15,-1},{0xe0,0xF0,0x15,-1} }, { {0xe0,0x1D,-1},{0xe0,0xF0,0x1D,-1} }, { {0xe0,0x24,-1},{0xe0,0xF0,0x24,-1} }, { {0xe0,0x2D,-1},{0xe0,0xF0,0x2D,-1} }, /*110*/ - { {0xe0,0x2C,-1},{0xe0,0xF0,0x2C,-1} }, { {0xe0,0x35,-1},{0xe0,0xF0,0x35,-1} }, { {0xe0,0x3C,-1},{0xe0,0xF0,0x3C,-1} }, { {0xe0,0x43,-1},{0xe0,0xF0,0x43,-1} }, /*114*/ - { {0xe0,0x44,-1},{0xe0,0xF0,0x44,-1} }, { {0xe0,0x4D,-1},{0xe0,0xF0,0x4D,-1} }, { {0xe0,0x54,-1},{0xe0,0xF0,0x54,-1} }, { {0xe0,0x5B,-1},{0xe0,0xF0,0x5B,-1} }, /*118*/ - { {0xe0,0x5A,-1},{0xe0,0xF0,0x5A,-1} }, { {0xe0,0x14,-1},{0xe0,0xF0,0x14,-1} }, { {0xe0,0x1C,-1},{0xe0,0xF0,0x1C,-1} }, { {0xe0,0x1B,-1},{0xe0,0xF0,0x1B,-1} }, /*11c*/ - { {0xe0,0x23,-1},{0xe0,0xF0,0x23,-1} }, { {0xe0,0x2B,-1},{0xe0,0xF0,0x2B,-1} }, { {0xe0,0x34,-1},{0xe0,0xF0,0x34,-1} }, { {0xe0,0x33,-1},{0xe0,0xF0,0x33,-1} }, /*120*/ - { {0xe0,0x3B,-1},{0xe0,0xF0,0x3B,-1} }, { {0xe0,0x42,-1},{0xe0,0xF0,0x42,-1} }, { {0xe0,0x4B,-1},{0xe0,0xF0,0x4B,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x1A,-1},{0xe0,0xF0,0x1A,-1} }, { {0xe0,0x22,-1},{0xe0,0xF0,0x22,-1} }, { {0xe0,0x21,-1},{0xe0,0xF0,0x21,-1} }, { {0xe0,0x2A,-1},{0xe0,0xF0,0x2A,-1} }, /*12c*/ - { {0xe0,0x32,-1},{0xe0,0xF0,0x32,-1} }, { {0xe0,0x31,-1},{0xe0,0xF0,0x31,-1} }, { {0xe0,0x3A,-1},{0xe0,0xF0,0x3A,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x49,-1},{0xe0,0xF0,0x49,-1} }, { {0xe0,0x4A,-1},{0xe0,0xF0,0x4A,-1} }, { { -1},{ -1} }, { {0xe0,0x7C,-1},{0xe0,0xF0,0x7C,-1} }, /*134*/ - { {0xe0,0x11,-1},{0xe0,0xF0,0x11,-1} }, { { -1},{ -1} }, { {0xe0,0x58,-1},{0xe0,0xF0,0x58,-1} }, { {0xe0,0x05,-1},{0xe0,0xF0,0x05,-1} }, /*138*/ - { {0xe0,0x06,-1},{0xe0,0xF0,0x06,-1} }, { {0xe0,0x04,-1},{0xe0,0xF0,0x04,-1} }, { {0xe0,0x0C,-1},{0xe0,0xF0,0x0C,-1} }, { {0xe0,0x03,-1},{0xe0,0xF0,0x03,-1} }, /*13c*/ - { {0xe0,0x0B,-1},{0xe0,0xF0,0x0B,-1} }, { {0xe0,0x02,-1},{0xe0,0xF0,0x02,-1} }, { {0xe0,0x0A,-1},{0xe0,0xF0,0x0A,-1} }, { {0xe0,0x01,-1},{0xe0,0xF0,0x01,-1} }, /*140*/ - { {0xe0,0x09,-1},{0xe0,0xF0,0x09,-1} }, { { -1},{ -1} }, { {0xe0,0x7E,-1},{0xe0,0xF0,0x7E,-1} }, { {0xe0,0x6C,-1},{0xe0,0xF0,0x6C,-1} }, /*144*/ - { {0xe0,0x75,-1},{0xe0,0xF0,0x75,-1} }, { {0xe0,0x7D,-1},{0xe0,0xF0,0x7D,-1} }, { { -1},{ -1} }, { {0xe0,0x6B,-1},{0xe0,0xF0,0x6B,-1} }, /*148*/ - { {0xe0,0x73,-1},{0xe0,0xF0,0x73,-1} }, { {0xe0,0x74,-1},{0xe0,0xF0,0x74,-1} }, { {0xe0,0x79,-1},{0xe0,0xF0,0x79,-1} }, { {0xe0,0x69,-1},{0xe0,0xF0,0x69,-1} }, /*14c*/ - { {0xe0,0x72,-1},{0xe0,0xF0,0x72,-1} }, { {0xe0,0x7A,-1},{0xe0,0xF0,0x7A,-1} }, { {0xe0,0x70,-1},{0xe0,0xF0,0x70,-1} }, { {0xe0,0x71,-1},{0xe0,0xF0,0x71,-1} }, /*150*/ - { { -1},{ -1} }, { {0xe0,0x60,-1},{0xe0,0xF0,0x60,-1} }, { { -1},{ -1} }, { {0xe0,0x78,-1},{0xe0,0xF0,0x78,-1} }, /*154*/ - { {0xe0,0x07,-1},{0xe0,0xF0,0x07,-1} }, { {0xe0,0x0F,-1},{0xe0,0xF0,0x0F,-1} }, { {0xe0,0x17,-1},{0xe0,0xF0,0x17,-1} }, { {0xe0,0x1F,-1},{0xe0,0xF0,0x1F,-1} }, /*158*/ - { {0xe0,0x27,-1},{0xe0,0xF0,0x27,-1} }, { {0xe0,0x2F,-1},{0xe0,0xF0,0x2F,-1} }, { {0xe0,0x37,-1},{0xe0,0xF0,0x37,-1} }, { {0xe0,0x3F,-1},{0xe0,0xF0,0x3F,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x4F,-1},{0xe0,0xF0,0x4F,-1} }, { {0xe0,0x56,-1},{0xe0,0xF0,0x56,-1} }, { {0xe0,0x5E,-1},{0xe0,0xF0,0x5E,-1} }, /*160*/ - { {0xe0,0x08,-1},{0xe0,0xF0,0x08,-1} }, { {0xe0,0x10,-1},{0xe0,0xF0,0x10,-1} }, { {0xe0,0x18,-1},{0xe0,0xF0,0x18,-1} }, { {0xe0,0x20,-1},{0xe0,0xF0,0x20,-1} }, /*164*/ - { {0xe0,0x28,-1},{0xe0,0xF0,0x28,-1} }, { {0xe0,0x30,-1},{0xe0,0xF0,0x30,-1} }, { {0xe0,0x38,-1},{0xe0,0xF0,0x38,-1} }, { {0xe0,0x40,-1},{0xe0,0xF0,0x40,-1} }, /*168*/ - { {0xe0,0x48,-1},{0xe0,0xF0,0x48,-1} }, { {0xe0,0x50,-1},{0xe0,0xF0,0x50,-1} }, { {0xe0,0x57,-1},{0xe0,0xF0,0x57,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x13,-1},{0xe0,0xF0,0x13,-1} }, { {0xe0,0x19,-1},{0xe0,0xF0,0x19,-1} }, { {0xe0,0x39,-1},{0xe0,0xF0,0x39,-1} }, { {0xe0,0x51,-1},{0xe0,0xF0,0x51,-1} }, /*170*/ - { {0xe0,0x53,-1},{0xe0,0xF0,0x53,-1} }, { {0xe0,0x5C,-1},{0xe0,0xF0,0x5C,-1} }, { { -1},{ -1} }, { {0xe0,0x62,-1},{0xe0,0xF0,0x62,-1} }, /*174*/ - { {0xe0,0x63,-1},{0xe0,0xF0,0x63,-1} }, { {0xe0,0x64,-1},{0xe0,0xF0,0x64,-1} }, { {0xe0,0x65,-1},{0xe0,0xF0,0x65,-1} }, { {0xe0,0x67,-1},{0xe0,0xF0,0x67,-1} }, /*178*/ - { {0xe0,0x68,-1},{0xe0,0xF0,0x68,-1} }, { {0xe0,0x6A,-1},{0xe0,0xF0,0x6A,-1} }, { {0xe0,0x6D,-1},{0xe0,0xF0,0x6D,-1} }, { {0xe0,0x6E,-1},{0xe0,0xF0,0x6E,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{0xe0,0xF0,0xE1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{0xe0,0xF0,0xEE,-1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{0xe0,0xF0,0xF1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ -}; - -static const scancode scancode_set3[512] = { - { { -1},{ -1} }, { { 0x08,-1},{ 0xf0,0x08,-1} }, { { 0x16,-1},{ 0xf0,0x16,-1} }, { { 0x1E,-1},{ 0xf0,0x1E,-1} }, /*000*/ - { { 0x26,-1},{ 0xf0,0x26,-1} }, { { 0x25,-1},{ 0xf0,0x25,-1} }, { { 0x2E,-1},{ 0xf0,0x2E,-1} }, { { 0x36,-1},{ 0xf0,0x36,-1} }, /*004*/ - { { 0x3D,-1},{ 0xf0,0x3D,-1} }, { { 0x3E,-1},{ 0xf0,0x3E,-1} }, { { 0x46,-1},{ 0xf0,0x46,-1} }, { { 0x45,-1},{ 0xf0,0x45,-1} }, /*008*/ - { { 0x4E,-1},{ 0xf0,0x4E,-1} }, { { 0x55,-1},{ 0xf0,0x55,-1} }, { { 0x66,-1},{ 0xf0,0x66,-1} }, { { 0x0D,-1},{ 0xf0,0x0D,-1} }, /*00c*/ - { { 0x15,-1},{ 0xf0,0x15,-1} }, { { 0x1D,-1},{ 0xf0,0x1D,-1} }, { { 0x24,-1},{ 0xf0,0x24,-1} }, { { 0x2D,-1},{ 0xf0,0x2D,-1} }, /*010*/ - { { 0x2C,-1},{ 0xf0,0x2C,-1} }, { { 0x35,-1},{ 0xf0,0x35,-1} }, { { 0x3C,-1},{ 0xf0,0x3C,-1} }, { { 0x43,-1},{ 0xf0,0x43,-1} }, /*014*/ - { { 0x44,-1},{ 0xf0,0x44,-1} }, { { 0x4D,-1},{ 0xf0,0x4D,-1} }, { { 0x54,-1},{ 0xf0,0x54,-1} }, { { 0x5B,-1},{ 0xf0,0x5B,-1} }, /*018*/ - { { 0x5A,-1},{ 0xf0,0x5A,-1} }, { { 0x11,-1},{ 0xf0,0x11,-1} }, { { 0x1C,-1},{ 0xf0,0x1C,-1} }, { { 0x1B,-1},{ 0xf0,0x1B,-1} }, /*01c*/ - { { 0x23,-1},{ 0xf0,0x23,-1} }, { { 0x2B,-1},{ 0xf0,0x2B,-1} }, { { 0x34,-1},{ 0xf0,0x34,-1} }, { { 0x33,-1},{ 0xf0,0x33,-1} }, /*020*/ - { { 0x3B,-1},{ 0xf0,0x3B,-1} }, { { 0x42,-1},{ 0xf0,0x42,-1} }, { { 0x4B,-1},{ 0xf0,0x4B,-1} }, { { 0x4C,-1},{ 0xf0,0x4C,-1} }, /*024*/ - { { 0x52,-1},{ 0xf0,0x52,-1} }, { { 0x0E,-1},{ 0xf0,0x0E,-1} }, { { 0x12,-1},{ 0xf0,0x12,-1} }, { { 0x5C,-1},{ 0xf0,0x5C,-1} }, /*028*/ - { { 0x1A,-1},{ 0xf0,0x1A,-1} }, { { 0x22,-1},{ 0xf0,0x22,-1} }, { { 0x21,-1},{ 0xf0,0x21,-1} }, { { 0x2A,-1},{ 0xf0,0x2A,-1} }, /*02c*/ - { { 0x32,-1},{ 0xf0,0x32,-1} }, { { 0x31,-1},{ 0xf0,0x31,-1} }, { { 0x3A,-1},{ 0xf0,0x3A,-1} }, { { 0x41,-1},{ 0xf0,0x41,-1} }, /*030*/ - { { 0x49,-1},{ 0xf0,0x49,-1} }, { { 0x4A,-1},{ 0xf0,0x4A,-1} }, { { 0x59,-1},{ 0xf0,0x59,-1} }, { { 0x7E,-1},{ 0xf0,0x7E,-1} }, /*034*/ - { { 0x19,-1},{ 0xf0,0x19,-1} }, { { 0x29,-1},{ 0xf0,0x29,-1} }, { { 0x14,-1},{ 0xf0,0x14,-1} }, { { 0x07,-1},{ 0xf0,0x07,-1} }, /*038*/ - { { 0x0F,-1},{ 0xf0,0x0F,-1} }, { { 0x17,-1},{ 0xf0,0x17,-1} }, { { 0x1F,-1},{ 0xf0,0x1F,-1} }, { { 0x27,-1},{ 0xf0,0x27,-1} }, /*03c*/ - { { 0x2F,-1},{ 0xf0,0x2F,-1} }, { { 0x37,-1},{ 0xf0,0x37,-1} }, { { 0x3F,-1},{ 0xf0,0x3F,-1} }, { { 0x47,-1},{ 0xf0,0x47,-1} }, /*040*/ - { { 0x4F,-1},{ 0xf0,0x4F,-1} }, { { 0x76,-1},{ 0xf0,0x76,-1} }, { { 0x5F,-1},{ 0xf0,0x5F,-1} }, { { 0x6C,-1},{ 0xf0,0x6C,-1} }, /*044*/ - { { 0x75,-1},{ 0xf0,0x75,-1} }, { { 0x7D,-1},{ 0xf0,0x7D,-1} }, { { 0x84,-1},{ 0xf0,0x84,-1} }, { { 0x6B,-1},{ 0xf0,0x6B,-1} }, /*048*/ - { { 0x73,-1},{ 0xf0,0x73,-1} }, { { 0x74,-1},{ 0xf0,0x74,-1} }, { { 0x7C,-1},{ 0xf0,0x7C,-1} }, { { 0x69,-1},{ 0xf0,0x69,-1} }, /*04c*/ - { { 0x72,-1},{ 0xf0,0x72,-1} }, { { 0x7A,-1},{ 0xf0,0x7A,-1} }, { { 0x70,-1},{ 0xf0,0x70,-1} }, { { 0x71,-1},{ 0xf0,0x71,-1} }, /*050*/ - { { 0x57,-1},{ 0xf0,0x57,-1} }, { { 0x60,-1},{ 0xf0,0x60,-1} }, { { -1},{ -1} }, { { 0x56,-1},{ 0xf0,0x56,-1} }, /*054*/ - { { 0x5E,-1},{ 0xf0,0x5E,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*058*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*05c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*060*/ - { { -1},{ -1} }, { { 0x10,-1},{ 0xf0,0x10,-1} }, { { 0x18,-1},{ 0xf0,0x18,-1} }, { { 0x20,-1},{ 0xf0,0x20,-1} }, /*064*/ - { { 0x28,-1},{ 0xf0,0x28,-1} }, { { 0x30,-1},{ 0xf0,0x30,-1} }, { { 0x38,-1},{ 0xf0,0x38,-1} }, { { 0x40,-1},{ 0xf0,0x40,-1} }, /*068*/ - { { 0x48,-1},{ 0xf0,0x48,-1} }, { { 0x50,-1},{ 0xf0,0x50,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*06c*/ - { { 0x87,-1},{ 0xf0,0x87,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { 0x51,-1},{ 0xf0,0x51,-1} }, /*070*/ - { { 0x53,-1},{ 0xf0,0x53,-1} }, { { 0x5C,-1},{ 0xf0,0x5C,-1} }, { { -1},{ -1} }, { { 0x62,-1},{ 0xf0,0x62,-1} }, /*074*/ - { { 0x63,-1},{ 0xf0,0x63,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x85,-1} }, /*078*/ - { { 0x68,-1},{ 0xf0,0x68,-1} }, { { 0x13,-1},{ 0xf0,0x13,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*07c*/ - - { { 0x80,-1},{ 0xf0,0x80,-1} }, { { 0x81,-1},{ 0xf0,0x81,-1} }, { { 0x82,-1},{ 0xf0,0x82,-1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x54,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { 0x87,-1},{ 0xf0,0x87,-1} }, /*084*/ - { { 0x88,-1},{ 0xf0,0x88,-1} }, { { 0x89,-1},{ 0xf0,0x89,-1} }, { { 0x8a,-1},{ 0xf0,0x8a,-1} }, { { 0x8b,-1},{ 0xf0,0x8b,-1} }, /*088*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { 0x8e,-1},{ 0xf0,0x8e,-1} }, { { 0x8f,-1},{ 0xf0,0x8f,-1} }, /*08c*/ - { { 0x90,-1},{ 0xf0,0x90,-1} }, { { 0x91,-1},{ 0xf0,0x91,-1} }, { { 0x92,-1},{ 0xf0,0x92,-1} }, { { 0x93,-1},{ 0xf0,0x93,-1} }, /*090*/ - { { 0x94,-1},{ 0xf0,0x94,-1} }, { { 0x95,-1},{ 0xf0,0x95,-1} }, { { 0x96,-1},{ 0xf0,0x96,-1} }, { { 0x97,-1},{ 0xf0,0x97,-1} }, /*094*/ - { { 0x98,-1},{ 0xf0,0x98,-1} }, { { 0x99,-1},{ 0xf0,0x99,-1} }, { { 0x9a,-1},{ 0xf0,0x9a,-1} }, { { 0x9b,-1},{ 0xf0,0x9b,-1} }, /*098*/ - { { 0x9c,-1},{ 0xf0,0x9c,-1} }, { { 0x9d,-1},{ 0xf0,0x9d,-1} }, { { 0x9e,-1},{ 0xf0,0x9e,-1} }, { { 0x9f,-1},{ 0xf0,0x9f,-1} }, /*09c*/ - { { 0xa0,-1},{ 0xf0,0xa0,-1} }, { { 0xa1,-1},{ 0xf0,0xa1,-1} }, { { 0xa2,-1},{ 0xf0,0xa2,-1} }, { { 0xa3,-1},{ 0xf0,0xa3,-1} }, /*0a0*/ - { { 0xa4,-1},{ 0xf0,0xa4,-1} }, { { 0xa5,-1},{ 0xf0,0xa5,-1} }, { { 0xa6,-1},{ 0xf0,0xa6,-1} }, { { 0xa7,-1},{ 0xf0,0xa7,-1} }, /*0a4*/ - { { 0xa8,-1},{ 0xf0,0xa8,-1} }, { { 0xa9,-1},{ 0xf0,0xa9,-1} }, { { 0xaa,-1},{ 0xf0,0xaa,-1} }, { { 0xab,-1},{ 0xf0,0xab,-1} }, /*0a8*/ - { { 0xac,-1},{ 0xf0,0xac,-1} }, { { 0xad,-1},{ 0xf0,0xad,-1} }, { { 0xae,-1},{ 0xf0,0xae,-1} }, { { 0xaf,-1},{ 0xf0,0xaf,-1} }, /*0ac*/ - { { 0xb0,-1},{ 0xf0,0xb0,-1} }, { { 0xb1,-1},{ 0xf0,0xb1,-1} }, { { 0xb2,-1},{ 0xf0,0xb2,-1} }, { { 0xb3,-1},{ 0xf0,0xb3,-1} }, /*0b0*/ - { { 0xb4,-1},{ 0xf0,0xb4,-1} }, { { 0xb5,-1},{ 0xf0,0xb5,-1} }, { { 0xb6,-1},{ 0xf0,0xb6,-1} }, { { 0xb7,-1},{ 0xf0,0xb7,-1} }, /*0b4*/ - { { 0xb8,-1},{ 0xf0,0xb8,-1} }, { { 0xb9,-1},{ 0xf0,0xb9,-1} }, { { 0xba,-1},{ 0xf0,0xba,-1} }, { { 0xbb,-1},{ 0xf0,0xbb,-1} }, /*0b8*/ - { { 0xbc,-1},{ 0xf0,0xbc,-1} }, { { 0xbd,-1},{ 0xf0,0xbd,-1} }, { { 0xbe,-1},{ 0xf0,0xbe,-1} }, { { 0xbf,-1},{ 0xf0,0xbf,-1} }, /*0bc*/ - { { 0xc0,-1},{ 0xf0,0xc0,-1} }, { { 0xc1,-1},{ 0xf0,0xc1,-1} }, { { 0xc2,-1},{ 0xf0,0xc2,-1} }, { { 0xc3,-1},{ 0xf0,0xc3,-1} }, /*0c0*/ - { { 0xc4,-1},{ 0xf0,0xc4,-1} }, { { 0xc5,-1},{ 0xf0,0xc5,-1} }, { { 0xc6,-1},{ 0xf0,0xc6,-1} }, { { 0xc7,-1},{ 0xf0,0xc7,-1} }, /*0c4*/ - { { 0xc8,-1},{ 0xf0,0xc8,-1} }, { { 0xc9,-1},{ 0xf0,0xc9,-1} }, { { 0xca,-1},{ 0xf0,0xca,-1} }, { { 0xcb,-1},{ 0xf0,0xcb,-1} }, /*0c8*/ - { { 0xcc,-1},{ 0xf0,0xcc,-1} }, { { 0xcd,-1},{ 0xf0,0xcd,-1} }, { { 0xce,-1},{ 0xf0,0xce,-1} }, { { 0xcf,-1},{ 0xf0,0xcf,-1} }, /*0cc*/ - { { 0xd0,-1},{ 0xf0,0xd0,-1} }, { { 0xd1,-1},{ 0xf0,0xd0,-1} }, { { 0xd2,-1},{ 0xf0,0xd2,-1} }, { { 0xd3,-1},{ 0xf0,0xd3,-1} }, /*0d0*/ - { { 0xd4,-1},{ 0xf0,0xd4,-1} }, { { 0xd5,-1},{ 0xf0,0xd5,-1} }, { { 0xd6,-1},{ 0xf0,0xd6,-1} }, { { 0xd7,-1},{ 0xf0,0xd7,-1} }, /*0d4*/ - { { 0xd8,-1},{ 0xf0,0xd8,-1} }, { { 0xd9,-1},{ 0xf0,0xd9,-1} }, { { 0xda,-1},{ 0xf0,0xda,-1} }, { { 0xdb,-1},{ 0xf0,0xdb,-1} }, /*0d8*/ - { { 0xdc,-1},{ 0xf0,0xdc,-1} }, { { 0xdd,-1},{ 0xf0,0xdd,-1} }, { { 0xde,-1},{ 0xf0,0xde,-1} }, { { 0xdf,-1},{ 0xf0,0xdf,-1} }, /*0dc*/ - { { 0xe0,-1},{ 0xf0,0xe0,-1} }, { { 0xe1,-1},{ 0xf0,0xe1,-1} }, { { 0xe2,-1},{ 0xf0,0xe2,-1} }, { { 0xe3,-1},{ 0xf0,0xe3,-1} }, /*0e0*/ - { { 0xe4,-1},{ 0xf0,0xe4,-1} }, { { 0xe5,-1},{ 0xf0,0xe5,-1} }, { { 0xe6,-1},{ 0xf0,0xe6,-1} }, { { 0xe7,-1},{ 0xf0,0xe7,-1} }, /*0e4*/ - { { 0xe8,-1},{ 0xf0,0xe8,-1} }, { { 0xe9,-1},{ 0xf0,0xe9,-1} }, { { 0xea,-1},{ 0xf0,0xea,-1} }, { { 0xeb,-1},{ 0xf0,0xeb,-1} }, /*0e8*/ - { { 0xec,-1},{ 0xf0,0xec,-1} }, { { 0xed,-1},{ 0xf0,0xed,-1} }, { { 0xee,-1},{ 0xf0,0xee,-1} }, { { 0xef,-1},{ 0xf0,0xef,-1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ 0xf0,0xf1,-1} }, { { 0xf2,-1},{ 0xf0,0xf2,-1} }, { { 0xf3,-1},{ 0xf0,0xf3,-1} }, /*0f0*/ - { { 0xf4,-1},{ 0xf0,0xf4,-1} }, { { 0xf5,-1},{ 0xf0,0xf5,-1} }, { { 0xf6,-1},{ 0xf0,0xf6,-1} }, { { 0xf7,-1},{ 0xf0,0xf7,-1} }, /*0f4*/ - { { 0xf8,-1},{ 0xf0,0xf8,-1} }, { { 0xf9,-1},{ 0xf0,0xf9,-1} }, { { 0xfa,-1},{ 0xf0,0xfa,-1} }, { { 0xfb,-1},{ 0xf0,0xfb,-1} }, /*0f8*/ - { { 0xfc,-1},{ 0xf0,0xfc,-1} }, { { 0xfd,-1},{ 0xf0,0xfd,-1} }, { { 0xfe,-1},{ 0xf0,0xfe,-1} }, { { 0xff,-1},{ 0xf0,0xff,-1} }, /*0fc*/ - - { { 0x62,-1},{ 0xF0,0x62,-1} }, { {0xe0,0x76,-1},{0xe0,0xF0,0x76,-1} }, { {0xe0,0x16,-1},{0xe0,0xF0,0x16,-1} }, { {0xe0,0x1E,-1},{0xe0,0xF0,0x1E,-1} }, /*100*/ - { {0xe0,0x26,-1},{0xe0,0xF0,0x26,-1} }, { {0xe0,0x25,-1},{0xe0,0xF0,0x25,-1} }, { {0xe0,0x2E,-1},{0xe0,0xF0,0x2E,-1} }, { {0xe0,0x36,-1},{0xe0,0xF0,0x36,-1} }, /*104*/ - { {0xe0,0x3D,-1},{0xe0,0xF0,0x3D,-1} }, { {0xe0,0x3E,-1},{0xe0,0xF0,0x3E,-1} }, { {0xe0,0x46,-1},{0xe0,0xF0,0x46,-1} }, { {0xe0,0x45,-1},{0xe0,0xF0,0x45,-1} }, /*108*/ - { {0xe0,0x4E,-1},{0xe0,0xF0,0x4E,-1} }, { { -1},{ -1} }, { {0xe0,0x66,-1},{0xe0,0xF0,0x66,-1} }, { {0xe0,0x0D,-1},{0xe0,0xF0,0x0D,-1} }, /*10c*/ - { {0xe0,0x15,-1},{0xe0,0xF0,0x15,-1} }, { {0xe0,0x1D,-1},{0xe0,0xF0,0x1D,-1} }, { {0xe0,0x24,-1},{0xe0,0xF0,0x24,-1} }, { {0xe0,0x2D,-1},{0xe0,0xF0,0x2D,-1} }, /*110*/ - { {0xe0,0x2C,-1},{0xe0,0xF0,0x2C,-1} }, { {0xe0,0x35,-1},{0xe0,0xF0,0x35,-1} }, { {0xe0,0x3C,-1},{0xe0,0xF0,0x3C,-1} }, { {0xe0,0x43,-1},{0xe0,0xF0,0x43,-1} }, /*114*/ - { {0xe0,0x44,-1},{0xe0,0xF0,0x44,-1} }, { {0xe0,0x4D,-1},{0xe0,0xF0,0x4D,-1} }, { {0xe0,0x54,-1},{0xe0,0xF0,0x54,-1} }, { {0xe0,0x5B,-1},{0xe0,0xF0,0x5B,-1} }, /*118*/ - { { 0x79,-1},{ 0xf0,0x79,-1} }, { { 0x58,-1},{ 0xf0,0x58,-1} }, { {0xe0,0x1C,-1},{0xe0,0xF0,0x1C,-1} }, { {0xe0,0x1B,-1},{0xe0,0xF0,0x1B,-1} }, /*11c*/ - { {0xe0,0x23,-1},{0xe0,0xF0,0x23,-1} }, { {0xe0,0x2B,-1},{0xe0,0xF0,0x2B,-1} }, { {0xe0,0x34,-1},{0xe0,0xF0,0x34,-1} }, { {0xe0,0x33,-1},{0xe0,0xF0,0x33,-1} }, /*120*/ - { {0xe0,0x3B,-1},{0xe0,0xF0,0x3B,-1} }, { {0xe0,0x42,-1},{0xe0,0xF0,0x42,-1} }, { {0xe0,0x4B,-1},{0xe0,0xF0,0x4B,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x1A,-1},{0xe0,0xF0,0x1A,-1} }, { {0xe0,0x22,-1},{0xe0,0xF0,0x22,-1} }, { {0xe0,0x21,-1},{0xe0,0xF0,0x21,-1} }, { {0xe0,0x2A,-1},{0xe0,0xF0,0x2A,-1} }, /*12c*/ - { {0xe0,0x32,-1},{0xe0,0xF0,0x32,-1} }, { {0xe0,0x31,-1},{0xe0,0xF0,0x31,-1} }, { {0xe0,0x3A,-1},{0xe0,0xF0,0x3A,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x49,-1},{0xe0,0xF0,0x49,-1} }, { { 0x77,-1},{ 0xf0,0x77,-1} }, { { -1},{ -1} }, { { 0x57,-1},{ 0xf0,0x57,-1} }, /*134*/ - { { 0x39,-1},{ 0xf0,0x39,-1} }, { { -1},{ -1} }, { {0xe0,0x58,-1},{0xe0,0xF0,0x58,-1} }, { {0xe0,0x05,-1},{0xe0,0xF0,0x05,-1} }, /*138*/ - { {0xe0,0x06,-1},{0xe0,0xF0,0x06,-1} }, { {0xe0,0x04,-1},{0xe0,0xF0,0x04,-1} }, { {0xe0,0x0C,-1},{0xe0,0xF0,0x0C,-1} }, { {0xe0,0x03,-1},{0xe0,0xF0,0x03,-1} }, /*13c*/ - { {0xe0,0x0B,-1},{0xe0,0xF0,0x0B,-1} }, { {0xe0,0x02,-1},{0xe0,0xF0,0x02,-1} }, { {0xe0,0x0A,-1},{0xe0,0xF0,0x0A,-1} }, { {0xe0,0x01,-1},{0xe0,0xF0,0x01,-1} }, /*140*/ - { {0xe0,0x09,-1},{0xe0,0xF0,0x09,-1} }, { { -1},{ -1} }, { {0xe0,0x7E,-1},{0xe0,0xF0,0x7E,-1} }, { { 0x6E,-1},{ 0xf0,0x6E,-1} }, /*144*/ - { { 0x63,-1},{ 0xf0,0x63,-1} }, { { 0x6F,-1},{ 0xf0,0x6F,-1} }, { { -1},{ -1} }, { { 0x61,-1},{ 0xf0,0x61,-1} }, /*148*/ - { {0xe0,0x73,-1},{0xe0,0xF0,0x73,-1} }, { { 0x6A,-1},{ 0xf0,0x6A,-1} }, { {0xe0,0x79,-1},{0xe0,0xF0,0x79,-1} }, { { 0x65,-1},{ 0xf0,0x65,-1} }, /*14c*/ - { { 0x60,-1},{ 0xf0,0x60,-1} }, { { 0x6D,-1},{ 0xf0,0x6D,-1} }, { { 0x67,-1},{ 0xf0,0x67,-1} }, { { 0x64,-1},{ 0xf0,0x64,-1} }, /*150*/ - { { 0xd4,-1},{ 0xf0,0xD4,-1} }, { {0xe0,0x60,-1},{0xe0,0xF0,0x60,-1} }, { { -1},{ -1} }, { {0xe0,0x78,-1},{0xe0,0xF0,0x78,-1} }, /*154*/ - { {0xe0,0x07,-1},{0xe0,0xF0,0x07,-1} }, { {0xe0,0x0F,-1},{0xe0,0xF0,0x0F,-1} }, { {0xe0,0x17,-1},{0xe0,0xF0,0x17,-1} }, { { 0x8B,-1},{ 0xf0,0x8B,-1} }, /*158*/ - { { 0x8C,-1},{ 0xf0,0x8C,-1} }, { { 0x8D,-1},{ 0xf0,0x8D,-1} }, { { -1},{ -1} }, { { 0x7F,-1},{ 0xf0,0x7F,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x4F,-1},{0xe0,0xF0,0x4F,-1} }, { {0xe0,0x56,-1},{0xe0,0xF0,0x56,-1} }, { { -1},{ -1} }, /*160*/ - { {0xe0,0x08,-1},{0xe0,0xF0,0x08,-1} }, { {0xe0,0x10,-1},{0xe0,0xF0,0x10,-1} }, { {0xe0,0x18,-1},{0xe0,0xF0,0x18,-1} }, { {0xe0,0x20,-1},{0xe0,0xF0,0x20,-1} }, /*164*/ - { {0xe0,0x28,-1},{0xe0,0xF0,0x28,-1} }, { {0xe0,0x30,-1},{0xe0,0xF0,0x30,-1} }, { {0xe0,0x38,-1},{0xe0,0xF0,0x38,-1} }, { {0xe0,0x40,-1},{0xe0,0xF0,0x40,-1} }, /*168*/ - { {0xe0,0x48,-1},{0xe0,0xF0,0x48,-1} }, { {0xe0,0x50,-1},{0xe0,0xF0,0x50,-1} }, { {0xe0,0x57,-1},{0xe0,0xF0,0x57,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x13,-1},{0xe0,0xF0,0x13,-1} }, { {0xe0,0x19,-1},{0xe0,0xF0,0x19,-1} }, { {0xe0,0x39,-1},{0xe0,0xF0,0x39,-1} }, { {0xe0,0x51,-1},{0xe0,0xF0,0x51,-1} }, /*170*/ - { {0xe0,0x53,-1},{0xe0,0xF0,0x53,-1} }, { {0xe0,0x5C,-1},{0xe0,0xF0,0x5C,-1} }, { { -1},{ -1} }, { {0xe0,0x62,-1},{0xe0,0xF0,0x62,-1} }, /*174*/ - { {0xe0,0x63,-1},{0xe0,0xF0,0x63,-1} }, { {0xe0,0x64,-1},{0xe0,0xF0,0x64,-1} }, { {0xe0,0x65,-1},{0xe0,0xF0,0x65,-1} }, { {0xe0,0x67,-1},{0xe0,0xF0,0x67,-1} }, /*178*/ - { {0xe0,0x68,-1},{0xe0,0xF0,0x68,-1} }, { {0xe0,0x6A,-1},{0xe0,0xF0,0x6A,-1} }, { {0xe0,0x6D,-1},{0xe0,0xF0,0x6D,-1} }, { {0xe0,0x6E,-1},{0xe0,0xF0,0x6E,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{0xe0,0xF0,0xE1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{0xe0,0xF0,0xEE,-1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{0xe0,0xF0,0xF1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ -}; - - -static void -kbdlog(const char *fmt, ...) -{ -#ifdef ENABLE_KEYBOARD_AT_LOG - va_list ap; - - if (keyboard_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -kbd_setmap(atkbd_t *kbd) -{ - switch (keyboard_mode & 3) { - case 1: - default: - keyboard_set_table(scancode_set1); - break; - - case 2: - keyboard_set_table(scancode_set2); - break; - - case 3: - keyboard_set_table(scancode_set3); - break; - } - - if (keyboard_mode & 0x20) - keyboard_set_table(scancode_set1); -} - - -static void -kbd_poll(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - keyboard_delay += (1000LL * TIMER_USEC); - - if ((kbd->out_new != -1) && !kbd->last_irq) { - kbd->wantirq = 0; - if (kbd->out_new & 0x100) { - kbdlog("ATkbd: want mouse data\n"); - if (kbd->mem[0] & 0x02) - picint(0x1000); - kbd->out = kbd->out_new & 0xff; - kbd->out_new = -1; - kbd->status |= STAT_OFULL; - kbd->status &= ~STAT_IFULL; - kbd->status |= STAT_MFULL; - kbd->last_irq = 0x1000; - } else { - kbdlog("ATkbd: want keyboard data\n"); - if (kbd->mem[0] & 0x01) - picint(2); - kbd->out = kbd->out_new & 0xff; - kbd->out_new = -1; - kbd->status |= STAT_OFULL; - kbd->status &= ~STAT_IFULL; - kbd->status &= ~STAT_MFULL; - kbd->last_irq = 2; - } - } - - if (kbd->out_new == -1 && !(kbd->status & STAT_OFULL) && - key_ctrl_queue_start != key_ctrl_queue_end) { - kbd->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && - kbd->out_delayed != -1) { - kbd->out_new = kbd->out_delayed; - kbd->out_delayed = -1; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && - !(kbd->mem[0] & 0x10) && kbd->out_delayed != -1) { - kbd->out_new = kbd->out_delayed; - kbd->out_delayed = -1; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1/* && !(kbd->mem[0] & 0x20)*/ && - (mouse_queue_start != mouse_queue_end)) { - kbd->out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(kbd->status&STAT_OFULL) && kbd->out_new == -1 && - !(kbd->mem[0]&0x10) && (key_queue_start != key_queue_end)) { - kbd->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } -} - - -static void -kbd_adddata(uint8_t val) -{ - key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; - - if (!(CurrentKbd->out_new & 0x300)) { - CurrentKbd->out_delayed = CurrentKbd->out_new; - CurrentKbd->out_new = -1; - } -} - - -static void -kbd_adddata_vals(uint8_t *val, uint8_t len) -{ - int translate = (keyboard_mode & 0x40) && !(keyboard_mode & 0x20); - int i; - uint8_t or = 0; - uint8_t send; - - for (i = 0; i < len; i++) { - if (translate) { - if (val[i] == 0xf0) { - or = 0x80; - continue; - } - send = nont_to_t[val[i]] | or; - if (or == 0x80) - or = 0; - } else - send = val[i]; - kbdlog("%02X", send); - kbd_adddata(send); - if (i < (len - 1)) kbdlog(" "); - } - - if (translate) { - kbdlog(" original: ("); - for (i = 0; i < len; i++) { - kbdlog("%02X", val[i]); - if (i < (len - 1)) kbdlog(" "); - } - kbdlog(")"); - } - - kbdlog("\n"); -} - - -static void -kbd_adddata_keyboard(uint16_t val) -{ - int translate = (keyboard_mode & 0x40) && !(keyboard_mode & 0x20); - - uint8_t fake_shift[4]; - uint8_t num_lock = 0, shift_states = 0; - - keyboard_get_states(NULL, &num_lock, NULL); - shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; - - /* Allow for scan code translation. */ - if (translate && (val == 0xf0)) { - kbdlog("Translate is on, F0 prefix detected\n"); - sc_or = 0x80; - return; - } - - /* Skip break code if translated make code has bit 7 set. */ - if (translate && (sc_or == 0x80) && (val & 0x80)) { - kbdlog("Translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); - sc_or = 0; - return; - } - - /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T3100E && (keyboard_recv(0xb8) || keyboard_recv(0x9d))) - { - switch (val) - { - case 0x4f: t3100e_notify_set(0x01); break; /* End */ - case 0x50: t3100e_notify_set(0x02); break; /* Down */ - case 0x51: t3100e_notify_set(0x03); break; /* PgDn */ - case 0x52: t3100e_notify_set(0x04); break; /* Ins */ - case 0x53: t3100e_notify_set(0x05); break; /* Del */ - case 0x54: t3100e_notify_set(0x06); break; /* SysRQ */ - case 0x45: t3100e_notify_set(0x07); break; /* NumLock */ - case 0x46: t3100e_notify_set(0x08); break; /* ScrLock */ - case 0x47: t3100e_notify_set(0x09); break; /* Home */ - case 0x48: t3100e_notify_set(0x0A); break; /* Up */ - case 0x49: t3100e_notify_set(0x0B); break; /* PgUp */ - case 0x4A: t3100e_notify_set(0x0C); break; /* Keypad -*/ - case 0x4B: t3100e_notify_set(0x0D); break; /* Left */ - case 0x4C: t3100e_notify_set(0x0E); break; /* KP 5 */ - case 0x4D: t3100e_notify_set(0x0F); break; /* Right */ - } - } - - kbdlog("Translate is %s, ", translate ? "on" : "off"); - switch(val) { - case FAKE_LSHIFT_ON: - kbdlog("fake left shift on, scan code: "); - if (num_lock) { - if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); - break; - } else { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x12; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xb6; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (!shift_states) - kbdlog("N/A (both shifts off)\n"); - } - break; - case FAKE_LSHIFT_OFF: - kbdlog("fake left shift on, scan code: "); - if (num_lock) { - if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); - break; - } else { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x12; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x36; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x59; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (!shift_states) - kbdlog("N/A (both shifts off)\n"); - } - break; - default: - kbdlog("scan code: "); - if (translate) { - kbdlog("%02X (original: ", (nont_to_t[val] | sc_or)); - if (sc_or == 0x80) - kbdlog("F0 "); - kbdlog("%02X)\n", val); - } else - kbdlog("%02X\n", val); - - key_queue[key_queue_end] = (translate ? (nont_to_t[val] | sc_or) : val); - key_queue_end = (key_queue_end + 1) & 0xf; - break; - } - - if (sc_or == 0x80) sc_or = 0; -} - - -static void -kbd_output_write(atkbd_t *kbd, uint8_t val) -{ - kbdlog("Write output port: %02X (old: %02X)\n", val, kbd->output_port); - if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/ - if (val & 0x20) - picint(1 << 12); - else - picintc(1 << 12); - } - if ((kbd->output_port ^ val) & 0x10) { /*IRQ 1*/ - if (val & 0x10) - picint(1 << 1); - else - picintc(1 << 1); - } - if ((kbd->output_port ^ val) & 0x02) { /*A20 enable change*/ - mem_a20_key = val & 0x02; - mem_a20_recalc(); - flushmmucache(); - } - if ((kbd->output_port ^ val) & 0x01) { /*Reset*/ - if (! (val & 0x01)) { - /* Pin 0 selected. */ - softresetx86(); /*Pulse reset!*/ - cpu_set_edx(); - } - } - kbd->output_port = val; -} - - -static void -kbd_cmd_write(atkbd_t *kbd, uint8_t val) -{ - kbdlog("Write command byte: %02X (old: %02X)\n", val, kbd->mem[0]); - - if ((val & 1) && (kbd->status & STAT_OFULL)) - kbd->wantirq = 1; - if (!(val & 1) && kbd->wantirq) - kbd->wantirq = 0; - - /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ - if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { - val &= ~CCB_TRANSLATE; - kbd->mem[0] &= ~CCB_TRANSLATE; - } - - /* Scan code translate ON/OFF. */ - keyboard_mode &= 0x93; - keyboard_mode |= (val & MODE_MASK); - - keyboard_scan = !(val & 0x10); - kbdlog("ATkbd: keyboard is now %s\n", mouse_scan ? "enabled" : "disabled"); - kbdlog("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); - - /* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); - PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. */ - if (((kbd->flags & KBC_VEN_MASK) == KBC_VEN_AMI) || ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { - keyboard_mode &= ~CCB_PCMODE; - - mouse_scan = !(val & 0x20); - kbdlog("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled"); - - kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); - } -} - - -static void -kbd_output_pulse(atkbd_t *kbd, uint8_t mask) -{ - if (mask != 0xF) { - kbd->old_output_port = kbd->output_port & ~(0xF0 | mask); - kbd_output_write(kbd, kbd->output_port & (0xF0 | mask)); - kbd->pulse_cb = 6LL * TIMER_USEC; - } -} - - -static void -kbd_pulse_poll(void *p) -{ - atkbd_t *kbd = (atkbd_t *) p; - - kbd_output_write(kbd, kbd->output_port | kbd->old_output_port); - kbd->pulse_cb = 0LL; -} - - -static void -kbd_keyboard_set(atkbd_t *kbd, uint8_t enable) -{ - kbd->mem[0] &= 0xef; - kbd->mem[0] |= (enable ? 0x00 : 0x10); - keyboard_scan = enable; -} - - -static void -kbd_mouse_set(atkbd_t *kbd, uint8_t enable) -{ - kbd->mem[0] &= 0xdf; - kbd->mem[0] |= (enable ? 0x00 : 0x20); - mouse_scan = enable; -} - - -static uint8_t -kbd_write64_generic(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xa4: /*Check if password installed*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: check if password installed\n"); - kbd_adddata(0xf1); - return 0; - } else - kbdlog("ATkbd: bad command A4\n"); - break; - case 0xa7: /*Disable mouse port*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: disable mouse port\n"); - kbd_mouse_set(kbd, 0); - return 0; - } else - kbdlog("ATkbd: bad command A7\n"); - break; - case 0xa8: /*Enable mouse port*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: enable mouse port\n"); - kbd_mouse_set(kbd, 1); - return 0; - } else - kbdlog("ATkbd: bad command A8\n"); - break; - case 0xa9: /*Test mouse port*/ - kbdlog("ATkbd: test mouse port\n"); - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - if (mouse_write) - kbd_adddata(0x00); /*no error*/ - else - kbd_adddata(0xff); /*no mouse*/ - return 0; - } else - kbdlog("ATkbd: bad command A9\n"); - break; - case 0xaf: /*Read keyboard version*/ - kbdlog("ATkbd: read keyboard version\n"); - kbd_adddata(0x00); - return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); - - kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); - kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); - return 0; - case 0xd3: /*Write mouse output buffer*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write mouse output buffer\n"); - kbd->want60 = 1; - return 0; - } - break; - case 0xd4: /*Write to mouse*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write to mouse\n"); - kbd->want60 = 1; - return 0; - } - break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - // kbdlog("ATkbd: pulse %01X\n", val & 0x0f); - kbd_output_pulse(kbd, val & 0x0f); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write60_ami(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - /* 0x40 - 0x5F are aliases for 0x60-0x7F */ - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); - kbd->mem[kbd->command & 0x1f] = val; - if (kbd->command == 0x60) - kbd_cmd_write(kbd, val); - return 0; - case 0xaf: /*AMI - set extended controller RAM*/ - kbdlog("AMI - set extended controller RAM\n"); - if (kbd->secr_phase == 1) { - kbd->mem_addr = val; - kbd->want60 = 1; - kbd->secr_phase = 2; - } else if (kbd->secr_phase == 2) { - kbd->mem[kbd->mem_addr] = val; - kbd->secr_phase = 0; - } - return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_ami(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - kbdlog("AMI - alias read from register %08X\n", val); - kbd_adddata(kbd->mem[val]); - return 0; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); - kbd->want60 = 1; - return 0; - case 0xa1: /*AMI - get controller version*/ - kbdlog("AMI - get controller version\n"); - return 0; - case 0xa2: /*AMI - reset keyboard controller lines P22 and P23 low*/ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - reset keyboard controller lines P22 and P23 low\n"); - kbd_output_write(kbd, kbd->output_port & 0xf3); - kbd_adddata(0x00); - return 0; - } - break; - case 0xa3: /*AMI - set keyboard controller lines P22 and P23 high*/ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - set keyboard controller lines P22 and P23 high\n"); - kbd_output_write(kbd, kbd->output_port | 0x0c); - kbd_adddata(0x00); - return 0; - } - break; - case 0xa4: /* AMI - write clock = low */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = low\n"); - kbd->ami_stat &= 0xfe; - return 0; - } - break; - case 0xa5: /* AMI - write clock = high */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = high\n"); - kbd->ami_stat |= 0x01; - return 0; - } - break; - case 0xa6: /* AMI - read clock */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read clock\n"); - kbd_adddata(!!(kbd->ami_stat & 1)); - return 0; - } - break; - case 0xa7: /* AMI - write cache bad */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache bad\n"); - kbd->ami_stat &= 0xfd; - return 0; - } - break; - case 0xa8: /* AMI - write cache good */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache good\n"); - kbd->ami_stat |= 0x02; - return 0; - } - break; - case 0xa9: /* AMI - read cache */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read cache\n"); - kbd_adddata(!!(kbd->ami_stat & 2)); - return 0; - } - break; - case 0xaf: /*Set extended controller RAM*/ - kbdlog("ATkbd: set extended controller RAM\n"); - kbd->want60 = 1; - kbd->secr_phase = 1; - return 0; - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - /*Set keyboard controller line P10-P13 (input port bits 0-3) low*/ - if (!PCI || (val > 0xb1)) - kbd->input_port &= ~(1 << (val & 0x03)); - kbd_adddata(0x00); - return 0; - case 0xb4: case 0xb5: - /*Set keyboard controller line P22-P23 (output port bits 2-3) low*/ - if (!PCI) - kbd_output_write(kbd, kbd->output_port & ~(4 << (val & 0x01))); - kbd_adddata(0x00); - return 0; - case 0xb8: case 0xb9: case 0xba: case 0xbb: - /*Set keyboard controller line P10-P13 (input port bits 0-3) high*/ - if (!PCI || (val > 0xb9)) { - kbd->input_port |= (1 << (val & 0x03)); - kbd_adddata(0x00); - } - return 0; - case 0xbc: case 0xbd: - /*Set keyboard controller line P22-P23 (output port bits 2-3) high*/ - if (!PCI) - kbd_output_write(kbd, kbd->output_port | (4 << (val & 0x01))); - kbd_adddata(0x00); - return 0; - case 0xc8: /*AMI - unblock keyboard controller lines P22 and P23 - (allow command D1 to change bits 2 and 3 of the output - port)*/ - kbdlog("AMI - unblock keyboard controller lines P22 and P23\n"); - kbd->output_locked = 1; - return 0; - case 0xc9: /*AMI - block keyboard controller lines P22 and P23 - (prevent command D1 from changing bits 2 and 3 of the - output port)*/ - kbdlog("AMI - block keyboard controller lines P22 and P23\n"); - kbd->output_locked = 1; - return 0; - case 0xca: /*AMI - read keyboard mode*/ - kbdlog("AMI - read keyboard mode\n"); - kbd_adddata(0x00); /*ISA mode*/ - return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - kbd->want60 = 1; - return 0; - case 0xef: /*??? - sent by AMI486*/ - kbdlog("??? - sent by AMI486\n"); - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write64_ibm_mca(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 0 to 3 of input port to status bits 4 to 7\n"); - kbd->status &= 0xf; - kbd->status |= ((((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf) << 4); - return 0; - case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 4 to 7 of input port to status bits 4 to 7\n"); - kbd->status &= 0xf; - kbd->status |= (((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0); - return 0; - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - kbdlog("ATkbd: pulse: %01X\n", (val & 0x03) | 0x0c); - kbd_output_pulse(kbd, (val & 0x03) | 0x0c); - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write60_quadtel(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_quadtel(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - kbd->want60 = 1; - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write60_toshiba(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - case 0xb6: /* T3100e - set colour/mono switch */ - t3100e_mono_set(val); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_toshiba(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xb0: /* T3100e: Turbo on */ - t3100e_turbo_set(1); - return 0; - case 0xb1: /* T3100e: Turbo off */ - t3100e_turbo_set(0); - return 0; - case 0xb2: /* T3100e: Select external display */ - t3100e_display_set(0x00); - return 0; - case 0xb3: /* T3100e: Select internal display */ - t3100e_display_set(0x01); - return 0; - case 0xb4: /* T3100e: Get configuration / status */ - kbd_adddata(t3100e_config_get()); - return 0; - case 0xb5: /* T3100e: Get colour / mono byte */ - kbd_adddata(t3100e_mono_get()); - return 0; - case 0xb6: /* T3100e: Set colour / mono byte */ - kbd->want60 = 1; - return 0; - case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ - case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ - return 0; - case 0xbb: /* T3100e: Read 'Fn' key. - Return it for right Ctrl and right Alt; on the real - T3100e, these keystrokes could only be generated - using 'Fn'. */ - if (keyboard_recv(0xb8) || /* Right Alt */ - keyboard_recv(0x9d)) /* Right Ctrl */ - kbd_adddata(0x04); - else kbd_adddata(0x00); - return 0; - case 0xbc: /* T3100e: Reset Fn+Key notification */ - t3100e_notify_set(0x00); - return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); - - /* The T3100e returns all bits set except bit 6 which - * is set by t3100e_mono_set() */ - kbd->input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - kbd_adddata(kbd->input_port); - return 0; - - } - - return kbd_write64_generic(kbd, val); -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - int i = 0; - int bad = 1; - uint8_t mask; - - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; - - switch (port) { - case 0x60: - if (kbd->want60) { - /*Write to controller*/ - kbd->want60 = 0; - switch (kbd->command) { - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x65: case 0x66: case 0x67: - case 0x68: case 0x69: case 0x6a: case 0x6b: - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - kbd->mem[kbd->command & 0x1f] = val; - if (kbd->command == 0x60) - kbd_cmd_write(kbd, val); - break; - - case 0xd1: /*Write output port*/ - // kbdlog("Write output port\n"); - if (kbd->output_locked) { - /*If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged.*/ - val &= ~0x0c; - val |= (kbd->output_port & 0x0c); - } - kbd_output_write(kbd, val); - break; - - case 0xd2: /*Write to keyboard output buffer*/ - kbdlog("ATkbd: write to keyboard output buffer\n"); - kbd_adddata_keyboard(val); - break; - - case 0xd3: /*Write to mouse output buffer*/ - kbdlog("ATkbd: write to mouse output buffer\n"); - if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - keyboard_at_adddata_mouse(val); - break; - - case 0xd4: /*Write to mouse*/ - kbdlog("ATkbd: write to mouse (%02X)\n", val); - kbd_mouse_set(kbd, 1); - if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - mouse_write(val, mouse_p); - else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - keyboard_at_adddata_mouse(0xff); - break; - - default: - /* Run the vendor-specific command handler, if present, - otherwise (or if the former returns 1), assume bad command. */ - if (kbd->write60_ven) - bad = kbd->write60_ven(kbd, val); - - if (bad) - kbdlog("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); - } - } else { - /*Write to keyboard*/ - kbd->mem[0] &= ~0x10; - if (kbd->key_wantdata) { - kbd->key_wantdata = 0; - switch (kbd->key_command) { - case 0xed: /*Set/reset LEDs*/ - kbd_adddata_keyboard(0xfa); - break; - - case 0xf0: /*Get/set scancode set*/ - if (val == 0) { - kbd_adddata_keyboard(keyboard_mode & 3); - } else { - if (val <= 3) { - keyboard_mode &= 0xFC; - keyboard_mode |= (val & 3); - } - kbd_adddata_keyboard(0xfa); - kbd_setmap(kbd); - } - break; - - case 0xf3: /*Set typematic rate/delay*/ - kbd_adddata_keyboard(0xfa); - break; - - default: - kbdlog("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, kbd->key_command); - } - } else { - kbd->key_command = val; - kbd_keyboard_set(kbd, 1); - switch (val) { - case 0x00: - kbdlog("ATkbd: command 00\n"); - kbd_adddata_keyboard(0xfa); - break; - - case 0x05: /*??? - sent by NT 4.0*/ - kbdlog("ATkbd: nt 4.0 command fe\n"); - kbd_adddata_keyboard(0xfe); - break; - - case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/ - case 0x82: - kbdlog("ATkbd: pentium-era ami bios command %02x\n", val); - break; - - case 0xed: /*Set/reset LEDs*/ - kbdlog("ATkbd: set/reset leds\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xee: /*Diagnostic echo*/ - kbdlog("ATkbd: diagnostic echo\n"); - kbd_adddata_keyboard(0xee); - break; - - case 0xef: /*NOP (No OPeration). Reserved for future use.*/ - kbdlog("ATkbd: kbd nop\n"); - break; - - case 0xf0: /*Get/set scan code set*/ - kbdlog("ATkbd: scan code set\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf2: /*Read ID*/ - /* Fixed as translation will be done in kbd_adddata_keyboard(). */ - kbdlog("ATkbd: read keyboard id\n"); - kbd_adddata_keyboard(0xfa); - kbd_adddata_keyboard(0xab); - kbd_adddata_keyboard(0x83); - break; - - case 0xf3: /*Set typematic rate/delay*/ - kbdlog("ATkbd: set typematic rate/delay\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf4: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard via keyboard\n"); - keyboard_scan = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf5: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard via keyboard\n"); - keyboard_scan = 0; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf6: /*Set defaults*/ - kbdlog("ATkbd: set defaults\n"); - keyboard_set3_all_break = 0; - keyboard_set3_all_repeat = 0; - memset(keyboard_set3_flags, 0, 512); - keyboard_mode = (keyboard_mode & 0xFC) | 0x02; - kbd_adddata_keyboard(0xfa); - kbd_setmap(kbd); - break; - - case 0xf7: /*Set all keys to repeat*/ - kbdlog("ATkbd: set all keys to repeat\n"); - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf8: /*Set all keys to give make/break codes*/ - kbdlog("ATkbd: set all keys to give make/break codes\n"); - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf9: /*Set all keys to give make codes only*/ - kbdlog("ATkbd: set all keys to give make codes only\n"); - keyboard_set3_all_break = 0; - kbd_adddata_keyboard(0xfa); - break; - - case 0xfa: /*Set all keys to repeat and give make/break codes*/ - kbdlog("ATkbd: set all keys to repeat and give make/break codes\n"); - keyboard_set3_all_repeat = 1; - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xfe: /*Resend last scan code*/ - kbdlog("ATkbd: reset last scan code\n"); - kbd_adddata_keyboard(kbd->last_scan_code); - break; - - case 0xff: /*Reset*/ - kbdlog("ATkbd: kbd reset\n"); - key_queue_start = key_queue_end = 0; /*Clear key queue*/ - kbd_adddata_keyboard(0xfa); - kbd_adddata_keyboard(0xaa); - /* Set system flag to 1 and scan code set to 2. */ - keyboard_mode &= 0xFC; - keyboard_mode |= 2; - kbd_setmap(kbd); - break; - - default: - kbdlog("ATkbd: bad keyboard command %02X\n", val); - kbd_adddata_keyboard(0xfe); - } - } - } - break; - - case 0x61: - ppi.pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); - - if (romset == ROM_XI8088) { - if (val & 0x04) - xi8088_turbo_set(1); - else - xi8088_turbo_set(0); - } - break; - - case 0x64: - kbd->want60 = 0; - kbd->command = val; - /*New controller command*/ - switch (val) { - case 0x20: case 0x21: case 0x22: case 0x23: - case 0x24: case 0x25: case 0x26: case 0x27: - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - kbd_adddata(kbd->mem[val & 0x1f]); - break; - - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x65: case 0x66: case 0x67: - case 0x68: case 0x69: case 0x6a: case 0x6b: - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - kbd->want60 = 1; - break; - - case 0xaa: /*Self-test*/ - kbdlog("Self-test\n"); - if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) - kbd->status |= STAT_IFULL; - if (! kbd->initialized) { - kbd->initialized = 1; - key_ctrl_queue_start = key_ctrl_queue_end = 0; - kbd->status &= ~STAT_OFULL; - } - kbd->status |= STAT_SYSFLAG; - kbd->mem[0] |= 0x04; - kbd_keyboard_set(kbd, 1); - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) - kbd_mouse_set(kbd, 1); - kbd_output_write(kbd, 0xcf); - kbd_adddata(0x55); - break; - - case 0xab: /*Interface test*/ - kbdlog("ATkbd: interface test\n"); - kbd_adddata(0x00); /*no error*/ - break; - - case 0xac: /*Diagnostic dump*/ - kbdlog("ATkbd: diagnostic dump\n"); - for (i=0; i<16; i++) - kbd_adddata(kbd->mem[i]); - kbd_adddata((kbd->input_port & 0xf0) | 0x80); - kbd_adddata(kbd->output_port); - kbd_adddata(kbd->status); - break; - - case 0xad: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard\n"); - kbd_keyboard_set(kbd, 0); - break; - - case 0xae: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard\n"); - kbd_keyboard_set(kbd, 1); - break; - - case 0xd0: /*Read output port*/ - kbdlog("ATkbd: read output port\n"); - mask = 0xff; - if(!keyboard_scan) - mask &= 0xbf; - if(!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - mask &= 0xf7; - kbd_adddata(kbd->output_port & mask); - break; - - case 0xd1: /*Write output port*/ - // kbdlog("ATkbd: write output port\n"); - kbd->want60 = 1; - break; - - case 0xd2: /*Write keyboard output buffer*/ - kbdlog("ATkbd: write keyboard output buffer\n"); - kbd->want60 = 1; - break; - - case 0xdd: /* Disable A20 Address Line */ - kbdlog("ATkbd: disable A20 Address Line\n"); - kbd_output_write(kbd, kbd->output_port & 0xfd); - break; - - case 0xdf: /* Enable A20 Address Line */ - kbdlog("ATkbd: enable A20 address line\n"); - kbd_output_write(kbd, kbd->output_port | 0x02); - break; - - case 0xe0: /*Read test inputs*/ - kbdlog("ATkbd: read test inputs\n"); - kbd_adddata(0x00); - break; - - default: - /* Run the vendor-specific command handler, if present, - otherwise (or if the former returns 1), assume bad command. */ - if (kbd->write64_ven) - bad = kbd->write64_ven(kbd, val); - - if (bad) - kbdlog("ATkbd: bad controller command %02X\n", val); - } - break; - } -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - uint8_t ret = 0xff; - - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; - - switch (port) { - case 0x60: - ret = kbd->out; - kbd->status &= ~(STAT_OFULL); - picintc(kbd->last_irq); - kbd->last_irq = 0; - break; - - case 0x61: - ret = ppi.pb & ~0xe0; - if (ppispeakon) - ret |= 0x20; - if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { - if (kbd->refresh) - ret |= 0x10; - else - ret &= ~0x10; - } - if (romset == ROM_XI8088){ - if (xi8088_turbo_get()) - ret |= 0x04; - else - ret &= ~0x04; - } - break; - - case 0x64: - ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); - ret |= STAT_LOCK; - /* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise - the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */ - kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); - break; - } - - return(ret); -} - - -static void -kbd_refresh(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd->refresh = !kbd->refresh; - kbd->refresh_time += PS2_REFRESH_TIME; -} - - -static void -kbd_reset(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd->initialized = 0; - kbd->dtrans = 0; - kbd->first_write = 1; - kbd->status = STAT_LOCK | STAT_CD; - kbd->mem[0] = 0x01; - kbd->wantirq = 0; - kbd_output_write(kbd, 0xcf); - kbd->input_port = (video_is_mda()) ? 0xf0 : 0xb0; - kbd->out_new = -1; - kbd->last_irq = 0; - kbd->secr_phase = 0; - kbd->key_wantdata = 0; - - keyboard_mode = 0x02 | kbd->dtrans; - - kbd_keyboard_set(kbd, 1); - kbd_mouse_set(kbd, 0); - - sc_or = 0; - keyboard_update_states(0, 0, 0); - - memset(keyboard_set3_flags, 0, 512); - - kbd_setmap(kbd); -} - - -static void * -kbd_init(const device_t *info) -{ - atkbd_t *kbd; - - kbd = (atkbd_t *)malloc(sizeof(atkbd_t)); - memset(kbd, 0x00, sizeof(atkbd_t)); - - kbd->flags = info->local; - - kbd_reset(kbd); - - io_sethandler(0x0060, 5, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - keyboard_send = kbd_adddata_keyboard; - - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); - - if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { - if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) - keyboard_mode &= ~0x03; /* These machines force translation off, so the keyboard - must start in scan code set 0. */ - - timer_add(kbd_refresh, - &kbd->refresh_time, TIMER_ALWAYS_ENABLED, kbd); - } - - timer_add(kbd_pulse_poll, - &kbd->pulse_cb, &kbd->pulse_cb, kbd); - - kbd->write60_ven = NULL; - kbd->write64_ven = NULL; - - switch(kbd->flags & KBC_VEN_MASK) { - case KBC_VEN_GENERIC: - kbd->write64_ven = &kbd_write64_generic; - break; - case KBC_VEN_AMI: - kbd->write60_ven = &kbd_write60_ami; - kbd->write64_ven = &kbd_write64_ami; - break; - case KBC_VEN_IBM_MCA: - kbd->write64_ven = &kbd_write64_ibm_mca; - break; - case KBC_VEN_QUADTEL: - kbd->write60_ven = &kbd_write60_quadtel; - kbd->write64_ven = &kbd_write64_quadtel; - break; - case KBC_VEN_TOSHIBA: - kbd->write60_ven = &kbd_write60_toshiba; - kbd->write64_ven = &kbd_write64_toshiba; - break; - } - - /* We need this, sadly. */ - CurrentKbd = kbd; - - return(kbd); -} - - -static void -kbd_close(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd_reset(kbd); - - /* Stop timers. */ - keyboard_delay = 0; - kbd->refresh_time = 0; - - keyboard_scan = 0; - keyboard_send = NULL; - - /* Disable the scancode maps. */ - keyboard_set_table(NULL); - - CurrentKbd = NULL; - free(kbd); -} - - -const device_t keyboard_at_device = { - "PC/AT Keyboard", - 0, - KBC_TYPE_ISA | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_at_ami_device = { - "PC/AT Keyboard (AMI)", - 0, - KBC_TYPE_ISA | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_at_toshiba_device = { - "PC/AT Keyboard (Toshiba)", - 0, - KBC_TYPE_ISA | KBC_VEN_TOSHIBA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_ami_device = { - "PS/2 Keyboard (AMI)", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_mca_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_mca_2_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_quadtel_device = { - "PS/2 Keyboard (Quadtel/MegaPC)", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_pci_device = { - "PS/2 Keyboard", - DEVICE_PCI, - KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_ami_pci_device = { - "PS/2 Keyboard (AMI)", - DEVICE_PCI, - KBC_TYPE_PS2_1 | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - - -void -keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv) -{ - mouse_write = func; - mouse_p = priv; -} - - -void -keyboard_at_adddata_keyboard_raw(uint8_t val) -{ - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; -} - - -void -keyboard_at_adddata_mouse(uint8_t val) -{ - mouse_queue[mouse_queue_end] = val; - mouse_queue_end = (mouse_queue_end + 1) & 0xf; -} - - -void -keyboard_at_set_mouse_scan(uint8_t val) -{ - atkbd_t *kbd = CurrentKbd; - uint8_t temp_mouse_scan = val ? 1 : 0; - - if (temp_mouse_scan == mouse_scan) return; - - kbd_mouse_set(kbd, val ? 1 : 0); - - kbdlog("ATkbd: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis"); -} - - -uint8_t -keyboard_at_get_mouse_scan(void) -{ - return(mouse_scan ? 0x10 : 0x00); -} diff --git a/src - Cópia/keyboard_xt.c b/src - Cópia/keyboard_xt.c deleted file mode 100644 index 80405387c..000000000 --- a/src - Cópia/keyboard_xt.c +++ /dev/null @@ -1,595 +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. - * - * Implementation of the XT-style keyboard. - * - * Version: @(#)keyboard_xt.c 1.0.12 2018/04/26 - * - * 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. - */ -#include -#include -#include -#include -#include -#include "86box.h" -#include "machine/machine.h" -#include "io.h" -#include "pic.h" -#include "pit.h" -#include "ppi.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" -#include "device.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" -#include "keyboard.h" - - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - - -typedef struct { - int blocked; - - uint8_t pa; - uint8_t pb; - - int tandy; -} xtkbd_t; - - -/*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ -const scancode scancode_xt[512] = { - { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, - { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, - { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, - { {0x06, -1}, {0x86, -1} }, { {0x07, -1}, {0x87, -1} }, - { {0x08, -1}, {0x88, -1} }, { {0x09, -1}, {0x89, -1} }, - { {0x0a, -1}, {0x8a, -1} }, { {0x0b, -1}, {0x8b, -1} }, - { {0x0c, -1}, {0x8c, -1} }, { {0x0d, -1}, {0x8d, -1} }, - { {0x0e, -1}, {0x8e, -1} }, { {0x0f, -1}, {0x8f, -1} }, - { {0x10, -1}, {0x90, -1} }, { {0x11, -1}, {0x91, -1} }, - { {0x12, -1}, {0x92, -1} }, { {0x13, -1}, {0x93, -1} }, - { {0x14, -1}, {0x94, -1} }, { {0x15, -1}, {0x95, -1} }, - { {0x16, -1}, {0x96, -1} }, { {0x17, -1}, {0x97, -1} }, - { {0x18, -1}, {0x98, -1} }, { {0x19, -1}, {0x99, -1} }, - { {0x1a, -1}, {0x9a, -1} }, { {0x1b, -1}, {0x9b, -1} }, - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, - { {0x1e, -1}, {0x9e, -1} }, { {0x1f, -1}, {0x9f, -1} }, - { {0x20, -1}, {0xa0, -1} }, { {0x21, -1}, {0xa1, -1} }, - { {0x22, -1}, {0xa2, -1} }, { {0x23, -1}, {0xa3, -1} }, - { {0x24, -1}, {0xa4, -1} }, { {0x25, -1}, {0xa5, -1} }, - { {0x26, -1}, {0xa6, -1} }, { {0x27, -1}, {0xa7, -1} }, - { {0x28, -1}, {0xa8, -1} }, { {0x29, -1}, {0xa9, -1} }, - { {0x2a, -1}, {0xaa, -1} }, { {0x2b, -1}, {0xab, -1} }, - { {0x2c, -1}, {0xac, -1} }, { {0x2d, -1}, {0xad, -1} }, - { {0x2e, -1}, {0xae, -1} }, { {0x2f, -1}, {0xaf, -1} }, - { {0x30, -1}, {0xb0, -1} }, { {0x31, -1}, {0xb1, -1} }, - { {0x32, -1}, {0xb2, -1} }, { {0x33, -1}, {0xb3, -1} }, - { {0x34, -1}, {0xb4, -1} }, { {0x35, -1}, {0xb5, -1} }, - { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, - { {0x38, -1}, {0xb8, -1} }, { {0x39, -1}, {0xb9, -1} }, - { {0x3a, -1}, {0xba, -1} }, { {0x3b, -1}, {0xbb, -1} }, - { {0x3c, -1}, {0xbc, -1} }, { {0x3d, -1}, {0xbd, -1} }, - { {0x3e, -1}, {0xbe, -1} }, { {0x3f, -1}, {0xbf, -1} }, - { {0x40, -1}, {0xc0, -1} }, { {0x41, -1}, {0xc1, -1} }, - { {0x42, -1}, {0xc2, -1} }, { {0x43, -1}, {0xc3, -1} }, - { {0x44, -1}, {0xc4, -1} }, { {0x45, -1}, {0xc5, -1} }, - { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, - { {0x4a, -1}, {0xca, -1} }, { {0x4b, -1}, {0xcb, -1} }, - { {0x4c, -1}, {0xcc, -1} }, { {0x4d, -1}, {0xcd, -1} }, - { {0x4e, -1}, {0xce, -1} }, { {0x4f, -1}, {0xcf, -1} }, - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, - { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*054*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*058*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*05c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*060*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*064*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*068*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*06c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*070*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*074*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*078*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*07c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*080*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*084*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*088*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*08c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*090*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*094*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*098*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*09c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0cc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0fc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*100*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*104*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*108*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*10c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*110*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*114*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*118*/ - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*11c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*120*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*124*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*128*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*12c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*130*/ - { {-1}, {-1} }, { {0x35, -1}, {0xb5, -1} }, - { {-1}, {-1} }, { {0x37, -1}, {0xb7, -1} }, /*134*/ - { {0x38, -1}, {0xb8, -1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*138*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*13c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*140*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, /*144*/ - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, - { {-1}, {-1} }, { {0x4b, -1}, {0xcb, -1} }, /*148*/ - { {-1}, {-1} }, { {0x4d, -1}, {0xcd, -1} }, - { {-1}, {-1} }, { {0x4f, -1}, {0xcf, -1} }, /*14c*/ - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, - { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, /*150*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*154*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*158*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*15c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*160*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*164*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*168*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*16c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*170*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*174*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*148*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*17c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*180*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*184*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*88*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*18c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*190*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*194*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*198*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*19c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1cc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} } /*1fc*/ -}; - - -static uint8_t key_queue[16]; -static int key_queue_start, - key_queue_end; - - -static void -kbd_poll(void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *)priv; - - keyboard_delay += (1000LL * TIMER_USEC); - - if (key_queue_start != key_queue_end && !kbd->blocked) { - kbd->pa = key_queue[key_queue_start]; - picint(2); -#if ENABLE_KEYBOARD_LOG - pclog("XTkbd: reading %02X from the key queue at %i\n", - kbd->pa, key_queue_start); -#endif - key_queue_start = (key_queue_start + 1) & 0x0f; - kbd->blocked = 1; - } -} - - -static void -kbd_adddata(uint16_t val) -{ - key_queue[key_queue_end] = val; -#if ENABLE_KEYBOARD_LOG - pclog("XTkbd: %02X added to key queue at %i\n", - val, key_queue_end); -#endif - key_queue_end = (key_queue_end + 1) & 0x0f; -} - - -void -kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) -{ - uint8_t num_lock = 0, shift_states = 0; - - if (!adddata) - return; - - keyboard_get_states(NULL, &num_lock, NULL); - shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; - - switch(val) { - case FAKE_LSHIFT_ON: - if (num_lock) { - if (!shift_states) { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - adddata(0x2a); - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - adddata(0xaa); - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - adddata(0xb6); - } - } - break; - case FAKE_LSHIFT_OFF: - if (num_lock) { - if (!shift_states) { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - adddata(0xaa); - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - adddata(0x2a); - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - adddata(0x36); - } - } - break; - default: - adddata(val); - break; - } -} - - -void -kbd_adddata_ex(uint16_t val) -{ - kbd_adddata_process(val, kbd_adddata); -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *)priv; - - if (port != 0x61) return; - - if (!(kbd->pb & 0x40) && (val & 0x40)) { /*Reset keyboard*/ -#if ENABLE_KEYBOARD_LOG - pclog("XTkbd: reset keyboard\n"); -#endif - key_queue_end = key_queue_start; - kbd_adddata(0xaa); - } - - if ((kbd->pb & 0x80)==0 && (val & 0x80)!=0) { - kbd->pa = 0; - kbd->blocked = 0; - picintc(2); - } - kbd->pb = val; - ppi.pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x60: - if ((romset == ROM_IBMPC) && (kbd->pb & 0x80)) { - if (video_is_ega_vga()) - ret = 0x4d; - else if (video_is_mda()) - ret = 0x7d; - else - ret = 0x6d; - } else - ret = kbd->pa; - break; - - case 0x61: - ret = kbd->pb; - break; - - case 0x62: - if (romset == ROM_IBMPC) { - if (kbd->pb & 0x04) - ret = ((mem_size-64) / 32) & 0x0f; - else - ret = ((mem_size-64) / 32) >> 4; - } else { - if (kbd->pb & 0x08) { - if (video_is_ega_vga()) - ret = 0x4; - else if (video_is_mda()) - ret = 0x7; - else - ret = 0x6; - } else { - /* LaserXT = Always 512k RAM; - LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - if (romset == ROM_LXT3) - ret = (mem_size == 512) ? 0x0d : 0x0c; - else -#endif - ret = 0x0d; - } - } - ret |= (ppispeakon ? 0x20 : 0); - - if (kbd->tandy) - ret |= (tandy1k_eeprom_read() ? 0x10 : 0); - break; - - default: - pclog("XTkbd: bad read %04X\n", port); - ret = 0xff; - } - - return(ret); -} - - -static void -kbd_reset(void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *)priv; - - kbd->blocked = 0; - kbd->pa = 0x00; - kbd->pb = 0x00; - - key_queue_start = 0, - key_queue_end = 0; -} - - -static void * -kbd_init(const device_t *info) -{ - xtkbd_t *kbd; - - kbd = (xtkbd_t *)malloc(sizeof(xtkbd_t)); - memset(kbd, 0x00, sizeof(xtkbd_t)); - - keyboard_set_table(scancode_xt); - - if (info->local == 1) { - kbd->tandy = 1; - } - - keyboard_scan = 1; - - io_sethandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - keyboard_send = kbd_adddata_ex; - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); - - return(kbd); -} - - -static void -kbd_close(void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *)priv; - - /* Stop the timer. */ - keyboard_delay = 0; - - /* Disable scanning. */ - keyboard_scan = 0; - - keyboard_send = NULL; - - io_removehandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - - free(kbd); -} - - -const device_t keyboard_xt_device = { - "PC/XT Keyboard", - 0, - 0, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_tandy_device = { - "Tandy 1000 Keyboard", - 0, - 1, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; diff --git a/src - Cópia/lang/language.h b/src - Cópia/lang/language.h deleted file mode 100644 index 39e3aff6a..000000000 --- a/src - Cópia/lang/language.h +++ /dev/null @@ -1,186 +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. - * - * Definitions for the language management module. - * - * NOTE: FIXME: Strings 2176 and 2193 are same. - * - * Version: @(#)language.h 1.0.8 2018/05/25 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef LANG_UAGE_H -# define LANG_UAGE_H - - -/* String IDs. */ -#define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "86Box Error" -#define IDS_2050 2050 // "86Box Fatal Error" -#define IDS_2051 2051 // "This will reset 86Box.." -#define IDS_2052 2052 // "Use CTRL+ALT+PAGE DOWN.." -#define IDS_2053 2053 // "Speed" -#define IDS_2054 2054 // "ZIP %i (%03i): %ls" -#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2056 2056 // "No usable ROM images found!" -#define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2059 2059 // "(Turbo)" -#define IDS_2060 2060 // "On" -#define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Configured ROM set not avai.." -#define IDS_2064 2064 // "Configured video BIOS not.." -#define IDS_2065 2065 // "Machine" -#define IDS_2066 2066 // "Display" -#define IDS_2067 2067 // "Input devices" -#define IDS_2068 2068 // "Sound" -#define IDS_2069 2069 // "Network" -#define IDS_2070 2070 // "Ports (COM & LPT)" -#define IDS_2071 2071 // "Other peripherals" -#define IDS_2072 2072 // "Hard disks" -#define IDS_2073 2073 // "Floppy drives" -#define IDS_2074 2074 // "Other removable devices" -#define IDS_2075 2075 // "CD-ROM images (*.ISO;*.CU.." -#define IDS_2076 2076 // "Surface-based images (*.8.." -#define IDS_2077 2077 // "Click to capture mouse" -#define IDS_2078 2078 // "Press F12-F8 to release mouse" -#define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2080 2080 // "E&xport to 86F..." -#define IDS_2081 2081 // "Unable to initialize Flui.." -#define IDS_2082 2082 // "Bus" -#define IDS_2083 2083 // "File" -#define IDS_2084 2084 // "C" -#define IDS_2085 2085 // "H" -#define IDS_2086 2086 // "S" -#define IDS_2087 2087 // "MB" -#define IDS_2088 2088 // "Check BPB" -#define IDS_2089 2089 // "&Image..." -#define IDS_2090 2090 // "&Reload previous image" -#define IDS_2091 2091 // "E&mpty" -#define IDS_2092 2092 // "&Mute" -#define IDS_2093 2093 // "E&ject" -#define IDS_2094 2094 // "KB" -#define IDS_2095 2095 // "Neither DirectDraw nor Dire.." -#define IDS_2096 2096 // "&New image..." -#define IDS_2097 2097 // "&Existing image..." -#define IDS_2098 2098 // "Existing image (&Write-pr..." -#define IDS_2099 2099 // "Default" -#define IDS_2100 2100 // "%i Wait state(s)" -#define IDS_2101 2101 // "Type" -#define IDS_2102 2102 // "PCap failed to set up.." -#define IDS_2103 2103 // "No PCap devices found" -#define IDS_2104 2104 // "Invalid PCap device" -#define IDS_2105 2105 // "Standard 2-button joystick(s)" -#define IDS_2106 2106 // "Standard 4-button joystick" -#define IDS_2107 2107 // "Standard 6-button joystick" -#define IDS_2108 2108 // "Standard 8-button joystick" -#define IDS_2109 2109 // "CH Flightstick Pro" -#define IDS_2110 2110 // "Microsoft SideWinder Pad" -#define IDS_2111 2111 // "Thrustmaster Flight Cont.." -#define IDS_2112 2112 // "None" -#define IDS_2113 2113 // "Unable to load Accelerators" -#define IDS_2114 2114 // "Unable to register Raw Input" -#define IDS_2115 2115 // "%u" -#define IDS_2116 2116 // "%u MB (CHS: %i, %i, %i)" -#define IDS_2117 2117 // "Floppy %i (%s): %ls" -#define IDS_2118 2118 // "All floppy images (*.0??;*.." - -#define IDS_4096 4096 // "Hard disk (%s)" -#define IDS_4097 4097 // "%01i:%01i" -#define IDS_4098 4098 // "%i" -#define IDS_4099 4099 // "MFM/RLL or ESDI CD-ROM driv.." -#define IDS_4100 4100 // "Custom..." -#define IDS_4101 4101 // "Custom (large)..." -#define IDS_4102 4102 // "Add New Hard Disk" -#define IDS_4103 4103 // "Add Existing Hard Disk" -#define IDS_4104 4104 // "Attempting to create a HDI ima.." -#define IDS_4105 4105 // "Attempting to create a spurio.." -#define IDS_4106 4106 // "Hard disk images (*.HDI;*.HD.." -#define IDS_4107 4107 // "Unable to open the file for read" -#define IDS_4108 4108 // "Unable to open the file for write" -#define IDS_4109 4109 // "HDI or HDX image with a sect.." -#define IDS_4110 4110 // "USB is not yet supported" -#define IDS_4111 4111 // "This image exists and will be.." -#define IDS_4112 4112 // "Please enter a valid file name" -#define IDS_4113 4113 // "Remember to partition and fo.." - -#define IDS_4352 4352 // "MFM/RLL" -#define IDS_4353 4353 // "XT IDE" -#define IDS_4354 4354 // "ESDI" -#define IDS_4355 4355 // "IDE (PIO-only)" -#define IDS_4356 4356 // "IDE (PIO+DMA)" -#define IDS_4357 4357 // "SCSI" -#define IDS_4358 4358 // "SCSI (removable)" - -#define IDS_4608 4608 // "MFM/RLL (%01i:%01i)" -#define IDS_4609 4609 // "XT IDE (%01i:%01i)" -#define IDS_4610 4610 // "ESDI (%01i:%01i)" -#define IDS_4611 4611 // "IDE (PIO-only) (%01i:%01i)" -#define IDS_4612 4612 // "IDE (PIO+DMA) (%01i:%01i)" -#define IDS_4613 4613 // "SCSI (%02i:%02i)" -#define IDS_4614 4614 // "SCSI (removable) (%02i:%02i)" - -#define IDS_5120 5120 // "CD-ROM %i (%s): %s" - -#define IDS_5376 5376 // "Disabled" -#define IDS_5377 5377 // -#define IDS_5378 5378 // -#define IDS_5379 5379 // -#define IDS_5380 5380 // "ATAPI (PIO-only)" -#define IDS_5381 5381 // "ATAPI (PIO and DMA)" -#define IDS_5382 5382 // "SCSI" - -#define IDS_5632 5632 // "Disabled" -#define IDS_5633 5633 // -#define IDS_5634 5634 // -#define IDS_5635 5635 // -#define IDS_5636 5636 // "ATAPI (PIO-only) (%01i:%01i)" -#define IDS_5637 5637 // "ATAPI (PIO and DMA) (%01i:%01i)" -#define IDS_5638 5638 // "SCSI (%02i:%02i)" - -#define IDS_5888 5888 // "160 kB" -#define IDS_5889 5889 // "180 kB" -#define IDS_5890 5890 // "320 kB" -#define IDS_5891 5891 // "360 kB" -#define IDS_5892 5892 // "640 kB" -#define IDS_5893 5893 // "720 kB" -#define IDS_5894 5894 // "1.2 MB" -#define IDS_5895 5895 // "1.25 MB" -#define IDS_5896 5896 // "1.44 MB" -#define IDS_5897 5897 // "DMF (cluster 1024)" -#define IDS_5898 5898 // "DMF (cluster 2048)" -#define IDS_5899 5899 // "2.88 MB" -#define IDS_5900 5900 // "ZIP 100" -#define IDS_5901 5901 // "ZIP 250" - -#define IDS_6144 6144 // "Perfect RPM" -#define IDS_6145 6145 // "1%% below perfect RPM" -#define IDS_6146 6146 // "1.5%% below perfect RPM" -#define IDS_6147 6147 // "2%% below perfect RPM" - -#define IDS_7168 7168 // "English (United States)" - -#define IDS_LANG_ENUS IDS_7168 - -#define STR_NUM_2048 71 -#define STR_NUM_3072 11 -#define STR_NUM_4096 18 -#define STR_NUM_4352 7 -#define STR_NUM_4608 7 -#define STR_NUM_5120 1 -#define STR_NUM_5376 7 -#define STR_NUM_5632 7 -#define STR_NUM_5888 14 -#define STR_NUM_6144 4 -#define STR_NUM_7168 1 - - -#endif /*LANG_UAGE_H*/ diff --git a/src - Cópia/lpt.c b/src - Cópia/lpt.c deleted file mode 100644 index fbd048beb..000000000 --- a/src - Cópia/lpt.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "86box.h" -#include "io.h" -#include "lpt.h" -#include "sound/snd_lpt_dac.h" -#include "sound/snd_lpt_dss.h" - - -char lpt_device_names[3][16]; - - -static const struct -{ - const char *name; - const char *internal_name; - const lpt_device_t *device; -} lpt_devices[] = -{ - {"None", "none", NULL}, - {"Disney Sound Source", "dss", &dss_device}, - {"LPT DAC / Covox Speech Thing", "lpt_dac", &lpt_dac_device}, - {"Stereo LPT DAC", "lpt_dac_stereo", &lpt_dac_stereo_device}, - {"", "", NULL} -}; - -char *lpt_device_get_name(int id) -{ - if (strlen((char *) lpt_devices[id].name) == 0) - return NULL; - return (char *) lpt_devices[id].name; -} -char *lpt_device_get_internal_name(int id) -{ - if (strlen((char *) lpt_devices[id].internal_name) == 0) - return NULL; - return (char *) lpt_devices[id].internal_name; -} - -static lpt_device_t *lpt_device_ts[3]; -static void *lpt_device_ps[3]; - -void lpt_devices_init() -{ - int i = 0; - int c; - - for (i = 0; i < 3; i++) { - c = 0; - - while (strcmp((char *) lpt_devices[c].internal_name, lpt_device_names[i]) && strlen((char *) lpt_devices[c].internal_name) != 0) - c++; - - if (strlen((char *) lpt_devices[c].internal_name) == 0) - lpt_device_ts[i] = NULL; - else - { - lpt_device_ts[i] = (lpt_device_t *) lpt_devices[c].device; - if (lpt_device_ts[i]) - lpt_device_ps[i] = lpt_device_ts[i]->init(); - } - } -} - -void lpt_devices_close() -{ - int i = 0; - - for (i = 0; i < 3; i++) { - if (lpt_device_ts[i]) - lpt_device_ts[i]->close(lpt_device_ps[i]); - lpt_device_ts[i] = NULL; - } -} - -static uint8_t lpt_dats[3], lpt_ctrls[3]; - -void lpt_write(int i, uint16_t port, uint8_t val, void *priv) -{ - switch (port & 3) - { - case 0: - if (lpt_device_ts[i]) - lpt_device_ts[i]->write_data(val, lpt_device_ps[i]); - lpt_dats[i] = val; - break; - case 2: - if (lpt_device_ts[i]) - lpt_device_ts[i]->write_ctrl(val, lpt_device_ps[i]); - lpt_ctrls[i] = val; - break; - } -} -uint8_t lpt_read(int i, uint16_t port, void *priv) -{ - switch (port & 3) - { - case 0: - return lpt_dats[i]; - case 1: - if (lpt_device_ts[i]) - return lpt_device_ts[i]->read_status(lpt_device_ps[i]); - return 0; - case 2: - return lpt_ctrls[i]; - } - return 0xff; -} - -void lpt1_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(0, port, val, priv); -} - -uint8_t lpt1_read(uint16_t port, void *priv) -{ - return lpt_read(0, port, priv); -} - -void lpt2_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(1, port, val, priv); -} - -uint8_t lpt2_read(uint16_t port, void *priv) -{ - return lpt_read(1, port, priv); -} - -void lpt3_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(2, port, val, priv); -} - -uint8_t lpt3_read(uint16_t port, void *priv) -{ - return lpt_read(2, port, priv); -} - -uint16_t lpt_addr[3] = { 0x378, 0x278, 0x3bc }; - -void lpt_init(void) -{ - if (lpt_enabled) - { - io_sethandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_sethandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - lpt_addr[0] = 0x378; - lpt_addr[1] = 0x278; - } -} - -void lpt1_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - lpt_addr[0] = port; - } -} -void lpt1_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[0], 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - } -} -void lpt2_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - lpt_addr[1] = port; - } -} -void lpt2_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[1], 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - } -} - -void lpt2_remove_ams(void) -{ - if (lpt_enabled) - { - io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - } -} - -void lpt3_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt3_read, NULL, NULL, lpt3_write, NULL, NULL, NULL); - lpt_addr[2] = port; - } -} -void lpt3_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[2], 0x0003, lpt3_read, NULL, NULL, lpt3_write, NULL, NULL, NULL); - } -} diff --git a/src - Cópia/lpt.h b/src - Cópia/lpt.h deleted file mode 100644 index 7db61930b..000000000 --- a/src - Cópia/lpt.h +++ /dev/null @@ -1,26 +0,0 @@ -extern void lpt_init(); -extern void lpt1_init(uint16_t port); -extern void lpt1_remove(); -extern void lpt2_init(uint16_t port); -extern void lpt2_remove(); -extern void lpt2_remove_ams(); -extern void lpt3_init(uint16_t port); -extern void lpt3_remove(); - -void lpt_devices_init(); -void lpt_devices_close(); - -char *lpt_device_get_name(int id); -char *lpt_device_get_internal_name(int id); - -extern char lpt_device_names[3][16]; - -typedef struct -{ - char name[80]; - void *(*init)(); - void (*close)(void *p); - void (*write_data)(uint8_t val, void *p); - void (*write_ctrl)(uint8_t val, void *p); - uint8_t (*read_status)(void *p); -} lpt_device_t; diff --git a/src - Cópia/machine/m_amstrad.c b/src - Cópia/machine/m_amstrad.c deleted file mode 100644 index 62614afee..000000000 --- a/src - Cópia/machine/m_amstrad.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the Amstrad series of PC's: PC1512, PC1640 and - * PC200, including their keyboard, mouse and video devices, as - * well as the PC2086 and PC3086 systems. - * - * PC1512: The PC1512 extends CGA with a bit-planar 640x200x16 mode. - * Most CRTC registers are fixed. - * - * The Technical Reference Manual lists the video waitstate - * time as between 12 and 46 cycles. We currently always use - * the lower number. - * - * PC1640: Mostly standard EGA, but with CGA & Hercules emulation. - * - * PC200: CGA with some NMI stuff. But we don't need that as it's only - * used for TV and LCD displays, and we're emulating a CRT. - * - * TODO: This module is not complete yet: - * - * PC1512: The BIOS assumes 512K RAM, because I cannot figure out how to - * read the status of the LK4 jumper on the mainboard, which is - * somehow linked to the bus gate array on the NDMACS line... - * - * PC1612: EGA mode does not seem to work in the PC1640; it works fine - * in alpha mode, but in highres ("ECD350") mode, it displays - * some semi-random junk. Video-memory pointer maybe? - * - * Version: @(#)m_amstrad.c 1.0.14 2018/04/29 - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.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_paradise.h" -#include "machine.h" - - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - - -typedef struct { - rom_t bios_rom; /* 1640 */ - cga_t cga; /* 1640/200 */ - ega_t ega; /* 1640 */ - uint8_t crtc[32]; - int crtcreg; - int cga_enabled; /* 1640 */ - uint8_t cgacol, - cgamode, - stat; - uint8_t plane_write, /* 1512/200 */ - plane_read, /* 1512/200 */ - border; /* 1512/200 */ - int linepos, - displine; - int sc, vc; - int cgadispon; - int con, coff, - cursoron, - cgablink; - int64_t vsynctime; - int vadj; - uint16_t ma, maback; - int dispon; - int blink; - int64_t dispontime, /* 1512/1640 */ - dispofftime; /* 1512/1640 */ - int64_t vidtime; /* 1512/1640 */ - int firstline, - lastline; - uint8_t *vram; -} amsvid_t; - -typedef struct { - /* Machine stuff. */ - uint8_t dead; - uint8_t stat1, - stat2; - - /* Keyboard stuff. */ - int8_t wantirq; - uint8_t key_waiting; - uint8_t pa; - uint8_t pb; - - /* Mouse stuff. */ - uint8_t mousex, - mousey; - int oldb; - - /* Video stuff. */ - amsvid_t *vid; -} amstrad_t; - - -static uint8_t key_queue[16]; -static int key_queue_start = 0, - key_queue_end = 0; -static uint8_t crtc_mask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - -#ifdef ENABLE_AMSTRAD_LOG -int amstrad_do_log = ENABLE_AMSTRAD_LOG; -#endif - - -static void -amstrad_log(const char *fmt, ...) -{ -#ifdef ENABLE_AMSTRAD_LOG - va_list ap; - - if (amstrad_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -recalc_timings_1512(amsvid_t *vid) -{ - double _dispontime, _dispofftime, disptime; - - disptime = 128; /*Fixed on PC1512*/ - _dispontime = 80; - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - vid->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - vid->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void -vid_out_1512(uint16_t addr, uint8_t val, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - uint8_t old; - - switch (addr) { - case 0x03d4: - vid->crtcreg = val & 31; - return; - - case 0x03d5: - old = vid->crtc[vid->crtcreg]; - vid->crtc[vid->crtcreg] = val & crtc_mask[vid->crtcreg]; - if (old != val) { - if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { - fullchange = changeframecount; - recalc_timings_1512(vid); - } - } - return; - - case 0x03d8: - if ((val & 0x12) == 0x12 && (vid->cgamode & 0x12) != 0x12) { - vid->plane_write = 0xf; - vid->plane_read = 0; - } - vid->cgamode = val; - return; - - case 0x03d9: - vid->cgacol = val; - return; - - case 0x03dd: - vid->plane_write = val; - return; - - case 0x03de: - vid->plane_read = val & 3; - return; - - case 0x03df: - vid->border = val; - return; - } -} - - -static uint8_t -vid_in_1512(uint16_t addr, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0x03d4: - ret = vid->crtcreg; - - case 0x03d5: - ret = vid->crtc[vid->crtcreg]; - - case 0x03da: - ret = vid->stat; - } - - return(ret); -} - - -static void -vid_write_1512(uint32_t addr, uint8_t val, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - egawrites++; - cycles -= 12; - addr &= 0x3fff; - - if ((vid->cgamode & 0x12) == 0x12) { - if (vid->plane_write & 1) vid->vram[addr] = val; - if (vid->plane_write & 2) vid->vram[addr | 0x4000] = val; - if (vid->plane_write & 4) vid->vram[addr | 0x8000] = val; - if (vid->plane_write & 8) vid->vram[addr | 0xc000] = val; - } else - vid->vram[addr] = val; -} - - -static uint8_t -vid_read_1512(uint32_t addr, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - egareads++; - cycles -= 12; - addr &= 0x3fff; - - if ((vid->cgamode & 0x12) == 0x12) - return(vid->vram[addr | (vid->plane_read << 14)]); - - return(vid->vram[addr]); -} - - -static void -vid_poll_1512(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - uint8_t chr, attr; - uint16_t dat, dat2, dat3, dat4; - int cols[4]; - int col; - int oldsc; - - if (! vid->linepos) { - vid->vidtime += vid->dispofftime; - vid->stat |= 1; - vid->linepos = 1; - oldsc = vid->sc; - if (vid->dispon) { - if (vid->displine < vid->firstline) { - vid->firstline = vid->displine; - video_wait_for_buffer(); - } - vid->lastline = vid->displine; - for (c = 0; c < 8; c++) { - if ((vid->cgamode & 0x12) == 0x12) { - buffer->line[vid->displine][c] = (vid->border & 15) + 16; - if (vid->cgamode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = 0; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = 0; - } else { - buffer->line[vid->displine][c] = (vid->cgacol & 15) + 16; - if (vid->cgamode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = (vid->cgacol & 15) + 16; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = (vid->cgacol & 15) + 16; - } - } - if (vid->cgamode & 1) { - for (x = 0; x < 80; x++) { - chr = vid->vram[ ((vid->ma << 1) & 0x3fff)]; - attr = vid->vram[(((vid->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - vid->ma++; - } - } else if (! (vid->cgamode & 2)) { - for (x = 0; x < 40; x++) { - chr = vid->vram[((vid->ma << 1) & 0x3fff)]; - attr = vid->vram[(((vid->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((vid->blink & 16) && (attr & 0x80)) - cols[1] = cols[0]; - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - vid->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } else if (! (vid->cgamode & 16)) { - cols[0] = (vid->cgacol & 15) | 16; - col = (vid->cgacol & 16) ? 24 : 16; - if (vid->cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (vid->cgacol & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < 40; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - for (x = 0; x < 40; x++) { - ca = ((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000); - dat = (vid->vram[ca] << 8) | vid->vram[ca + 1]; - dat2 = (vid->vram[ca + 0x4000] << 8) | vid->vram[ca + 0x4001]; - dat3 = (vid->vram[ca + 0x8000] << 8) | vid->vram[ca + 0x8001]; - dat4 = (vid->vram[ca + 0xc000] << 8) | vid->vram[ca + 0xc001]; - - vid->ma++; - for (c = 0; c < 16; c++) { - buffer->line[vid->displine][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (vid->cgacol & 15)) + 16; - dat <<= 1; - dat2 <<= 1; - dat3 <<= 1; - dat4 <<= 1; - } - } - } - } else { - cols[0] = ((vid->cgamode & 0x12) == 0x12) ? 0 : (vid->cgacol & 15) + 16; - if (vid->cgamode & 1) - hline(buffer, 0, vid->displine, (vid->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer, 0, vid->displine, (vid->crtc[1] << 4) + 16, cols[0]); - } - - vid->sc = oldsc; - if (vid->vsynctime) - vid->stat |= 8; - vid->displine++; - if (vid->displine >= 360) - vid->displine = 0; - } else { - vid->vidtime += vid->dispontime; - if ((vid->lastline - vid->firstline) == 199) - vid->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ - if (vid->dispon) - vid->stat &= ~1; - vid->linepos = 0; - if (vid->vsynctime) { - vid->vsynctime--; - if (! vid->vsynctime) - vid->stat &= ~8; - } - if (vid->sc == (vid->crtc[11] & 31)) { - vid->con = 0; - vid->coff = 1; - } - if (vid->vadj) { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - vid->vadj--; - if (! vid->vadj) { - vid->dispon = 1; - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - vid->sc = 0; - } - } else if (vid->sc == vid->crtc[9]) { - vid->maback = vid->ma; - vid->sc = 0; - vid->vc++; - vid->vc &= 127; - - if (vid->displine == 32) { - vid->vc = 0; - vid->vadj = 6; - if ((vid->crtc[10] & 0x60) == 0x20) - vid->cursoron = 0; - else - vid->cursoron = vid->blink & 16; - } - - if (vid->displine >= 262) { - vid->dispon = 0; - vid->displine = 0; - vid->vsynctime = 46; - - if (vid->cgamode&1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - vid->lastline++; - - if ((x != xsize) || ((vid->lastline - vid->firstline) != ysize) || video_force_resize_get()) { - xsize = x; - ysize = vid->lastline - vid->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - video_blit_memtoscreen_8(0, vid->firstline - 4, 0, (vid->lastline - vid->firstline) + 8, xsize, (vid->lastline - vid->firstline) + 8); - - video_res_x = xsize - 16; - video_res_y = ysize; - if (vid->cgamode & 1) { - video_res_x /= 8; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 4; - } - - vid->firstline = 1000; - vid->lastline = 0; - vid->blink++; - } - } else { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - } - if (vid->sc == (vid->crtc[10] & 31)) - vid->con = 1; - } -} - - -static void -vid_init_1512(amstrad_t *ams) -{ - amsvid_t *vid; - - /* Allocate a video controller block. */ - vid = (amsvid_t *)malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); - - vid->vram = malloc(0x10000); - vid->cgacol = 7; - vid->cgamode = 0x12; - - timer_add(vid_poll_1512, &vid->vidtime, TIMER_ALWAYS_ENABLED, vid); - mem_mapping_add(&vid->cga.mapping, 0xb8000, 0x08000, - vid_read_1512, NULL, NULL, vid_write_1512, NULL, NULL, - NULL, 0, vid); - io_sethandler(0x03d0, 16, - vid_in_1512, NULL, NULL, vid_out_1512, NULL, NULL, vid); - - overscan_x = overscan_y = 16; - - ams->vid = vid; -} - - -static void -vid_close_1512(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - free(vid->vram); - - free(vid); -} - - -static void -vid_speed_change_1512(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - recalc_timings_1512(vid); -} - - -static const device_t vid_1512_device = { - "Amstrad PC1512 (video)", - 0, 0, - NULL, vid_close_1512, NULL, - NULL, - vid_speed_change_1512, - NULL -}; - - -static void -recalc_timings_1640(amsvid_t *vid) -{ - cga_recalctimings(&vid->cga); - ega_recalctimings(&vid->ega); - - if (vid->cga_enabled) { - overscan_x = overscan_y = 16; - - vid->dispontime = vid->cga.dispontime; - vid->dispofftime = vid->cga.dispofftime; - } else { - overscan_x = 16; overscan_y = 28; - - vid->dispontime = vid->ega.dispontime; - vid->dispofftime = vid->ega.dispofftime; - } -} - - -static void -vid_out_1640(uint16_t addr, uint8_t val, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - switch (addr) { - case 0x03db: - vid->cga_enabled = val & 0x40; - if (vid->cga_enabled) { - mem_mapping_enable(&vid->cga.mapping); - mem_mapping_disable(&vid->ega.mapping); - } else { - mem_mapping_disable(&vid->cga.mapping); - switch (vid->ega.gdcreg[6] & 0xc) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&vid->ega.mapping, - 0xa0000, 0x20000); - break; - - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&vid->ega.mapping, - 0xa0000, 0x10000); - break; - - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&vid->ega.mapping, - 0xb0000, 0x08000); - break; - - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&vid->ega.mapping, - 0xb8000, 0x08000); - break; - } - } - return; - } - - if (vid->cga_enabled) - cga_out(addr, val, &vid->cga); - else - ega_out(addr, val, &vid->ega); -} - - -static uint8_t -vid_in_1640(uint16_t addr, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - switch (addr) { - } - - if (vid->cga_enabled) - return(cga_in(addr, &vid->cga)); - else - return(ega_in(addr, &vid->ega)); -} - - -static void -vid_poll_1640(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - if (vid->cga_enabled) { - overscan_x = overscan_y = 16; - - vid->cga.vidtime = vid->vidtime; - cga_poll(&vid->cga); - vid->vidtime = vid->cga.vidtime; - } else { - overscan_x = 16; overscan_y = 28; - - vid->ega.vidtime = vid->vidtime; - ega_poll(&vid->ega); - vid->vidtime = vid->ega.vidtime; - } -} - - -static void -vid_init_1640(amstrad_t *ams) -{ - amsvid_t *vid; - - /* Allocate a video controller block. */ - vid = (amsvid_t *)malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); - - rom_init(&vid->bios_rom, L"roms/machines/pc1640/40100", - 0xc0000, 0x8000, 0x7fff, 0, 0); - - ega_init(&vid->ega, 9, 0); - vid->cga.vram = vid->ega.vram; - vid->cga_enabled = 1; - cga_init(&vid->cga); - - mem_mapping_add(&vid->cga.mapping, 0xb8000, 0x08000, - cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, &vid->cga); - mem_mapping_add(&vid->ega.mapping, 0, 0, - ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, &vid->ega); - io_sethandler(0x03a0, 64, - vid_in_1640, NULL, NULL, vid_out_1640, NULL, NULL, vid); - - timer_add(vid_poll_1640, &vid->vidtime, TIMER_ALWAYS_ENABLED, vid); - - overscan_x = overscan_y = 16; - - ams->vid = vid; -} - - -static void -vid_close_1640(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - free(vid->ega.vram); - - free(vid); -} - - -static void -vid_speed_changed_1640(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - recalc_timings_1640(vid); -} - - -static const device_t vid_1640_device = { - "Amstrad PC1640 (video)", - 0, 0, - NULL, vid_close_1640, NULL, - NULL, - vid_speed_changed_1640, - NULL -}; - - -static void -vid_out_200(uint16_t addr, uint8_t val, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - cga_t *cga = &vid->cga; - uint8_t old; - - switch (addr) { - case 0x03d5: - if (!(vid->plane_read & 0x40) && cga->crtcreg <= 11) { - if (vid->plane_read & 0x80) - nmi = 1; - - vid->plane_write = 0x20 | (cga->crtcreg & 0x1f); - vid->border = val; - return; - } - old = cga->crtc[cga->crtcreg]; - cga->crtc[cga->crtcreg] = val & crtc_mask[cga->crtcreg]; - if (old != val) { - if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange = changeframecount; - cga_recalctimings(cga); - } - } - return; - - case 0x03d8: - old = cga->cgamode; - cga->cgamode = val; - if ((cga->cgamode ^ old) & 3) - cga_recalctimings(cga); - vid->plane_write |= 0x80; - if (vid->plane_read & 0x80) - nmi = 1; - return; - - case 0x03de: - vid->plane_read = val; - vid->plane_write = 0x1f; - if (val & 0x80) - vid->plane_write |= 0x40; - return; - } - - cga_out(addr, val, cga); -} - - -static uint8_t -vid_in_200(uint16_t addr, void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - cga_t *cga = &vid->cga; - uint8_t ret; - - switch (addr) { - case 0x03d8: - return(cga->cgamode); - - case 0x03dd: - ret = vid->plane_write; - vid->plane_write &= 0x1f; - nmi = 0; - return(ret); - - case 0x03de: - return((vid->plane_read & 0xc7) | 0x10); /*External CGA*/ - - case 0x03df: - return(vid->border); - } - - return(cga_in(addr, cga)); -} - - -static void -vid_init_200(amstrad_t *ams) -{ - amsvid_t *vid; - cga_t *cga; - - /* Allocate a video controller block. */ - vid = (amsvid_t *)malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); - - cga = &vid->cga; - cga->vram = malloc(0x4000); - cga_init(cga); - - mem_mapping_add(&vid->cga.mapping, 0xb8000, 0x08000, - cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); - io_sethandler(0x03d0, 16, - vid_in_200, NULL, NULL, vid_out_200, NULL, NULL, vid); - - timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - - overscan_x = overscan_y = 16; - - ams->vid = vid; -} - - -static void -vid_close_200(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - free(vid->cga.vram); - - free(vid); -} - - -static void -vid_speed_changed_200(void *priv) -{ - amsvid_t *vid = (amsvid_t *)priv; - - cga_recalctimings(&vid->cga); -} - - -static const device_t vid_200_device = { - "Amstrad PC200 (video)", - 0, 0, - NULL, vid_close_200, NULL, - NULL, - vid_speed_changed_200, - NULL -}; - - -static void -ms_write(uint16_t addr, uint8_t val, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - if (addr == 0x78) - ams->mousex = 0; - else - ams->mousey = 0; -} - - -static uint8_t -ms_read(uint16_t addr, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - if (addr == 0x78) - return(ams->mousex); - - return(ams->mousey); -} - - -static int -ms_poll(int x, int y, int z, int b, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - ams->mousex += x; - ams->mousey -= y; - - if ((b & 1) && !(ams->oldb & 1)) - keyboard_send(0x7e); - if ((b & 2) && !(ams->oldb & 2)) - keyboard_send(0x7d); - if (!(b & 1) && (ams->oldb & 1)) - keyboard_send(0xfe); - if (!(b & 2) && (ams->oldb & 2)) - keyboard_send(0xfd); - - ams->oldb = b; - - return(0); -} - - -static void -kbd_adddata(uint16_t val) -{ - key_queue[key_queue_end] = val; - amstrad_log("keyboard_amstrad : %02X added to key queue at %i\n", - val, key_queue_end); - key_queue_end = (key_queue_end + 1) & 0xf; -} - - -static void -kbd_adddata_ex(uint16_t val) -{ - kbd_adddata_process(val, kbd_adddata); -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - amstrad_log("keyboard_amstrad : write %04X %02X %02X\n", port, val, ams->pb); - - switch (port) { - case 0x61: - /* - * PortB - System Control. - * - * 7 Enable Status-1/Disable Keyboard Code on Port A. - * 6 Enable incoming Keyboard Clock. - * 5 Prevent external parity errors from causing NMI. - * 4 Disable parity checking of on-board system Ram. - * 3 Undefined (Not Connected). - * 2 Enable Port C LSB / Disable MSB. (See 1.8.3) - * 1 Speaker Drive. - * 0 8253 GATE 2 (Speaker Modulate). - * - * This register is controlled by BIOS and/or ROS. - */ - amstrad_log("AMSkb: write PB %02x (%02x)\n", val, ams->pb); - if (!(ams->pb & 0x40) && (val & 0x40)) { /*Reset keyboard*/ - amstrad_log("AMSkb: reset keyboard\n"); - kbd_adddata(0xaa); - } - ams->pb = val; - ppi.pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 0x01; - speaker_enable = val & 0x02; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 0x01); - - if (val & 0x80) { - /* Keyboard enabled, so enable PA reading. */ - ams->pa = 0x00; - } - break; - - case 0x63: - break; - - case 0x64: - ams->stat1 = val; - break; - - case 0x65: - ams->stat2 = val; - break; - - case 0x66: - pc_reset(1); - break; - - default: - amstrad_log("AMSkb: bad keyboard write %04X %02X\n", port, val); - } -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x60: - if (ams->pb & 0x80) { - /* - * PortA - System Status 1 - * - * 7 Always 0 (KBD7) - * 6 Second Floppy disk drive installed (KBD6) - * 5 DDM1 - Default Display Mode bit 1 (KBD5) - * 4 DDM0 - Default Display Mode bit 0 (KBD4) - * 3 Always 1 (KBD3) - * 2 Always 1 (KBD2) - * 1 8087 NDP installed (KBD1) - * 0 Always 1 (KBD0) - * - * DDM00 - * 00 unknown, external color? - * 01 Color,alpha,40x25, bright white on black. - * 10 Color,alpha,80x25, bright white on black. - * 11 External Monochrome,80x25. - * - * Following a reset, the hardware selects VDU mode - * 2. The ROS then sets the initial VDU state based - * on the DDM value. - */ - ret = (0x0d | ams->stat1) & 0x7f; - } else { - ret = ams->pa; - if (key_queue_start == key_queue_end) { - ams->wantirq = 0; - } else { - ams->key_waiting = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - ams->wantirq = 1; - } - } - break; - - case 0x61: - ret = ams->pb; - break; - - case 0x62: - /* - * PortC - System Status 2. - * - * 7 On-board system RAM parity error. - * 6 External parity error (I/OCHCK from expansion bus). - * 5 8253 PIT OUT2 output. - * 4 Undefined (Not Connected). - *------------------------------------------- - * LSB MSB (depends on PB2) - *------------------------------------------- - * 3 RAM3 Undefined - * 2 RAM2 Undefined - * 1 RAM1 Undefined - * 0 RAM0 RAM4 - * - * PC7 is forced to 0 when on-board system RAM parity - * checking is disabled by PB4. - * - * RAM4:0 - * 01110 512K bytes on-board. - * 01111 544K bytes (32K external). - * 10000 576K bytes (64K external). - * 10001 608K bytes (96K external). - * 10010 640K bytes (128K external or fitted on-board). - */ - if (ams->pb & 0x04) - ret = ams->stat2 & 0x0f; - else - ret = ams->stat2 >> 4; - ret |= (ppispeakon ? 0x20 : 0); - if (nmi) - ret |= 0x40; - break; - - default: - amstrad_log("AMDkb: bad keyboard read %04X\n", port); - } - - return(ret); -} - - -static void -kbd_poll(void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - keyboard_delay += (1000 * TIMER_USEC); - - if (ams->wantirq) { - ams->wantirq = 0; - ams->pa = ams->key_waiting; - picint(2); - amstrad_log("keyboard_amstrad : take IRQ\n"); - } - - if (key_queue_start != key_queue_end && !ams->pa) { - ams->key_waiting = key_queue[key_queue_start]; - amstrad_log("Reading %02X from the key queue at %i\n", - ams->key_waiting, key_queue_start); - key_queue_start = (key_queue_start + 1) & 0xf; - ams->wantirq = 1; - } -} - - -static void -ams_write(uint16_t port, uint8_t val, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - - switch (port) { - case 0xdead: - ams->dead = val; - break; - } -} - - -static uint8_t -ams_read(uint16_t port, void *priv) -{ - amstrad_t *ams = (amstrad_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x0379: /* printer control, also set LK1-3. - * 0 English Language. - * 1 German Language. - * 2 French Language. - * 3 Spanish Language. - * 4 Danish Language. - * 5 Swedish Language. - * 6 Italian Language. - * 7 Diagnostic Mode. - */ - ret = 0x02; /* ENGLISH. no Diags mode */ - break; - - case 0x037a: /* printer status */ - switch(romset) { - case ROM_PC1512: - ret = 0x20; - break; - - case ROM_PC200: - ret = 0x80; - break; - - default: - ret = 0x00; - } - break; - - case 0xdead: - ret = ams->dead; - break; - } - - return(ret); -} - - -void -machine_amstrad_init(const machine_t *model) -{ - amstrad_t *ams; - - ams = (amstrad_t *)malloc(sizeof(amstrad_t)); - memset(ams, 0x00, sizeof(amstrad_t)); - - device_add(&amstrad_nvr_device); - - machine_common_init(model); - - nmi_init(); - - lpt2_remove_ams(); - - io_sethandler(0x0379, 2, - ams_read, NULL, NULL, NULL, NULL, NULL, ams); - - io_sethandler(0xdead, 1, - ams_read, NULL, NULL, ams_write, NULL, NULL, ams); - - io_sethandler(0x0078, 1, - ms_read, NULL, NULL, ms_write, NULL, NULL, ams); - - io_sethandler(0x007a, 1, - ms_read, NULL, NULL, ms_write, NULL, NULL, ams); - -// device_add(&fdc_at_actlow_device); - - switch(romset) { - case ROM_PC1512: - device_add(&fdc_xt_device); - break; - - case ROM_PC1640: - device_add(&fdc_xt_device); - break; - - case ROM_PC200: - device_add(&fdc_xt_device); - break; - - case ROM_PC2086: - device_add(&fdc_at_actlow_device); - break; - - case ROM_PC3086: - device_add(&fdc_at_actlow_device); - break; - - case ROM_MEGAPC: - device_add(&fdc_at_actlow_device); - break; - } - - if (gfxcard == GFX_INTERNAL) switch(romset) { - case ROM_PC1512: - loadfont(L"roms/machines/pc1512/40078", 2); - vid_init_1512(ams); - device_add_ex(&vid_1512_device, ams->vid); - break; - - case ROM_PC1640: - vid_init_1640(ams); - device_add_ex(&vid_1640_device, ams->vid); - break; - - case ROM_PC200: - loadfont(L"roms/machines/pc200/40109.bin", 1); - vid_init_200(ams); - device_add_ex(&vid_200_device, ams->vid); - break; - - case ROM_PC2086: - device_add(¶dise_pvga1a_pc2086_device); - break; - - case ROM_PC3086: - device_add(¶dise_pvga1a_pc3086_device); - break; - - case ROM_MEGAPC: - device_add(¶dise_wd90c11_megapc_device); - break; - } - - /* Initialize the (custom) keyboard/mouse interface. */ - ams->wantirq = 0; - io_sethandler(0x0060, 7, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, ams); - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, ams); - keyboard_set_table(scancode_xt); - keyboard_send = kbd_adddata_ex; - keyboard_scan = 1; - - /* Tell mouse driver about our internal mouse. */ - mouse_reset(); - mouse_set_poll(ms_poll, ams); - - if (joystick_type != 7) - device_add(&gameport_device); -} diff --git a/src - Cópia/machine/m_at.c b/src - Cópia/machine/m_at.c deleted file mode 100644 index d4bf80adb..000000000 --- a/src - Cópia/machine/m_at.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include "../86box.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 "../disk/hdc.h" -#include "machine.h" - - -void -machine_at_common_init(const machine_t *model) -{ - machine_common_init(model); - - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - pic2_init(); - dma16_init(); - - if (lpt_enabled) - lpt2_remove(); - - device_add(&at_nvr_device); - - if (joystick_type != 7) - device_add(&gameport_device); -} - - -void -machine_at_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&keyboard_at_device); -} - - -void -machine_at_ps2_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&keyboard_ps2_device); -} - - -void -machine_at_common_ide_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&ide_isa_2ch_opt_device); -} - - -void -machine_at_ide_init(const machine_t *model) -{ - machine_at_init(model); - - device_add(&ide_isa_2ch_opt_device); -} - - -void -machine_at_ps2_ide_init(const machine_t *model) -{ - machine_at_ps2_init(model); - - device_add(&ide_isa_2ch_opt_device); -} - - -void -machine_at_top_remap_init(const machine_t *model) -{ - machine_at_init(model); - - mem_remap_top_384k(); -} - - -void -machine_at_ide_top_remap_init(const machine_t *model) -{ - machine_at_ide_init(model); - - mem_remap_top_384k(); -} - - -void -machine_at_ibm_init(const machine_t *model) -{ - machine_at_top_remap_init(model); - - device_add(&fdc_at_device); -} diff --git a/src - Cópia/machine/m_at_4x0.c b/src - Cópia/machine/m_at_4x0.c deleted file mode 100644 index 29833ab99..000000000 --- a/src - Cópia/machine/m_at_4x0.c +++ /dev/null @@ -1,919 +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. - * - * Implementation of the Intel PCISet chips from 430LX to 440FX. - * - * Version: @(#)m_at_430lx_nx.c 1.0.0 2018/05/09 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "../memregs.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../intel.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 "machine.h" - - -enum -{ - INTEL_430LX, - INTEL_430NX, - INTEL_430FX, - INTEL_430HX, -#if defined(DEV_BRANCH) && defined(USE_I686) - INTEL_430VX, - INTEL_440FX -#else - INTEL_430VX -#endif -}; - -typedef struct -{ - uint8_t regs[256]; - int type; -} i4x0_t; - - -typedef struct -{ - int index; -} acerm3a_t; - - -static void -i4x0_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | 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; - - 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 (romset == ROM_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 (romset == ROM_PB640) - val |= 0x20; - } - 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); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t -i4x0_read(int func, int addr, void *priv) -{ - i4x0_t *dev = (i4x0_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i4x0_reset(void *priv) -{ - i4x0_t *i4x0 = (i4x0_t *)priv; - - i4x0_write(0, 0x59, 0x00, priv); - if (i4x0->type >= INTEL_430FX) - i4x0_write(0, 0x72, 0x02, priv); -} - - -static void -i4x0_close(void *p) -{ - i4x0_t *i4x0 = (i4x0_t *)p; - - free(i4x0); -} - - -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_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: - i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/ - if (romset == ROM_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[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; -#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) && (romset != ROM_PB640)) - 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; - - pci_add_card(0, i4x0_read, i4x0_write, i4x0); - - return i4x0; -} - - -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 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 -}; - - -#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 - - -static void -acerm3a_out(uint16_t port, uint8_t val, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xea) - dev->index = val; -} - - -static uint8_t -acerm3a_in(uint16_t port, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xeb) { - switch (dev->index) { - case 2: - return 0xfd; - } - } - return 0xff; -} - - -static void -acerm3a_close(void *p) -{ - acerm3a_t *dev = (acerm3a_t *)p; - - free(dev); -} - - -static void -*acerm3a_init(const device_t *info) -{ - acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t)); - memset(acerm3a, 0, sizeof(acerm3a_t)); - - io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a); - - return acerm3a; -} - - -const device_t acerm3a_device = -{ - "Acer M3A Register", - 0, - 0, - acerm3a_init, - acerm3a_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; - - -static void -machine_at_premiere_common_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&ide_pci_2ch_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_2); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&sio_device); - fdc37c665_init(); - intel_batman_init(); - - device_add(&intel_flash_bxt_ami_device); -} - - -void -machine_at_batman_init(const machine_t *model) -{ - machine_at_premiere_common_init(model); - - device_add(&i430lx_device); -} - - -void -machine_at_plato_init(const machine_t *model) -{ - machine_at_premiere_common_init(model); - - device_add(&i430nx_device); -} - - -void -machine_at_p54tp4xe_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_endeavor_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); - - if (gfxcard == GFX_INTERNAL) - device_add(&s3_phoenix_trio64_onboard_pci_device); -} - - -const device_t * -at_endeavor_get_device(void) -{ - return &s3_phoenix_trio64_onboard_pci_device; -} - - -void -machine_at_zappa_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); -} - - -void -machine_at_mb500n_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_president_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_thor_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); -} - - -void -machine_at_pb640_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430fx_device); - device_add(&piix_pb640_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); - - if (gfxcard == GFX_INTERNAL) - device_add(&gd5440_onboard_pci_device); -} - - -const device_t * -at_pb640_get_device(void) -{ - return &gd5440_onboard_pci_device; -} - - -void -machine_at_acerm3a_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - powermate_memregs_init(); - 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(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); - pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - device_add(&acerm3a_device); - - device_add(&intel_flash_bxb_device); -} - - -void -machine_at_acerv35n_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - powermate_memregs_init(); - 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(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(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - device_add(&acerm3a_device); - - device_add(&intel_flash_bxb_device); -} - - -void -machine_at_ap53_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c669_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55t2p4_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430hx_device); - device_add(&piix3_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55t2s_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430hx_device); - device_add(&piix3_device); - pc87306_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55tvp4_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430vx_device); - device_add(&piix3_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_i430vx_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430vx_device); - device_add(&piix3_device); - um8669f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55va_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i430vx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - - device_add(&intel_flash_bxt_device); -} - - -#if defined(DEV_BRANCH) && defined(USE_I686) -void -machine_at_i440fx_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 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); - device_add(&i440fx_device); - device_add(&piix3_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_s1668_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - 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(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(&i440fx_device); - device_add(&piix3_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} -#endif diff --git a/src - Cópia/machine/m_at_ali1429.c b/src - Cópia/machine/m_at_ali1429.c deleted file mode 100644 index a0dc3ddf0..000000000 --- a/src - Cópia/machine/m_at_ali1429.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.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 "machine.h" - - -static int ali1429_index; -static uint8_t ali1429_regs[256]; - - -static void ali1429_recalc(void) -{ - int c; - - for (c = 0; c < 8; c++) - { - uint32_t base = 0xc0000 + (c << 15); - if (ali1429_regs[0x13] & (1 << c)) - { - switch (ali1429_regs[0x14] & 3) - { - case 0: - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - } - else - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - - flushmmucache(); -} - -void ali1429_write(uint16_t port, uint8_t val, void *priv) -{ - if (!(port & 1)) - ali1429_index = val; - else - { - ali1429_regs[ali1429_index] = val; - switch (ali1429_index) - { - case 0x13: - ali1429_recalc(); - break; - case 0x14: - shadowbios = val & 1; - shadowbios_write = val & 2; - ali1429_recalc(); - break; - } - } -} - -uint8_t ali1429_read(uint16_t port, void *priv) -{ - if (!(port & 1)) - return ali1429_index; - if ((ali1429_index >= 0xc0 || ali1429_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return ali1429_regs[ali1429_index]; -} - - -static void ali1429_reset(void) -{ - memset(ali1429_regs, 0xff, 256); -} - - -static void ali1429_init(void) -{ - io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL); -} - - -void -machine_at_ali1429_init(const machine_t *model) -{ - ali1429_reset(); - - machine_at_common_ide_init(model); - - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); - - ali1429_init(); - - secondary_ide_check(); -} diff --git a/src - Cópia/machine/m_at_commodore.c b/src - Cópia/machine/m_at_commodore.c deleted file mode 100644 index e12e13970..000000000 --- a/src - Cópia/machine/m_at_commodore.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../lpt.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "machine.h" - - -static void cbm_io_write(uint16_t port, uint8_t val, void *p) -{ - lpt1_remove(); - lpt2_remove(); - switch (val & 3) - { - case 1: - lpt1_init(0x3bc); - break; - case 2: - lpt1_init(0x378); - break; - case 3: - lpt1_init(0x278); - break; - } - switch (val & 0xc) - { - case 0x4: - serial_setup(1, 0x2f8, 3); - break; - case 0x8: - serial_setup(1, 0x3f8, 4); - break; - } -} - -static void cbm_io_init() -{ - io_sethandler(0x0230, 0x0001, NULL,NULL,NULL, cbm_io_write,NULL,NULL, NULL); -} - - -void -machine_at_cmdpc_init(const machine_t *model) -{ - machine_at_ide_top_remap_init(model); - device_add(&fdc_at_device); - - cbm_io_init(); -} diff --git a/src - Cópia/machine/m_at_compaq.c b/src - Cópia/machine/m_at_compaq.c deleted file mode 100644 index 9497a8498..000000000 --- a/src - Cópia/machine/m_at_compaq.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of various Compaq PC's. - * - * Version: @(#)m_at_compaq.c 1.0.5 2018/03/18 - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.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 "machine.h" - - -/* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */ -static mem_mapping_t ram_mapping; - - -static uint8_t -read_ram(uint32_t addr, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - - return(ram[addr]); -} - - -static uint16_t -read_ramw(uint32_t addr, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - - return(*(uint16_t *)&ram[addr]); -} - - -static uint32_t -read_raml(uint32_t addr, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - - return(*(uint32_t *)&ram[addr]); -} - - -static void -write_ram(uint32_t addr, uint8_t val, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addwritelookup(mem_logical_addr, addr); - - mem_write_ramb_page(addr, val, &pages[addr >> 12]); -} - - -static void -write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addwritelookup(mem_logical_addr, addr); - - mem_write_ramw_page(addr, val, &pages[addr >> 12]); -} - - -static void -write_raml(uint32_t addr, uint32_t val, void *priv) -{ - addr = (addr & 0x7ffff) + 0x80000; - addwritelookup(mem_logical_addr, addr); - - mem_write_raml_page(addr, val, &pages[addr >> 12]); -} - - -void -machine_at_compaq_init(const machine_t *model) -{ - machine_at_top_remap_init(model); - device_add(&fdc_at_device); - - mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, - read_ram, read_ramw, read_raml, - write_ram, write_ramw, write_raml, - 0xa0000+ram, MEM_MAPPING_INTERNAL, NULL); - - switch(model->id) { -#ifdef PORTABLE3 - case ROM_DESKPRO_386: - if (hdc_current == 1) - device_add(&ide_isa_device); - break; -#endif - - case ROM_PORTABLE: - break; - - case ROM_PORTABLEII: - break; - -#ifdef PORTABLE3 - case ROM_PORTABLEIII: - machine_olim24_video_init(); - break; - - case ROM_PORTABLEIII386: - machine_olim24_video_init(); - if (hdc_current == 1) - device_add(&ide_isa_device); - break; -#endif - } -} diff --git a/src - Cópia/machine/m_at_headland.c b/src - Cópia/machine/m_at_headland.c deleted file mode 100644 index b8f707d4e..000000000 --- a/src - Cópia/machine/m_at_headland.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "machine.h" - - -static int headland_index; -static uint8_t headland_regs[256]; - - -static void headland_write(uint16_t addr, uint8_t val, void *priv) -{ - uint8_t old_val; - - if (addr & 1) - { - old_val = headland_regs[headland_index]; - - if (headland_index == 0xc1 && !is486) val = 0; - headland_regs[headland_index] = val; - if (headland_index == 0x82) - { - shadowbios = val & 0x10; - shadowbios_write = !(val & 0x10); - if (shadowbios) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - } - else if (headland_index == 0x87) - { - if ((val & 1) && !(old_val & 1)) - softresetx86(); - } - } - else - headland_index = val; -} - - -static uint8_t headland_read(uint16_t addr, void *priv) -{ - if (addr & 1) - { - if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return headland_regs[headland_index]; - } - return headland_index; -} - - -static void headland_init(void) -{ - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); -} - - -void -machine_at_headland_init(const machine_t *model) -{ - machine_at_common_ide_init(model); - - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); - - headland_init(); -} diff --git a/src - Cópia/machine/m_at_neat.c b/src - Cópia/machine/m_at_neat.c deleted file mode 100644 index 2f789b3a1..000000000 --- a/src - Cópia/machine/m_at_neat.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -/*This is the chipset used in the AMI 286 clone model*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../keyboard.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "machine.h" - - -static uint8_t neat_regs[256]; -static int neat_index; -static int neat_emspage[4]; - - -static void neat_write(uint16_t port, uint8_t val, void *priv) -{ - switch (port) - { - case 0x22: - neat_index = val; - break; - - case 0x23: - neat_regs[neat_index] = val; - switch (neat_index) - { - case 0x6E: /*EMS page extension*/ - neat_emspage[3] = (neat_emspage[3] & 0x7F) | (( val & 3) << 7); - neat_emspage[2] = (neat_emspage[2] & 0x7F) | (((val >> 2) & 3) << 7); - neat_emspage[1] = (neat_emspage[1] & 0x7F) | (((val >> 4) & 3) << 7); - neat_emspage[0] = (neat_emspage[0] & 0x7F) | (((val >> 6) & 3) << 7); - break; - } - break; - - case 0x0208: case 0x0209: case 0x4208: case 0x4209: - case 0x8208: case 0x8209: case 0xC208: case 0xC209: - neat_emspage[port >> 14] = (neat_emspage[port >> 14] & 0x180) | (val & 0x7F); - break; - } -} - - -static uint8_t neat_read(uint16_t port, void *priv) -{ - switch (port) - { - case 0x22: - return neat_index; - - case 0x23: - return neat_regs[neat_index]; - } - return 0xff; -} - - -#if NOT_USED -static void neat_writeems(uint32_t addr, uint8_t val) -{ - ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; -} - - -static uint8_t neat_readems(uint32_t addr) -{ - return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; -} -#endif - - -static void neat_init(void) -{ - io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); -} - - -void -machine_at_neat_init(const machine_t *model) -{ - machine_at_init(model); - device_add(&fdc_at_device); - - neat_init(); -} - - -void -machine_at_neat_ami_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); - - neat_init(); -} diff --git a/src - Cópia/machine/m_at_opti495.c b/src - Cópia/machine/m_at_opti495.c deleted file mode 100644 index d38e47066..000000000 --- a/src - Cópia/machine/m_at_opti495.c +++ /dev/null @@ -1,347 +0,0 @@ -/*OPTi 82C495 emulation - This is the chipset used in the AMI386 model - - Details for the chipset from Ralph Brown's interrupt list - This describes the OPTi 82C493, the 82C495 seems similar except there is one - more register (2C) - -----------P00220024-------------------------- -PORT 0022-0024 - OPTi 82C493 System Controller (SYSC) - CONFIGURATION REGISTERS -Desc: The OPTi 486SXWB contains three chips and is designed for systems - running at 20, 25 and 33MHz. The chipset includes an 82C493 System - Controller (SYSC), the 82C392 Data Buffer Controller, and the - 82C206 Integrated peripheral Controller (IPC). -Note: every access to PORT 0024h must be preceded by a write to PORT 0022h, - even if the same register is being accessed a second time -SeeAlso: PORT 0022h"82C206" - -0022 ?W configuration register index (see #P0178) -0024 RW configuration register data - -(Table P0178) -Values for OPTi 82C493 System Controller configuration register index: - 20h Control Register 1 (see #P0179) - 21h Control Register 2 (see #P0180) - 22h Shadow RAM Control Register 1 (see #P0181) - 23h Shadow RAM Control Register 2 (see #P0182) - 24h DRAM Control Register 1 (see #P0183) - 25h DRAM Control Register 2 (see #P0184) - 26h Shadow RAM Control Register 3 (see #P0185) - 27h Control Register 3 (see #P0186) - 28h Non-cachable Block 1 Register 1 (see #P0187) - 29h Non-cachable Block 1 Register 2 (see #P0188) - 2Ah Non-cachable Block 2 Register 1 (see #P0187) - 2Bh Non-cachable Block 2 Register 2 (see #P0188) - -Bitfields for OPTi-82C493 Control Register 1: -Bit(s) Description (Table P0179) - 7-6 Revision of 82C493 (readonly) (default=01) - 5 Burst wait state control - 1 = Secondary cache read hit cycle is 3-2-2-2 or 2-2-2-2 - 0 = Secondary cache read hit cycle is 3-1-1-1 or 2-1-1-1 (default) - (if bit 5 is set to 1, bit 4 must be set to 0) - 4 Cache memory data buffer output enable control - 0 = disable (default) - 1 = enable - (must be disabled for frequency <= 33Mhz) - 3 Single Address Latch Enable (ALE) - 0 = disable (default) - 1 = enable - (if enabled, SYSC will activate single ALE rather than multiples - during bus conversion cycles) - 2 enable Extra AT Cycle Wait State (default is 0 = disabled) - 1 Emulation keyboard Reset Control - 0 = disable (default) - 1 = enable - Note: This bit must be enabled in BIOS default value; enabling this - bit requires HALT instruction to be executed before SYSC - generates processor reset (CPURST) - 0 enable Alternative Fast Reset (default is 0 = disabled) -SeeAlso: #P0180,#P0186 - -Bitfields for OPTi-82C493 Control Register 2: -Bit(s) Description (Table P0180) - 7 Master Mode Byte Swap Enable - 0 = disable (default) - 1 = enable - 6 Emulation Keyboard Reset Delay Control - 0 = Generate reset pulse 2us later (default) - 1 = Generate reset pulse immediately - 5 disable Parity Check (default is 0 = enabled) - 4 Cache Enable - 0 = Cache disabled and DRAM burst mode enabled (default) - 1 = Cache enabled and DRAM burst mode disabled - 3-2 Cache Size - 00 64KB (default) - 01 128KB - 10 256KB - 11 512KB - 1 Secondary Cache Read Burst Cycles Control - 0 = 3-1-1-1 cycle (default) - 1 = 2-1-1-1 cycle - 0 Cache Write Wait State Control - 0 = 1 wait state (default) - 1 = 0 wait state -SeeAlso: #P0179,#P0186 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 1: -Bit(s) Description (Table P0181) - 7 ROM(F0000h - FFFFFh) Enable - 0 = read/write on write-protected DRAM - 1 = read from ROM, write to DRAM (default) - 6 Shadow RAM at D0000h - EFFFFh Area - 0 = disable (default) - 1 = enable - 5 Shadow RAM at E0000h - EFFFFh Area - 0 = disable shadow RAM (default) - E0000h - EFFFFh ROM is defaulted to reside on XD bus - 1 = enable shadow RAM - 4 enable write-protect for Shadow RAM at D0000h - DFFFFh Area - 0 = disable (default) - 1 = enable - 3 enable write-protect for Shadow RAM at E0000h - EFFFFh Area - 0 = disable (default) - 1 = enable - 2 Hidden refresh enable (with holding CPU) - (Hidden refresh must be disabled if 4Mx1 or 1M x4 bit DRAM are used) - 1 = disable (default) - 0 = enable - 1 unused - 0 enable Slow Refresh (four times slower than normal refresh) - (default is 0 = disable) -SeeAlso: #P0182 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 2: -Bit(s) Description (Table P0182) - 7 enable Shadow RAM at EC000h - EFFFFh area - 6 enable Shadow RAM at E8000h - EBFFFh area - 5 enable Shadow RAM at E4000h - E7FFFh area - 4 enable Shadow RAM at E0000h - E3FFFh area - 3 enable Shadow RAM at DC000h - DFFFFh area - 2 enable Shadow RAM at D8000h - DBFFFh area - 1 enable Shadow RAM at D4000h - D7FFFh area - 0 enable Shadow RAM at D0000h - D3FFFh area -Note: the default is disabled (0) for all areas - -Bitfields for OPTi-82C493 DRAM Control Register 1: -Bit(s) Description (Table P0183) - 7 DRAM size - 0 = 256K DRAM mode - 1 = 1M and 4M DRAM mode - 6-4 DRAM types used for bank0 and bank1 - bits 7-4 Bank0 Bank1 - 0000 256K x - 0001 256K 256K - 0010 256K 1M - 0011 x x - 01xx x x - 1000 1M x (default) - 1001 1M 1M - 1010 1M 4M - 1011 4M 1M - 1100 4M x - 1101 4M 4M - 111x x x - 3 unused - 2-0 DRAM types used for bank2 and bank3 - bits 7,2-0 Bank2 Bank3 - x000 1M x - x001 1M 1M - x010 x x - x011 4M 1M - x100 4M x - x101 4M 4M - x11x x x (default) -SeeAlso: #P0184 - -Bitfields for OPTi-82C493 DRAM Control Register 2: -Bit(s) Description (Table P0184) - 7-6 Read cycle additional wait states - 00 not used - 01 = 0 - 10 = 1 - 11 = 2 (default) - 5-4 Write cycle additional wait states - 00 = 0 - 01 = 1 - 10 = 2 - 11 = 3 (default) - 3 Fast decode enable - 0 = disable fast decode. DRAM base wait states not changed (default) - 1 = enable fast decode. DRAM base wait state is decreased by 1 - Note: This function may be enabled in 20/25Mhz operation to speed up - DRAM access. If bit 4 of index register 21h (cache enable - bit) is enabled, this bit is automatically disabled--even if - set to 1 - 2 unused - 1-0 ATCLK selection - 00 ATCLK = CLKI/6 (default) - 01 ATCLK = CLKI/4 (default) - 10 ATCLK = CLKI/3 - 11 ATCLK = CLK2I/5 (CLKI * 2 /5) - Note: bit 0 will reflect the BCLKS (pin 142) status and bit 1 will be - set to 0 when 82C493 is reset. -SeeAlso: #P0183,#P0185 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 3: -Bit(s) Description (Table P0185) - 7 unused - 6 Shadow RAM copy enable for address C0000h - CFFFFh - 0 = Read/write at AT bus (default) - 1 = Read from AT bus and write into shadow RAM - 5 Shadow write protect at address C0000h - CFFFFh - 0 = Write protect disable (default) - 1 = Write protect enable - 4 enable Shadow RAM at C0000h - CFFFFh - 3 enable Shadow RAM at CC000h - CFFFFh - 2 enable Shadow RAM at C8000h - CBFFFh - 1 enable Shadow RAM at C4000h - C7FFFh - 0 enable Shadow RAM at C0000h - C3FFFh -Note: the default is disabled (0) for bits 4-0 -SeeAlso: #P0183,#P0184 - -Bitfields for OPTi-82C493 Control Register 3: -Bit(s) Description (Table P0186) - 7 enable NCA# pin to low state (default is 1 = enabled) - 6-5 unused - 4 Video BIOS at C0000h - C8000h non-cacheable - 0 = cacheable - 1 = non-cacheable (default) - 3-0 Cacheable address range for local memory - 0000 0 - 64MB - 0001 0 - 4MB (default) - 0010 0 - 8MB - 0011 0 - 12MB - 0100 0 - 16MB - 0101 0 - 20MB - 0110 0 - 24MB - 0111 0 - 28MB - 1000 0 - 32MB - 1001 0 - 36MB - 1010 0 - 40MB - 1011 0 - 44MB - 1100 0 - 48MB - 1101 0 - 52MB - 1110 0 - 56MB - 1111 0 - 60MB - Note: If total memory is 1MB or 2MB the cacheable range is 0-1 MB or - 0-2 MB and independent of the value of bits 3-0 -SeeAlso: #P0179,#P0180 - -Bitfields for OPTi-82C493 Non-cacheable Block Register 1: -Bit(s) Description (Table P0187) - 7-5 Size of non-cachable memory block - 000 64K - 001 128K - 010 256K - 011 512K - 1xx disabled (default) - 4-2 unused - 1-0 Address bits 25 and 24 of non-cachable memory block (default = 00) -Note: this register is used together with configuration register 29h - (non-cacheable block 1) or register 2Bh (block 2) (see #P0188) to - define a non-cacheable block. The starting address must be a - multiple of the block size -SeeAlso: #P0178,#P0188 - -Bitfields for OPTi-82C493 Non-cacheable Block Register 2: -Bit(s) Description (Table P0188) - 7-0 Address bits 23-16 of non-cachable memory block (default = 0001xxxx) -Note: the block address is forced to be a multiple of the block size by - ignoring the appropriate number of the least-significant bits -SeeAlso: #P0178,#P0187 -*/ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "machine.h" - - -static uint8_t optiregs[0x10]; -static int optireg; - - -static void opti495_write(uint16_t addr, uint8_t val, void *p) -{ - switch (addr) - { - case 0x22: - optireg=val; - break; - case 0x24: - if (optireg>=0x20 && optireg<=0x2C) - { - optiregs[optireg-0x20]=val; - if (optireg == 0x21) - { - cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); - } - if (optireg == 0x22) - { - shadowbios = !(val & 0x80); - shadowbios_write = val & 0x80; - if (shadowbios) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - } - } - break; - } -} - - -static uint8_t opti495_read(uint16_t addr, void *p) -{ - switch (addr) - { - case 0x24: - if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20]; - break; - } - return 0xFF; -} - - -static void opti495_init(void) -{ - io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - optiregs[0x22-0x20] = 0x80; -} - - -void -machine_at_opti495_init(const machine_t *model) -{ - machine_at_common_ide_init(model); - - device_add(&keyboard_at_device); - device_add(&fdc_at_device); - - opti495_init(); -} - - -void -machine_at_opti495_ami_init(const machine_t *model) -{ - machine_at_common_ide_init(model); - - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); - - opti495_init(); -} diff --git a/src - Cópia/machine/m_at_scat.c b/src - Cópia/machine/m_at_scat.c deleted file mode 100644 index c9af19fac..000000000 --- a/src - Cópia/machine/m_at_scat.c +++ /dev/null @@ -1,1397 +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. - * - * Implementation of Chips&Technology's SCAT (82C235) chipset. - * - * Re-worked version based on the 82C235 datasheet and errata. - * - * Version: @(#)m_at_scat.c 1.0.15 2018/04/29 - * - * Authors: Original by GreatPsycho for PCem. - * Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "machine.h" - - -#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 -#define SCAT_VERSION 0x40 -#define SCAT_CLOCK_CONTROL 0x41 -#define SCAT_PERIPHERAL_CONTROL 0x44 -#define SCAT_MISCELLANEOUS_STATUS 0x45 -#define SCAT_POWER_MANAGEMENT 0x46 -#define SCAT_ROM_ENABLE 0x48 -#define SCAT_RAM_WRITE_PROTECT 0x49 -#define SCAT_SHADOW_RAM_ENABLE_1 0x4A -#define SCAT_SHADOW_RAM_ENABLE_2 0x4B -#define SCAT_SHADOW_RAM_ENABLE_3 0x4C -#define SCAT_DRAM_CONFIGURATION 0x4D -#define SCAT_EXTENDED_BOUNDARY 0x4E -#define SCAT_EMS_CONTROL 0x4F - -#define SCATSX_LAPTOP_FEATURES 0x60 -#define SCATSX_FAST_VIDEO_CONTROL 0x61 -#define SCATSX_FAST_VIDEORAM_ENABLE 0x62 -#define SCATSX_HIGH_PERFORMANCE_REFRESH 0x63 -#define SCATSX_CAS_TIMING_FOR_DMA 0x64 - -typedef struct scat_t -{ - uint8_t regs_2x8; - uint8_t regs_2x9; -} scat_t; - - -static uint8_t scat_regs[256]; -static int scat_index; -static uint8_t scat_port_92 = 0; -static uint8_t scat_ems_reg_2xA = 0; -static mem_mapping_t scat_low_mapping[32]; -static mem_mapping_t scat_ems_mapping[32]; -static mem_mapping_t scat_high_mapping[16]; -static scat_t scat_stat[32]; -static uint32_t scat_xms_bound; -static mem_mapping_t scat_remap_mapping[6]; -static mem_mapping_t scat_4000_EFFF_mapping[44]; -static mem_mapping_t scat_low_ROMCS_mapping[8]; - - -static int scat_max_map[32] = { 0, 1, 1, 1, 2, 3, 4, 8, - 4, 8, 12, 16, 20, 24, 28, 32, - 0, 5, 9, 13, 6, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; -static int scatsx_max_map[32] = { 0, 1, 2, 1, 3, 4, 6, 10, - 5, 9, 13, 4, 8, 12, 16, 14, - 18, 22, 26, 20, 24, 28, 32, 18, - 20, 32, 0, 0, 0, 0, 0, 0 }; - -static int external_is_RAS = 0; - -static int scatsx_external_is_RAS[33] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0 }; - - -static uint8_t scat_read(uint16_t port, void *priv); -static void scat_write(uint16_t port, uint8_t val, void *priv); - - -static void -scat_romcs_state_update(uint8_t val) -{ - int i; - for(i = 0; i < 4; i++) { - if (val & 1) { - mem_mapping_enable(&scat_low_ROMCS_mapping[i << 1]); - mem_mapping_enable(&scat_low_ROMCS_mapping[(i << 1) + 1]); - } else { - mem_mapping_disable(&scat_low_ROMCS_mapping[i << 1]); - mem_mapping_disable(&scat_low_ROMCS_mapping[(i << 1) + 1]); - } - val >>= 1; - } - - for(i = 0; i < 4; i++) { - if (val & 1) { - mem_mapping_enable(&bios_mapping[i << 1]); - mem_mapping_enable(&bios_mapping[(i << 1) + 1]); - } else { - mem_mapping_disable(&bios_mapping[i << 1]); - mem_mapping_disable(&bios_mapping[(i << 1) + 1]); - } - val >>= 1; - } -} - - -static void -scat_shadow_state_update() -{ - int i, val; - - for (i = 0; i < 24; i++) { - val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; - mem_set_mem_state((i + 40) << 14, 0x4000, val); - } - - flushmmucache(); -} - - -static void -scat_set_xms_bound(uint8_t val) -{ - uint32_t max_xms_size = ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0xFE0000 : 0xFC0000; - - switch (val & 0x0F) { - case 1: - scat_xms_bound = 0x100000; - break; - case 2: - scat_xms_bound = 0x140000; - break; - case 3: - scat_xms_bound = 0x180000; - break; - case 4: - scat_xms_bound = 0x200000; - break; - case 5: - scat_xms_bound = 0x300000; - break; - case 6: - scat_xms_bound = 0x400000; - break; - case 7: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x600000 : 0x500000; - break; - case 8: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x800000 : 0x700000; - break; - case 9: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xA00000 : 0x800000; - break; - case 10: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xC00000 : 0x900000; - break; - case 11: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xE00000 : 0xA00000; - break; - case 12: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xB00000; - break; - case 13: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xC00000; - break; - case 14: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xD00000; - break; - case 15: - scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xF00000; - break; - default: - scat_xms_bound = max_xms_size; - break; - } - - if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { - if((val & 0x0F) == 0 || scat_xms_bound > 0x160000) - scat_xms_bound = 0x160000; - if (scat_xms_bound > 0x100000) - mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if (scat_xms_bound < 0x160000) - mem_set_mem_state(scat_xms_bound, 0x160000 - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } else { - if (scat_xms_bound > max_xms_size) - scat_xms_bound = max_xms_size; - if (scat_xms_bound > 0x100000) - mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if (scat_xms_bound < (mem_size << 10)) - mem_set_mem_state(scat_xms_bound, (mem_size << 10) - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - - mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0x60000 : 0x40000); - if(scat_regs[SCAT_VERSION] & 0xF0) { - int i; - for(i=0;i<8;i++) { - if(val & 0x10) - mem_mapping_disable(&scat_high_mapping[i]); - else - mem_mapping_enable(&scat_high_mapping[i]); - } - } -} - - -static uint32_t -get_scat_addr(uint32_t addr, scat_t *p) -{ - int nbank; - - if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) - addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; - - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - switch((scat_regs[SCAT_EXTENDED_BOUNDARY] & ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 0x40 : 0)) | (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F)) { - case 0x41: - nbank = addr >> 19; - if(nbank < 4) - nbank = 1; - else if(nbank == 4) - nbank = 0; - else - nbank -= 3; - break; - case 0x42: - nbank = addr >> 19; - if(nbank < 8) - nbank = 1 + (nbank >> 2); - else if(nbank == 8) - nbank = 0; - else - nbank -= 6; - break; - case 0x43: - nbank = addr >> 19; - if(nbank < 12) - nbank = 1 + (nbank >> 2); - else if(nbank == 12) - nbank = 0; - else - nbank -= 9; - break; - case 0x44: - nbank = addr >> 19; - if(nbank < 4) - nbank = 2; - else if(nbank < 6) - nbank -= 4; - else - nbank -= 3; - break; - case 0x45: - nbank = addr >> 19; - if(nbank < 8) - nbank = 2 + (nbank >> 2); - else if(nbank < 10) - nbank -= 8; - else - nbank -= 6; - break; - default: - nbank = addr >> (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) ? 19 : 21); - break; - } - nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && nbank == 2 && (addr & 0x7FFFF) < 0x60000 && mem_size > 640) { - nbank = 1; - addr ^= 0x70000; - } - - if(external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { - if(nbank == 3) - nbank = 7; - else - return 0xFFFFFFFF; - } else if(!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { - switch(nbank) { - case 7: - nbank = 3; - break; - /* Note - In the following cases, the chipset accesses multiple memory banks - at the same time, so it's impossible to predict which memory bank - is actually accessed. */ - case 5: - case 1: - nbank = 1; - break; - case 3: - nbank = 2; - break; - default: - nbank = 0; - break; - } - } - - if((scat_regs[SCAT_VERSION] & 0x0F) > 3 && (mem_size > 2048) && (mem_size & 1536)) { - if((mem_size & 1536) == 512) { - if(nbank == 0) - addr &= 0x7FFFF; - else - addr = 0x80000 + ((addr & 0x1FFFFF) | ((nbank - 1) << 21)); - } else { - if(nbank < 2) - addr = (addr & 0x7FFFF) | (nbank << 19); - else - addr = 0x100000 + ((addr & 0x1FFFFF) | ((nbank - 2) << 21)); - } - } else { - int nbanks_2048k, nbanks_512k; - if (mem_size <= ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 2048 : 4096) && (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8) || external_is_RAS)) { - nbanks_2048k = 0; - nbanks_512k = mem_size >> 9; - } else { - nbanks_2048k = mem_size >> 11; - nbanks_512k = (mem_size & 1536) >> 9; - } - if(nbank < nbanks_2048k || (nbanks_2048k > 0 && nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7))) { - addr &= 0x1FFFFF; - addr |= (nbank << 21); - } else if(nbank < nbanks_2048k + nbanks_512k || nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7)) { - addr &= 0x7FFFF; - addr |= (nbanks_2048k << 21) | ((nbank - nbanks_2048k) << 19); - } else { - addr &= 0x1FFFF; - addr |= (nbanks_2048k << 21) | (nbanks_512k << 19) | ((nbank - nbanks_2048k - nbanks_512k) << 17); - } - } - } else { - uint32_t addr2; - switch(scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) { - case 2: - case 4: - nbank = addr >> 19; - if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else - addr2 = addr >> 10; - break; - case 3: - nbank = addr >> 19; - if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) == 2 && (addr & 0x7FFFF) < 0x60000) { - addr ^= 0x1F0000; - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else - addr2 = addr >> 10; - break; - case 5: - nbank = addr >> 19; - if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { - nbank = (addr >> 10) & 3; - addr2 = addr >> 12; - } else - addr2 = addr >> 10; - break; - case 6: - nbank = addr >> 19; - if(nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else { - nbank = 2 + ((addr - 0x100000) >> 21); - addr2 = (addr - 0x100000) >> 11; - } - break; - case 7: - case 0x0F: - nbank = addr >> 19; - if(nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if(nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else { - nbank = 4 + ((addr - 0x500000) >> 21); - addr2 = (addr - 0x500000) >> 11; - } - break; - case 8: - nbank = addr >> 19; - if(nbank < 4) { - nbank = 1; - addr2 = addr >> 11; - } else if(nbank == 4) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 3; - addr2 = addr >> 10; - } - break; - case 9: - nbank = addr >> 19; - if(nbank < 8) { - nbank = 1 + ((addr >> 11) & 1); - addr2 = addr >> 12; - } else if(nbank == 8) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 6; - addr2 = addr >> 10; - } - break; - case 0x0A: - nbank = addr >> 19; - if(nbank < 8) { - nbank = 1 + ((addr >> 11) & 1); - addr2 = addr >> 12; - } else if(nbank < 12) { - nbank = 3; - addr2 = addr >> 11; - } else if(nbank == 12) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 9; - addr2 = addr >> 10; - } - break; - case 0x0B: - nbank = addr >> 21; - addr2 = addr >> 11; - break; - case 0x0C: - case 0x0D: - nbank = addr >> 21; - if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 11) & 1; - addr2 = addr >> 12; - } else - addr2 = addr >> 11; - break; - case 0x0E: - case 0x13: - nbank = addr >> 21; - if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { - nbank = (addr >> 11) & 3; - addr2 = addr >> 13; - } else - addr2 = addr >> 11; - break; - case 0x10: - case 0x11: - nbank = addr >> 19; - if(nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if(nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else if(nbank < 18) { - nbank = 4 + (((addr - 0x500000) >> 11) & 1); - addr2 = (addr - 0x500000) >> 12; - } else { - nbank = 6 + ((addr - 0x900000) >> 21); - addr2 = (addr - 0x900000) >> 11; - } - break; - case 0x12: - nbank = addr >> 19; - if(nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if(nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else { - nbank = 4 + (((addr - 0x500000) >> 11) & 3); - addr2 = (addr - 0x500000) >> 13; - } - break; - case 0x14: - case 0x15: - nbank = addr >> 21; - if((nbank & 7) < 4) { - nbank = (addr >> 11) & 3; - addr2 = addr >> 13; - } else if((nbank & 7) < 6) { - nbank = 4 + (((addr - 0x800000) >> 11) & 1); - addr2 = (addr - 0x800000) >> 12; - } else { - nbank = 6 + (((addr - 0xC00000) >> 11) & 3); - addr2 = (addr - 0xC00000) >> 13; - } - break; - case 0x16: - nbank = ((addr >> 21) & 4) | ((addr >> 11) & 3); - addr2 = addr >> 13; - break; - case 0x17: - if(external_is_RAS && (addr & 0x800) == 0) - return 0xFFFFFFFF; - nbank = addr >> 19; - if(nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else { - nbank = 2 + ((addr - 0x100000) >> 23); - addr2 = (addr - 0x100000) >> 12; - } - break; - case 0x18: - if(external_is_RAS && (addr & 0x800) == 0) - return 0xFFFFFFFF; - nbank = addr >> 21; - if(nbank < 4) { - nbank = 1; - addr2 = addr >> 12; - } else if(nbank == 4) { - nbank = 0; - addr2 = addr >> 11; - } else { - nbank -= 3; - addr2 = addr >> 11; - } - break; - case 0x19: - if(external_is_RAS && (addr & 0x800) == 0) - return 0xFFFFFFFF; - nbank = addr >> 23; - if((nbank & 3) < 2) { - nbank = (addr >> 12) & 1; - addr2 = addr >> 13; - } else - addr2 = addr >> 12; - break; - default: - if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6) { - nbank = addr >> 19; - addr2 = (addr >> 10) & 0x1FF; - } else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) { - nbank = addr >> 21; - addr2 = (addr >> 11) & 0x3FF; - } else { - nbank = addr >> 23; - addr2 = (addr >> 12) & 0x7FF; - } - break; - } - - nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 0x16 && nbank == 3) - return 0xFFFFFFFF; - - if(external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { - if(nbank == 3) - nbank = 7; - else - return 0xFFFFFFFF; - } else if(!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { - switch(nbank) { - case 7: - nbank = 3; - break; - /* Note - In the following cases, the chipset accesses multiple memory banks - at the same time, so it's impossible to predict which memory bank - is actually accessed. */ - case 5: - case 1: - nbank = 1; - break; - case 3: - nbank = 2; - break; - default: - nbank = 0; - break; - } - } - - switch(mem_size & ~511) { - case 1024: - case 1536: - addr &= 0x3FF; - if(nbank < 2) - addr |= (nbank << 10) | ((addr2 & 0x1FF) << 11); - else - addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); - break; - case 2048: - if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 5) { - addr &= 0x3FF; - if(nbank < 4) - addr |= (nbank << 10) | ((addr2 & 0x1FF) << 12); - else - addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); - } else { - addr &= 0x7FF; - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - } - break; - case 2560: - if(nbank == 0) - addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); - else { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); - } - break; - case 3072: - if(nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); - break; - case 4096: - case 6144: - addr &= 0x7FF; - if(nbank < 2) - addr |= (nbank << 11) | ((addr2 & 0x3FF) << 12); - else - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - break; - case 4608: - if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) { - if(nbank == 0) - addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); - else if(nbank < 3) - addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); - else - addr = 0x480000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 3) << 19)); - } else if(nbank == 0) - addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); - else { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); - } - break; - case 5120: - case 7168: - if(nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else if(nbank < 4) - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); - break; - case 6656: - if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) { - if(nbank == 0) - addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); - else if(nbank < 3) - addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); - else if(nbank == 3) - addr = 0x480000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11)); - else - addr = 0x680000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 4) << 19)); - } else if(nbank == 0) - addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); - else if(nbank == 1) { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr = addr + 0x80000 + (addr2 << 11); - } else { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr = addr + 0x280000 + ((addr2 << 12) | ((nbank & 1) << 11) | (((nbank - 2) & 6) << 21)); - } - break; - case 8192: - addr &= 0x7FF; - if(nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); - else - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - break; - case 9216: - if(nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else if(external_is_RAS) { - if(nbank < 6) - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); - } else - addr = 0x100000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); - break; - case 10240: - if(external_is_RAS) { - addr &= 0x7FF; - if(nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); - else - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - } else if(nbank == 0) - addr = (addr & 0x7FF) | ((addr2 & 0x3FF) << 11); - else { - addr &= 0xFFF; - addr2 &= 0x7FF; - addr = addr + 0x200000 + ((addr2 << 12) | ((nbank - 1) << 23)); - } - break; - case 11264: - if(nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else if(nbank < 6) - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); - break; - case 12288: - if(external_is_RAS) { - addr &= 0x7FF; - if(nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); - else if(nbank < 6) - addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); - else - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - } else { - if(nbank < 2) - addr = (addr & 0x7FF) | (nbank << 11) | ((addr2 & 0x3FF) << 12); - else - addr = 0x400000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); - } - break; - case 13312: - if(nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else if(nbank < 4) - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); - else - addr = 0x500000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 13) | ((nbank & 3) << 11)); - break; - case 14336: - addr &= 0x7FF; - if(nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); - else if(nbank < 6) - addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); - else - addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); - break; - case 16384: - if(external_is_RAS) { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr |= ((nbank & 3) << 11) | (addr2 << 13) | ((nbank & 4) << 21); - } else { - addr &= 0xFFF; - addr2 &= 0x7FF; - if(nbank < 2) - addr |= (addr2 << 13) | (nbank << 12); - else - addr |= (addr2 << 12) | (nbank << 23); - } - break; - default: - if(mem_size < 2048 || ((mem_size & 1536) == 512) || (mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6)) { - addr &= 0x3FF; - addr2 &= 0x1FF; - addr |= (addr2 << 10) | (nbank << 19); - } else if(mem_size < 8192 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) { - addr &= 0x7FF; - addr2 &= 0x3FF; - addr |= (addr2 << 11) | (nbank << 21); - } else { - addr &= 0xFFF; - addr2 &= 0x7FF; - addr |= (addr2 << 12) | (nbank << 23); - } - break; - } - } - return addr; -} - - -static void -scat_set_global_EMS_state(int state) -{ - int i; - uint32_t base_addr, virt_addr; - - for(i=((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 24; i<32; i++) { - base_addr = (i + 16) << 14; - if(i >= 24) - base_addr += 0x30000; - if(state && (scat_stat[i].regs_2x9 & 0x80)) { - virt_addr = get_scat_addr(base_addr, &scat_stat[i]); - if(i < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[i]); - else mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); - mem_mapping_enable(&scat_ems_mapping[i]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[i], ram + virt_addr); - else mem_mapping_set_exec(&scat_ems_mapping[i], NULL); - } else { - mem_mapping_set_exec(&scat_ems_mapping[i], ram + base_addr); - mem_mapping_disable(&scat_ems_mapping[i]); - - int conf = (scat_regs[SCAT_VERSION] & 0xF0) ? (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) : (scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2); - if(i < 24) { - if(conf > 1 || (conf == 1 && i < 16)) - mem_mapping_enable(&scat_4000_EFFF_mapping[i]); - else - mem_mapping_disable(&scat_4000_EFFF_mapping[i]); - } else if(conf > 3 || ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && conf == 2)) - mem_mapping_enable(&scat_4000_EFFF_mapping[i + 12]); - else - mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); - } - } - flushmmucache(); -} - - -static void -scat_memmap_state_update() -{ - int i; - uint32_t addr; - - for(i=(((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 16);i<44;i++) { - addr = get_scat_addr(0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&scat_4000_EFFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - } - addr = get_scat_addr(0, NULL); - mem_mapping_set_exec(&scat_low_mapping[0], addr < (mem_size << 10) ? ram + addr : NULL); - addr = get_scat_addr(0xF0000, NULL); - mem_mapping_set_exec(&scat_low_mapping[1], addr < (mem_size << 10) ? ram + addr : NULL); - for(i=2;i<32;i++) { - addr = get_scat_addr(i << 19, NULL); - mem_mapping_set_exec(&scat_low_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - } - - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - for(i=0;i < scat_max_map[(scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)];i++) - mem_mapping_enable(&scat_low_mapping[i]); - for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); - - for(i=24;i<36;i++) { - if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4) - mem_mapping_disable(&scat_4000_EFFF_mapping[i]); - else - mem_mapping_enable(&scat_4000_EFFF_mapping[i]); - } - } else { - for(i=0;i < scatsx_max_map[scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F];i++) - mem_mapping_enable(&scat_low_mapping[i]); - for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); - - for(i=24;i<36;i++) { - if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 2 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3) - mem_mapping_disable(&scat_4000_EFFF_mapping[i]); - else - mem_mapping_enable(&scat_4000_EFFF_mapping[i]); - } - } - - if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) { - if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { - mem_mapping_disable(&scat_low_mapping[2]); - for(i=0;i<6;i++) { - addr = get_scat_addr(0x100000 + (i << 16), NULL); - mem_mapping_set_exec(&scat_remap_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - mem_mapping_enable(&scat_remap_mapping[i]); - } - } else { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_remap_mapping[i]); - if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 4) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 3)) - mem_mapping_enable(&scat_low_mapping[2]); - } - } else { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_remap_mapping[i]); - mem_mapping_enable(&scat_low_mapping[2]); - } - - scat_set_global_EMS_state(scat_regs[SCAT_EMS_CONTROL] & 0x80); -} - - -static void -scat_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t scat_reg_valid = 0, scat_shadow_update = 0, scat_map_update = 0, index; - uint32_t base_addr, virt_addr; - - switch (port) { - case 0x22: - scat_index = val; - break; - - case 0x23: - switch (scat_index) { - case SCAT_DMA_WAIT_STATE_CONTROL: - case SCAT_CLOCK_CONTROL: - case SCAT_PERIPHERAL_CONTROL: - scat_reg_valid = 1; - break; - case SCAT_EMS_CONTROL: - if(val & 0x40) { - if(val & 1) { - io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - } else { - io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - } - } else { - io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - } - scat_set_global_EMS_state(val & 0x80); - scat_reg_valid = 1; - break; - case SCAT_POWER_MANAGEMENT: - /* TODO - Only use AUX parity disable bit for this version. - Other bits should be implemented later. */ - val &= (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x40 : 0x60; - scat_reg_valid = 1; - break; - case SCAT_DRAM_CONFIGURATION: - scat_map_update = 1; - - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; - cpu_update_waitstates(); - } - - scat_reg_valid = 1; - break; - case SCAT_EXTENDED_BOUNDARY: - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - if(scat_regs[SCAT_VERSION] < 4) { - val &= 0xBF; - scat_set_xms_bound(val & 0x0f); - } else { - val = (val & 0x7F) | 0x80; - scat_set_xms_bound(val & 0x4f); - } - } else - scat_set_xms_bound(val & 0x1f); - mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0xC0) scat_map_update = 1; - scat_reg_valid = 1; - break; - case SCAT_ROM_ENABLE: - scat_reg_valid = 1; - scat_romcs_state_update(val); - break; - case SCAT_RAM_WRITE_PROTECT: - scat_reg_valid = 1; - flushmmucache_cr3(); - break; - case SCAT_SHADOW_RAM_ENABLE_1: - case SCAT_SHADOW_RAM_ENABLE_2: - case SCAT_SHADOW_RAM_ENABLE_3: - scat_reg_valid = 1; - scat_shadow_update = 1; - break; - case SCATSX_LAPTOP_FEATURES: - if((scat_regs[SCAT_VERSION] & 0xF0) != 0) { - val = (val & ~8) | (scat_regs[SCATSX_LAPTOP_FEATURES] & 8); - scat_reg_valid = 1; - } - break; - case SCATSX_FAST_VIDEO_CONTROL: - case SCATSX_FAST_VIDEORAM_ENABLE: - case SCATSX_HIGH_PERFORMANCE_REFRESH: - case SCATSX_CAS_TIMING_FOR_DMA: - if((scat_regs[SCAT_VERSION] & 0xF0) != 0) scat_reg_valid = 1; - break; - default: - break; - } - if (scat_reg_valid) - scat_regs[scat_index] = val; - if (scat_shadow_update) - scat_shadow_state_update(); - if (scat_map_update) - scat_memmap_state_update(); - break; - - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~scat_port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - scat_port_92 = val; - break; - - case 0x208: - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; - else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; - scat_stat[index].regs_2x8 = val; - base_addr = (index + 16) << 14; - if(index >= 24) - base_addr += 0x30000; - - if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); - else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); - flushmmucache(); - } - } - break; - case 0x209: - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; - else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; - scat_stat[index].regs_2x9 = val; - base_addr = (index + 16) << 14; - if(index >= 24) - base_addr += 0x30000; - - if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { - if (val & 0x80) { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[index]); - else mem_mapping_disable(&scat_4000_EFFF_mapping[index + 12]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); - else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); - mem_mapping_enable(&scat_ems_mapping[index]); - } else { - mem_mapping_set_exec(&scat_ems_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_ems_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_EFFF_mapping[index]); - else mem_mapping_enable(&scat_4000_EFFF_mapping[index + 12]); - } - flushmmucache(); - } - - if (scat_ems_reg_2xA & 0x80) - scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & (((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0x1f : 3)); - } - break; - case 0x20A: - case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) - scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; - break; - } -} - - -static uint8_t -scat_read(uint16_t port, void *priv) -{ - uint8_t val = 0xff, index; - switch (port) { - case 0x23: - switch (scat_index) { - case SCAT_MISCELLANEOUS_STATUS: - val = (scat_regs[scat_index] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); - break; - case SCAT_DRAM_CONFIGURATION: - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); - else val = scat_regs[scat_index]; - break; - case SCAT_EXTENDED_BOUNDARY: - val = scat_regs[scat_index]; - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - if((scat_regs[SCAT_VERSION] & 0x0F) >= 4) - val |= 0x80; - else - val &= 0xAF; - } - break; - default: - val = scat_regs[scat_index]; - break; - } - break; - - case 0x92: - val = scat_port_92; - break; - - case 0x208: - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; - else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; - val = scat_stat[index].regs_2x8; - } - break; - case 0x209: - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; - else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; - val = scat_stat[index].regs_2x9; - } - break; - case 0x20A: - case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) - val = scat_ems_reg_2xA; - break; - } - return val; -} - - -static uint8_t -mem_read_scatb(uint32_t addr, void *priv) -{ - uint8_t val = 0xff; - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = ram[addr]; - - return val; -} - - -static void -mem_write_scatb(uint32_t addr, uint8_t val, void *priv) -{ - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; - - addr = get_scat_addr(addr, stat); - chkaddr = stat ? addr : oldaddr; - if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { - if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; - } - if (addr < (mem_size << 10)) - ram[addr] = val; -} - - -static uint16_t -mem_read_scatw(uint32_t addr, void *priv) -{ - uint16_t val = 0xffff; - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = *(uint16_t *)&ram[addr]; - - return val; -} - - -static void -mem_write_scatw(uint32_t addr, uint16_t val, void *priv) -{ - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; - - addr = get_scat_addr(addr, stat); - chkaddr = stat ? addr : oldaddr; - if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { - if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; - } - if (addr < (mem_size << 10)) - *(uint16_t *)&ram[addr] = val; -} - - -static uint32_t -mem_read_scatl(uint32_t addr, void *priv) -{ - uint32_t val = 0xffffffff; - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = *(uint32_t *)&ram[addr]; - - return val; -} - - -static void -mem_write_scatl(uint32_t addr, uint32_t val, void *priv) -{ - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; - - addr = get_scat_addr(addr, stat); - chkaddr = stat ? addr : oldaddr; - if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { - if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; - } - if (addr < (mem_size << 10)) - *(uint32_t *)&ram[addr] = val; -} - - -static void -scat_init() -{ - int i; - - io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - - for (i = 0; i < 256; i++) - scat_regs[i] = 0xff; - - scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - switch(romset) { - case ROM_GW286CT: - case ROM_SPC4216P: - scat_regs[SCAT_VERSION] = 4; - break; - default: - scat_regs[SCAT_VERSION] = 1; - break; - } - scat_regs[SCAT_CLOCK_CONTROL] = 2; - scat_regs[SCAT_PERIPHERAL_CONTROL] = 0x80; - scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; - scat_regs[SCAT_POWER_MANAGEMENT] = 0; - scat_regs[SCAT_ROM_ENABLE] = 0xC0; - scat_regs[SCAT_RAM_WRITE_PROTECT] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_1] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 0; - scat_regs[SCAT_DRAM_CONFIGURATION] = cpu_waitstates == 1 ? 2 : 0x12; - scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; - scat_regs[SCAT_EMS_CONTROL] = 0; - scat_port_92 = 0; - - mem_mapping_disable(&ram_low_mapping); - mem_mapping_disable(&ram_mid_mapping); - mem_mapping_disable(&ram_high_mapping); - for (i = 0; i < 4; i++) - mem_mapping_disable(&bios_mapping[i]); - mem_mapping_add(&scat_low_mapping[0], 0, 0x40000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); - for(i=2;i<32;i++) - mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, scat_regs[SCAT_VERSION] < 4 ? 0x40000 : 0x60000); - - for (i = 0; i < 44; i++) - mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - for (i = 0; i < 8; i++) { - mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); - mem_mapping_disable(&scat_low_ROMCS_mapping[i]); - } - - for (i = 0; i < 32; i++) { - scat_stat[i].regs_2x8 = 0xff; - scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); - } - - for(i=4;i<10;i++) isram[i] = 0; - - for (i = (scat_regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) { - mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&scat_high_mapping[i]); - } - - for(i=0;i<6;i++) - mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); - - external_is_RAS = (scat_regs[SCAT_VERSION] > 3) || (((mem_size & ~2047) >> 11) + ((mem_size & 1536) >> 9) + ((mem_size & 511) >> 7)) > 4; - - scat_set_xms_bound(0); - scat_memmap_state_update(); - scat_shadow_state_update(); -} - - -static void -scatsx_init() -{ - int i; - - io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - - for (i = 0; i < 256; i++) - scat_regs[i] = 0xff; - - scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - scat_regs[SCAT_VERSION] = 0x13; - scat_regs[SCAT_CLOCK_CONTROL] = 6; - scat_regs[SCAT_PERIPHERAL_CONTROL] = 0; - scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; - scat_regs[SCAT_POWER_MANAGEMENT] = 0; - scat_regs[SCAT_ROM_ENABLE] = 0xC0; - scat_regs[SCAT_RAM_WRITE_PROTECT] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_1] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; - scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 0; - scat_regs[SCAT_DRAM_CONFIGURATION] = 1; - scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; - scat_regs[SCAT_EMS_CONTROL] = 0; - scat_regs[SCATSX_LAPTOP_FEATURES] = 0; - scat_regs[SCATSX_FAST_VIDEO_CONTROL] = 0; - scat_regs[SCATSX_FAST_VIDEORAM_ENABLE] = 0; - scat_regs[SCATSX_HIGH_PERFORMANCE_REFRESH] = 8; - scat_regs[SCATSX_CAS_TIMING_FOR_DMA] = 3; - scat_port_92 = 0; - - mem_mapping_disable(&ram_low_mapping); - mem_mapping_disable(&ram_mid_mapping); - mem_mapping_disable(&ram_high_mapping); - for (i = 0; i < 4; i++) - mem_mapping_disable(&bios_mapping[i]); - mem_mapping_add(&scat_low_mapping[0], 0, 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); - for(i=2;i<32;i++) - mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, 0x40000); - - for (i = 16; i < 44; i++) { - mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_EFFF_mapping[i]); - } - for (i = 0; i < 8; i++) { - mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); - mem_mapping_disable(&scat_low_ROMCS_mapping[i]); - } - - for (i = 24; i < 32; i++) { - scat_stat[i].regs_2x8 = 0xff; - scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_ems_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + 28) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_ems_mapping[i]); - } - - for (i = 0; i < 16; i++) { - mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&scat_high_mapping[i]); - } - - for(i=0;i<6;i++) - mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); - - external_is_RAS = scatsx_external_is_RAS[mem_size >> 9]; - - scat_set_xms_bound(0); - scat_memmap_state_update(); - scat_shadow_state_update(); -} - - -void -machine_at_scat_init(const machine_t *model) -{ - machine_at_init(model); - device_add(&fdc_at_device); - - scat_init(); -} - - -void -machine_at_scatsx_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); - - scatsx_init(); -} diff --git a/src - Cópia/machine/m_at_sis_85c471.c b/src - Cópia/machine/m_at_sis_85c471.c deleted file mode 100644 index fc511d7c6..000000000 --- a/src - Cópia/machine/m_at_sis_85c471.c +++ /dev/null @@ -1,251 +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. - * - * Emulation of the SiS 85c471 chip. - * - * SiS sis85c471 Super I/O Chip - * Used by DTK PKM-0038S E-2 - * - * Version: @(#)m_at_sis85c471.c 1.0.10 2018/03/18 - * - * Author: Miran Grca, - * - * Copyright 2015-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../memregs.h" -#include "../device.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 "machine.h" - - -static int sis_85c471_curreg; -static uint8_t sis_85c471_regs[39]; - - -static void sis_85c471_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - uint8_t x; - - if (index) - { - if ((val >= 0x50) && (val <= 0x76)) sis_85c471_curreg = val; - return; - } - else - { - if ((sis_85c471_curreg < 0x50) || (sis_85c471_curreg > 0x76)) return; - x = val ^ sis_85c471_regs[sis_85c471_curreg - 0x50]; - /* Writes to 0x52 are blocked as otherwise, large hard disks don't read correctly. */ - if (sis_85c471_curreg != 0x52) sis_85c471_regs[sis_85c471_curreg - 0x50] = val; - goto process_value; - } - return; - -process_value: - switch(sis_85c471_curreg) - { - case 0x73: -#if 0 - if (x & 0x40) - { - if (val & 0x40) - ide_pri_enable(); - else - ide_pri_disable(); - } -#endif - - if (x & 0x20) - { - if (val & 0x20) - { - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - } - else - { - serial_remove(1); - serial_remove(2); - } - } - - if (x & 0x10) - { - if (val & 0x10) - lpt1_init(0x378); - else - lpt1_remove(); - } - - break; - } - sis_85c471_curreg = 0; -} - - -static uint8_t sis_85c471_read(uint16_t port, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - uint8_t temp; - - if (index) - return sis_85c471_curreg; - else - if ((sis_85c471_curreg >= 0x50) && (sis_85c471_curreg <= 0x76)) - { - temp = sis_85c471_regs[sis_85c471_curreg - 0x50]; - sis_85c471_curreg = 0; - return temp; - } - else - return 0xFF; -} - - -static void sis_85c471_init(void) -{ - int i = 0; - - lpt2_remove(); - - sis_85c471_curreg = 0; - for (i = 0; i < 0x27; i++) - { - sis_85c471_regs[i] = 0; - } - sis_85c471_regs[9] = 0x40; - switch (mem_size) - { - case 0: - case 1: - sis_85c471_regs[9] |= 0; - break; - case 2: - case 3: - sis_85c471_regs[9] |= 1; - break; - case 4: - sis_85c471_regs[9] |= 2; - break; - case 5: - sis_85c471_regs[9] |= 0x20; - break; - case 6: - case 7: - sis_85c471_regs[9] |= 9; - break; - case 8: - case 9: - sis_85c471_regs[9] |= 4; - break; - case 10: - case 11: - sis_85c471_regs[9] |= 5; - break; - case 12: - case 13: - case 14: - case 15: - sis_85c471_regs[9] |= 0xB; - break; - case 16: - sis_85c471_regs[9] |= 0x13; - break; - case 17: - sis_85c471_regs[9] |= 0x21; - break; - case 18: - case 19: - sis_85c471_regs[9] |= 6; - break; - case 20: - case 21: - case 22: - case 23: - sis_85c471_regs[9] |= 0xD; - break; - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - sis_85c471_regs[9] |= 0xE; - break; - case 32: - case 33: - case 34: - case 35: - sis_85c471_regs[9] |= 0x1B; - break; - case 36: - case 37: - case 38: - case 39: - sis_85c471_regs[9] |= 0xF; - break; - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - sis_85c471_regs[9] |= 0x17; - break; - case 48: - sis_85c471_regs[9] |= 0x1E; - break; - default: - if (mem_size < 64) - { - sis_85c471_regs[9] |= 0x1E; - } - else if ((mem_size >= 65) && (mem_size < 68)) - { - sis_85c471_regs[9] |= 0x22; - } - else - { - sis_85c471_regs[9] |= 0x24; - } - break; - } - - sis_85c471_regs[0x11] = 9; - sis_85c471_regs[0x12] = 0xFF; - sis_85c471_regs[0x23] = 0xF0; - sis_85c471_regs[0x26] = 1; - - io_sethandler(0x0022, 0x0002, sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, NULL); -} - - -void -machine_at_dtk486_init(const machine_t *model) -{ - machine_at_ide_init(model); - device_add(&fdc_at_device); - - memregs_init(); - sis_85c471_init(); - secondary_ide_check(); -} diff --git a/src - Cópia/machine/m_at_sis_85c496.c b/src - Cópia/machine/m_at_sis_85c496.c deleted file mode 100644 index ca8ffd732..000000000 --- a/src - Cópia/machine/m_at_sis_85c496.c +++ /dev/null @@ -1,230 +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. - * - * Implementation of the SiS 85c496/85c497 chip. - * - * Version: @(#)m_at_sis_85c496.c 1.0.1 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../keyboard.h" -#include "../io.h" -#include "../pci.h" -#include "../mem.h" -#include "../memregs.h" -#include "../sio.h" -#include "../disk/hdc.h" -#include "machine.h" - - -typedef struct sis_85c496_t -{ - uint8_t pci_conf[256]; -} sis_85c496_t; - - -static void -sis_85c496_recalcmapping(sis_85c496_t *dev) -{ - int c; - uint32_t base; - - for (c = 0; c < 8; c++) { - base = 0xc0000 + (c << 15); - if (dev->pci_conf[0x44] & (1 << c)) { - switch (dev->pci_conf[0x45] & 3) { - case 0: - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 1: - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - } - } else - mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - - flushmmucache(); - shadowbios = (dev->pci_conf[0x44] & 0xf0); -} - - -static void -sis_85c496_write(int func, int addr, uint8_t val, void *p) -{ - sis_85c496_t *dev = (sis_85c496_t *) p; - - switch (addr) { - case 0x44: /*Shadow configure*/ - if ((dev->pci_conf[0x44] & val) ^ 0xf0) { - dev->pci_conf[0x44] = val; - sis_85c496_recalcmapping(dev); - } - break; - case 0x45: /*Shadow configure*/ - if ((dev->pci_conf[0x45] & val) ^ 0x01) { - dev->pci_conf[0x45] = val; - sis_85c496_recalcmapping(dev); - } - break; - - case 0xc0: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, val & 0xf); - else - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - break; - case 0xc1: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, val & 0xf); - else - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - break; - case 0xc2: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, val & 0xf); - else - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - break; - case 0xc3: - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, val & 0xf); - else - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - break; - } - - if ((addr >= 4 && addr < 8) || addr >= 0x40) - dev->pci_conf[addr] = val; -} - - -static uint8_t -sis_85c496_read(int func, int addr, void *p) -{ - sis_85c496_t *dev = (sis_85c496_t *) p; - - return dev->pci_conf[addr]; -} - - -static void -sis_85c496_reset(void *priv) -{ - uint8_t val = 0; - - val = sis_85c496_read(0, 0x44, priv); /* Read current value of 0x44. */ - sis_85c496_write(0, 0x44, val & 0xf, priv); /* Turn off shadow BIOS but keep the lower 4 bits. */ -} - - -static void -sis_85c496_close(void *p) -{ - sis_85c496_t *sis_85c496 = (sis_85c496_t *)p; - - free(sis_85c496); -} - - -static void -*sis_85c496_init(const device_t *info) -{ - sis_85c496_t *sis496 = malloc(sizeof(sis_85c496_t)); - memset(sis496, 0, sizeof(sis_85c496_t)); - - sis496->pci_conf[0x00] = 0x39; /*SiS*/ - sis496->pci_conf[0x01] = 0x10; - sis496->pci_conf[0x02] = 0x96; /*496/497*/ - sis496->pci_conf[0x03] = 0x04; - - sis496->pci_conf[0x04] = 7; - sis496->pci_conf[0x05] = 0; - - sis496->pci_conf[0x06] = 0x80; - sis496->pci_conf[0x07] = 0x02; - - sis496->pci_conf[0x08] = 2; /*Device revision*/ - - sis496->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - sis496->pci_conf[0x0a] = 0x00; - sis496->pci_conf[0x0b] = 0x06; - - sis496->pci_conf[0x0e] = 0x00; /*Single function device*/ - - pci_add_card(5, sis_85c496_read, sis_85c496_write, sis496); - - return sis496; -} - - -const device_t sis_85c496_device = -{ - "SiS 85c496/85c497", - DEVICE_PCI, - 0, - sis_85c496_init, - sis_85c496_close, - sis_85c496_reset, - NULL, - NULL, - NULL, - NULL -}; - - -static void -machine_at_sis_85c496_common_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - device_add(&ide_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x05, PCI_CARD_SPECIAL, 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); - pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); - - 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); - - device_add(&sis_85c496_device); -} - - -void -machine_at_r418_init(const machine_t *model) -{ - machine_at_sis_85c496_common_init(model); - - fdc37c665_init(); -} diff --git a/src - Cópia/machine/m_at_sis_85c50x.c b/src - Cópia/machine/m_at_sis_85c50x.c deleted file mode 100644 index d64ffa48a..000000000 --- a/src - Cópia/machine/m_at_sis_85c50x.c +++ /dev/null @@ -1,323 +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. - * - * Emulation of the SiS 50x PCI chips. - * - * Version: @(#)m_at_sis_85c50x.c 1.0.7 2018/04/29 - * - * Author: Miran Grca, - * - * Copyright 2015-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../pci.h" -#include "../mem.h" -#include "machine.h" - - -typedef struct sis_85c501_t -{ - uint8_t pci_conf[256]; - uint8_t turbo_reg; -} sis_85c501_t; - -sis_85c501_t sis_85c501; - -typedef struct sis_85c503_t -{ - uint8_t pci_conf[256]; -} sis_85c503_t; - -sis_85c503_t sis_85c503; - -typedef struct sis_85c50x_t -{ - uint8_t isa_conf[12]; - uint8_t reg; -} sis_85c50x_isa_t; - -sis_85c50x_isa_t sis_85c50x_isa; - - -static void sis_85c501_recalcmapping(void) -{ - int c, d; - - for (c = 0; c < 1; c++) - { - for (d = 0; d < 4; d++) - { - uint32_t base = 0xe0000 + (d << 14); - if (sis_85c501.pci_conf[0x54 + c] & (1 << (d + 4))) - { - switch (sis_85c501.pci_conf[0x53] & 0x60) - { - case 0x00: - mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x20: - mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 0x40: - mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x60: - mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - } - } - else - mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - - flushmmucache(); - shadowbios = 1; -} - - -static void sis_85c501_write(int func, int addr, uint8_t val, void *p) -{ - if (func) - return; - - 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*/ - val &= 0x42; - val |= 0x04; - break; - case 0x05: - val &= 0x01; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x54: /*Shadow configure*/ - if ((sis_85c501.pci_conf[0x54] & val) ^ 0xf0) - { - sis_85c501.pci_conf[0x54] = val; - sis_85c501_recalcmapping(); - } - break; - } - - sis_85c501.pci_conf[addr] = val; -} - - -static void sis_85c503_write(int func, int addr, uint8_t val, void *p) -{ - if (func > 0) - return; - - if (addr >= 0x0f && addr < 0x41) - return; - - switch(addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x08; - val |= 0x07; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x41: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x42: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x43: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x44: - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - } - - sis_85c503.pci_conf[addr] = val; -} - - -static void sis_85c50x_isa_write(uint16_t port, uint8_t val, void *priv) -{ - if (port & 1) - { - if (sis_85c50x_isa.reg <= 0xB) sis_85c50x_isa.isa_conf[sis_85c50x_isa.reg] = val; - } - else - { - sis_85c50x_isa.reg = val; - } -} - - -static uint8_t sis_85c501_read(int func, int addr, void *p) -{ - if (func) - return 0xff; - - return sis_85c501.pci_conf[addr]; -} - - -static uint8_t sis_85c503_read(int func, int addr, void *p) -{ - if (func > 0) - return 0xff; - - return sis_85c503.pci_conf[addr]; -} - - -static uint8_t sis_85c50x_isa_read(uint16_t port, void *priv) -{ - if (port & 1) - { - if (sis_85c50x_isa.reg <= 0xB) - return sis_85c50x_isa.isa_conf[sis_85c50x_isa.reg]; - else - return 0xff; - } - else - { - return sis_85c50x_isa.reg; - } -} - -static void sis_85c501_reset(void) -{ - memset(&sis_85c501, 0, sizeof(sis_85c501_t)); - sis_85c501.pci_conf[0x00] = 0x39; /*SiS*/ - sis_85c501.pci_conf[0x01] = 0x10; - sis_85c501.pci_conf[0x02] = 0x06; /*501/502*/ - sis_85c501.pci_conf[0x03] = 0x04; - - sis_85c501.pci_conf[0x04] = 7; - sis_85c501.pci_conf[0x05] = 0; - - sis_85c501.pci_conf[0x06] = 0x80; - sis_85c501.pci_conf[0x07] = 0x02; - - sis_85c501.pci_conf[0x08] = 0; /*Device revision*/ - - sis_85c501.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - sis_85c501.pci_conf[0x0a] = 0x00; - sis_85c501.pci_conf[0x0b] = 0x06; - - sis_85c501.pci_conf[0x0e] = 0x00; /*Single function device*/ - - sis_85c501.pci_conf[0x50] = 0xbc; - sis_85c501.pci_conf[0x51] = 0xfb; - sis_85c501.pci_conf[0x52] = 0xad; - sis_85c501.pci_conf[0x53] = 0xfe; - - shadowbios = 1; -} - -static void sis_85c501_init(void) -{ - pci_add_card(0, sis_85c501_read, sis_85c501_write, NULL); - - sis_85c501_reset(); - - pci_reset_handler.pci_master_reset = NULL; -} - -static void sis_85c503_reset(void) -{ - memset(&sis_85c503, 0, sizeof(sis_85c503_t)); - sis_85c503.pci_conf[0x00] = 0x39; /*SiS*/ - sis_85c503.pci_conf[0x01] = 0x10; - sis_85c503.pci_conf[0x02] = 0x08; /*503*/ - sis_85c503.pci_conf[0x03] = 0x00; - - sis_85c503.pci_conf[0x04] = 7; - sis_85c503.pci_conf[0x05] = 0; - - sis_85c503.pci_conf[0x06] = 0x80; - sis_85c503.pci_conf[0x07] = 0x02; - - sis_85c503.pci_conf[0x08] = 0; /*Device revision*/ - - sis_85c503.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - sis_85c503.pci_conf[0x0a] = 0x01; - sis_85c503.pci_conf[0x0b] = 0x06; - - sis_85c503.pci_conf[0x0e] = 0x00; /*Single function device*/ - - sis_85c503.pci_conf[0x41] = sis_85c503.pci_conf[0x42] = sis_85c503.pci_conf[0x43] = sis_85c503.pci_conf[0x44] = 0x80; -} - -static void sis_85c503_init(int card) -{ - - pci_add_card(card, sis_85c503_read, sis_85c503_write, NULL); - - sis_85c503_reset(); - - trc_init(); - - port_92_reset(); - - port_92_add(); - - pci_reset_handler.pci_set_reset = sis_85c503_reset; -} - - -static void sis_85c50x_isa_init(void) -{ - memset(&sis_85c50x_isa, 0, sizeof(sis_85c50x_isa_t)); - - io_sethandler(0x22, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, NULL); -} diff --git a/src - Cópia/machine/m_at_t3100e.c b/src - Cópia/machine/m_at_t3100e.c deleted file mode 100644 index 6f62b7cf7..000000000 --- a/src - Cópia/machine/m_at_t3100e.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * 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. - * - * Implementation of the Toshiba T3100e. - * - * The Toshiba 3100e is a 286-based portable. - * - * To bring up the BIOS setup screen hold down the 'Fn' key - * on booting. - * - * Memory management - * ~~~~~~~~~~~~~~~~~ - * - * Motherboard memory is divided into: - * - Conventional memory: Either 512k or 640k - * - Upper memory: Either 512k or 384k, depending on - * amount of conventional memory. - * Upper memory can be used as EMS or XMS. - * - High memory: 0-4Mb, depending on RAM installed. - * The BIOS setup screen allows some or - * all of this to be used as EMS; the - * remainder is XMS. - * - * Additional memory (either EMS or XMS) can also be provided - * by ISA expansion cards. - * - * Under test in PCem, the BIOS will boot with up to 65368Kb - * of memory in total (16Mb less 16k). However it will give - * an error with RAM sizes above 8Mb, if any of the high - * memory is allocated as EMS, because the builtin EMS page - * registers can only access up to 8Mb. - * - * Memory is controlled by writes to I/O port 8084h: - * Bit 7: Always 0 } - * Bit 6: Always 1 } These bits select which motherboard - * Bit 5: Always 0 } function to access. - * Bit 4: Set to treat upper RAM as XMS - * Bit 3: Enable external RAM boards? - * Bit 2: Set for 640k conventional memory, clear for 512k - * Bit 1: Enable RAM beyond 1Mb. - * Bit 0: Enable EMS. - * - * The last value written to this port is saved at 0040:0093h, - * and in CMOS memory at offset 0x37. If the top bit of the - * CMOS byte is set, then high memory is being provided by - * an add-on card rather than the mainboard; accordingly, - * the BIOS will not allow high memory to be used as EMS. - * - * EMS is controlled by 16 page registers: - * - * Page mapped at 0xD000 0xD400 0xD800 0xDC00 - * ------------------------------------------------------ - * Pages 0x00-0x7F 0x208 0x4208 0x8208 0xc208 - * Pages 0x80-0xFF 0x218 0x4218 0x8218 0xc218 - * Pages 0x100-0x17F 0x258 0x4258 0x8258 0xc258 - * Pages 0x180-0x1FF 0x268 0x4268 0x8268 0xc268 - * - * The value written has bit 7 set to enable EMS, reset to - * disable it. - * - * So: - * OUT 0x208, 0x80 will page in the first 16k page at 0xD0000. - * OUT 0x208, 0x00 will page out EMS, leaving nothing at 0xD0000. - * OUT 0x4208, 0x80 will page in the first 16k page at 0xD4000. - * OUT 0x218, 0x80 will page in the 129th 16k page at 0xD0000. - * etc. - * - * To use EMS from DOS, you will need the Toshiba EMS driver - * (TOSHEMM.ZIP). This supports the above system, plus further - * ranges of ports at 0x_2A8, 0x_2B8, 0x_2C8. - * - * Features not implemented: - * > Four video fonts. - * > BIOS-controlled mapping of serial ports to IRQs. - * > Custom keyboard controller. This has a number of extra - * commands in the 0xB0-0xBC range, for such things as turbo - * on/off, and switching the keyboard between AT and PS/2 - * modes. Currently I have only implemented command 0xBB, - * so that self-test completes successfully. Commands include: - * - * 0xB0: Turbo on - * 0xB1: Turbo off - * 0xB2: Internal display on? - * 0xB3: Internal display off? - * 0xB5: Get settings byte (bottom bit is color/mono setting) - * 0xB6: Set settings byte - * 0xB7: Behave as 101-key PS/2 keyboard - * 0xB8: Behave as 84-key AT keyboard - * 0xBB: Return a byte, bit 2 is Fn key state, other bits unknown. - * - * The other main I/O port needed to POST is: - * 0x8084: System control. - * Top 3 bits give command, bottom 5 bits give parameters. - * 000 => set serial port IRQ / addresses - * bit 4: IRQ5 serial port base: 1 => 0x338, 0 => 0x3E8 - * bits 3, 2, 0 specify serial IRQs for COM1, COM2, COM3: - * 00 0 => 4, 3, 5 - * 00 1 => 4, 5, 3 - * 01 0 => 3, 4, 5 - * 01 1 => 3, 5, 4 - * 10 0 => 4, -, 3 - * 10 1 => 3, -, 4 - * 010 => set memory mappings - * bit 4 set if upper RAM is XMS - * bit 3 enable add-on memory boards beyond 5Mb? - * bit 2 set for 640k sysram, clear for 512k sysram - * bit 1 enable mainboard XMS - * bit 0 enable mainboard EMS - * 100 => set parallel mode / LCD settings - * bit 4 set for bidirectional parallel port - * bit 3 set to disable internal CGA - * bit 2 set for single-pixel LCD font - * bits 0,1 for display font - * - * Version: @(#)m_at_t3100e.c 1.0.5 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mouse.h" -#include "../mem.h" -#include "../device.h" -#include "../keyboard.h" -#include "../cpu/cpu.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "machine.h" -#include "m_at_t3100e.h" - - -extern uint8_t *ram; /* Physical RAM */ - -void at_init(); - - -/* The T3100e motherboard can (and does) dynamically reassign RAM between - * conventional, XMS and EMS. This translates to monkeying with the mappings. - */ - -extern mem_mapping_t base_mapping; - -extern mem_mapping_t ram_low_mapping; /* This is to switch conventional RAM - * between 512k and 640k */ - -extern mem_mapping_t ram_mid_mapping; /* This will not be used */ - -extern mem_mapping_t ram_high_mapping; /* This is RAM beyond 1Mb if any */ - -extern uint8_t *ram; - -static unsigned t3100e_ems_page_reg[] = -{ - 0x208, 0x4208, 0x8208, 0xc208, /* The first four map the first 2Mb */ - /* of RAM into the page frame */ - 0x218, 0x4218, 0x8218, 0xc218, /* The next four map the next 2Mb */ - /* of RAM */ - 0x258, 0x4258, 0x8258, 0xc258, /* and so on. */ - 0x268, 0x4268, 0x8268, 0xc268, -}; - -struct t3100e_ems_regs -{ - uint8_t page[16]; - mem_mapping_t mapping[4]; - uint32_t page_exec[4]; /* Physical location of memory pages */ - uint32_t upper_base; /* Start of upper RAM */ - uint8_t upper_pages; /* Pages of EMS available from upper RAM */ - uint8_t upper_is_ems; /* Upper RAM is EMS? */ - mem_mapping_t upper_mapping; - uint8_t notify; /* Notification from keyboard controller */ - uint8_t turbo; /* 0 for 6MHz, else full speed */ - uint8_t mono; /* Emulates PC/AT 'mono' motherboard switch */ - /* Bit 0 is 0 for colour, 1 for mono */ -} t3100e_ems; - -void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); - - -#ifdef ENABLE_T3100E_LOG -int t3100e_do_log = ENABLE_T3100E_LOG; -#endif - - -static void -t3100e_log(const char *fmt, ...) -{ -#ifdef ENABLE_T3100E_LOG - va_list ap; - - if (t3100e_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Given a memory address (which ought to be in the page frame at 0xD0000), - * which page does it relate to? */ -static int addr_to_page(uint32_t addr) -{ - if ((addr & 0xF0000) == 0xD0000) - { - return ((addr >> 14) & 3); - } - return -1; -} - -/* And vice versa: Given a page slot, which memory address does it - * correspond to? */ -static uint32_t page_to_addr(int pg) -{ - return 0xD0000 + ((pg & 3) * 16384); -} - -/* Given an EMS page ID, return its physical address in RAM. */ -uint32_t t3100e_ems_execaddr(struct t3100e_ems_regs *regs, - int pg, uint16_t val) -{ - uint32_t addr; - - if (!(val & 0x80)) return 0; /* Bit 7 reset => not mapped */ - - val &= 0x7F; - val += (0x80 * (pg >> 2)); /* The high bits of the register bank */ - /* are used to extend val to allow up */ - /* to 8Mb of EMS to be accessed */ - - /* Is it in the upper memory range? */ - if (regs->upper_is_ems) - { - if (val < regs->upper_pages) - { - addr = regs->upper_base + 0x4000 * val; - return addr; - } - val -= regs->upper_pages; - } - /* Otherwise work down from the top of high RAM (so, the more EMS, - * the less XMS) */ - if ((val * 0x4000) + 0x100000 >= (mem_size * 1024)) - { - return 0; /* Not enough high RAM for this page */ - } - /* High RAM found */ - addr = (mem_size * 1024) - 0x4000 * (val + 1); - - return addr; -} - - -/* The registers governing the EMS ports are in rather a nonintuitive order */ -static int port_to_page(uint16_t addr) -{ - switch (addr) - { - case 0x208: return 0; - case 0x4208: return 1; - case 0x8208: return 2; - case 0xC208: return 3; - case 0x218: return 4; - case 0x4218: return 5; - case 0x8218: return 6; - case 0xC218: return 7; - case 0x258: return 8; - case 0x4258: return 9; - case 0x8258: return 10; - case 0xC258: return 11; - case 0x268: return 12; - case 0x4268: return 13; - case 0x8268: return 14; - case 0xC268: return 15; - } - return -1; -} - -/* Used to dump the memory mapping table, for debugging -void dump_mappings() -{ - mem_mapping_t *mm = base_mapping.next; - - if (!t3100e_log) return; - while (mm) - { - const char *name = ""; - uint32_t offset = (uint32_t)(mm->exec - ram); - - if (mm == &ram_low_mapping ) name = "LOW "; - if (mm == &ram_mid_mapping ) name = "MID "; - if (mm == &ram_high_mapping) name = "HIGH"; - if (mm == &t3100e_ems.upper_mapping) name = "UPPR"; - if (mm == &t3100e_ems.mapping[0]) - { - name = "EMS0"; - offset = t3100e_ems.page_exec[0]; - } - if (mm == &t3100e_ems.mapping[1]) - { - name = "EMS1"; - offset = t3100e_ems.page_exec[1]; - } - if (mm == &t3100e_ems.mapping[2]) - { - name = "EMS2"; - offset = t3100e_ems.page_exec[2]; - } - if (mm == &t3100e_ems.mapping[3]) - { - name = "EMS3"; - offset = t3100e_ems.page_exec[3]; - } - - t3100e_log(" %p | base=%05x size=%05x %c @ %06x %s\n", mm, - mm->base, mm->size, mm->enable ? 'Y' : 'N', - offset, name); - - mm = mm->next; - } -}*/ - -void t3100e_map_ram(uint8_t val) -{ - int n; - int32_t upper_len; - - t3100e_log("OUT 0x8084, %02x [ set memory mapping :", val | 0x40); - if (val & 1) t3100e_log("ENABLE_EMS "); - if (val & 2) t3100e_log("ENABLE_XMS "); - if (val & 4) t3100e_log("640K "); - if (val & 8) t3100e_log("X8X "); - if (val & 16) t3100e_log("UPPER_IS_XMS "); - t3100e_log("\n"); - - /* Bit 2 controls size of conventional memory */ - if (val & 4) - { - t3100e_ems.upper_base = 0xA0000; - t3100e_ems.upper_pages = 24; - } - else - { - t3100e_ems.upper_base = 0x80000; - t3100e_ems.upper_pages = 32; - } - upper_len = t3100e_ems.upper_pages * 16384; - - mem_mapping_set_addr(&ram_low_mapping, 0, t3100e_ems.upper_base); - /* Bit 0 set if upper RAM is EMS */ - t3100e_ems.upper_is_ems = (val & 1); - - /* Bit 1 set if high RAM is enabled */ - if (val & 2) - { - mem_mapping_enable(&ram_high_mapping); - } - else - { - mem_mapping_disable(&ram_high_mapping); - } - - /* Bit 4 set if upper RAM is mapped to high memory - * (and bit 1 set if XMS enabled) */ - if ((val & 0x12) == 0x12) - { - mem_mapping_set_addr(&t3100e_ems.upper_mapping, - mem_size * 1024, - upper_len); - mem_mapping_enable(&t3100e_ems.upper_mapping); - mem_mapping_set_exec(&t3100e_ems.upper_mapping, ram + t3100e_ems.upper_base); - } - else - { - mem_mapping_disable(&t3100e_ems.upper_mapping); - } - /* Recalculate EMS mappings */ - for (n = 0; n < 4; n++) - { - t3100e_ems_out(t3100e_ems_page_reg[n], t3100e_ems.page[n], - &t3100e_ems); - } - - //dump_mappings(); -} - - -void t3100e_notify_set(uint8_t value) -{ - t3100e_ems.notify = value; -} - -void t3100e_mono_set(uint8_t value) -{ - t3100e_ems.mono = value; -} - -uint8_t t3100e_mono_get(void) -{ - return t3100e_ems.mono; -} - -void t3100e_turbo_set(uint8_t value) -{ - t3100e_ems.turbo = value; - if (!value) - { - cpu_dynamic_switch(0); /* 286/6 */ - } - else - { - cpu_dynamic_switch(cpu); - } -} - - - -uint8_t t3100e_sys_in(uint16_t addr, void *p) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - - /* The low 4 bits always seem to be 0x0C. The high 4 are a - * notification sent by the keyboard controller when it detects - * an [Fn] key combination */ - t3100e_log("IN 0x8084\n"); - return 0x0C | (regs->notify << 4); -} - - - -/* Handle writes to the T3100e system control port at 0x8084 */ -void t3100e_sys_out(uint16_t addr, uint8_t val, void *p) -{ -// struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - - switch (val & 0xE0) - { - case 0x00: /* Set serial port IRQs. Not implemented */ - t3100e_log("OUT 0x8084, %02x [ set serial port IRQs]\n", val); - break; - case 0x40: /* Set RAM mappings. */ - t3100e_map_ram(val & 0x1F); - break; - - case 0x80: /* Set video options. */ - t3100e_video_options_set(val & 0x1F); break; - - /* Other options not implemented. */ - default: t3100e_log("OUT 0x8084, %02x\n", val); break; - } -} - - -uint8_t t3100e_config_get(void) -{ -/* The byte returned: - Bit 7: Set if internal plasma display enabled - Bit 6: Set if running at 6MHz, clear at full speed - Bit 5: Always 1? - Bit 4: Set if the FD2MB jumper is present (internal floppy is ?tri-mode) - Bit 3: Clear if the FD2 jumper is present (two internal floppies) - Bit 2: Set if the internal drive is A:, clear if B: - Bit 1: Set if the parallel port is configured as a floppy connector - for the second drive. - Bit 0: Set if the F2HD jumper is present (internal floppy is 720k) - */ - uint8_t value = 0x28; /* Start with bits 5 and 3 set. */ - - int type_a = fdd_get_type(0); - int type_b = fdd_get_type(1); - int prt_switch; /* External drive type: 0=> none, 1=>A, 2=>B */ - -/* Get display setting */ - if (t3100e_display_get()) value |= 0x80; - if (!t3100e_ems.turbo) value |= 0x40; - -/* Try to determine the floppy types.*/ - - prt_switch = (type_b ? 2 : 0); - switch(type_a) - { -/* Since a T3100e cannot have an internal 5.25" drive, mark 5.25" A: drive as - * being external, and set the internal type based on type_b. */ - case 1: /* 360k */ - case 2: /* 1.2Mb */ - case 3: /* 1.2Mb RPMx2*/ - prt_switch = 1; /* External drive is A: */ - switch (type_b) - { - case 1: /* 360k */ - case 4: value |= 1; break; /* 720k */ - case 6: value |= 0x10; break; /* Tri-mode */ - /* All others will be treated as 1.4M */ - } - break; - case 4: value |= 0x01; /* 720k */ - if (type_a == type_b) - { - value &= (~8); /* Two internal drives */ - prt_switch = 0; /* No external drive */ - } - break; - case 5: /* 1.4M */ - case 7: /* 2.8M */ - if (type_a == type_b) - { - value &= (~8); /* Two internal drives */ - prt_switch = 0; /* No external drive */ - } - break; - case 6: /* 3-mode */ - value |= 0x10; - if (type_a == type_b) - { - value &= (~8); /* Two internal drives */ - prt_switch = 0; /* No external drive */ - } - break; - } /* End switch */ - switch (prt_switch) - { - case 0: value |= 4; break; /* No external floppy */ - case 1: value |= 2; break; /* External floppy is A: */ - case 2: value |= 6; break; /* External floppy is B: */ - } - return value; -} - - -/* Read EMS page register */ -uint8_t t3100e_ems_in(uint16_t addr, void *p) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - - return regs->page[port_to_page(addr)]; - -} - -/* Write EMS page register */ -void t3100e_ems_out(uint16_t addr, uint8_t val, void *p) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - int pg = port_to_page(addr); - - regs->page_exec[pg & 3] = t3100e_ems_execaddr(regs, pg, val); - t3100e_log("EMS: page %d %02x -> %02x [%06x]\n", - pg, regs->page[pg], val, regs->page_exec[pg & 3]); - regs->page[pg] = val; - - pg &= 3; -/* Bit 7 set if page is enabled, reset if page is disabled */ - if (regs->page_exec[pg]) - { - t3100e_log("Enabling EMS RAM at %05x\n", - page_to_addr(pg)); - mem_mapping_enable(®s->mapping[pg]); - mem_mapping_set_exec(®s->mapping[pg], ram + regs->page_exec[pg]); - } - else - { - t3100e_log("Disabling EMS RAM at %05x\n", - page_to_addr(pg)); - mem_mapping_disable(®s->mapping[pg]); - } -} - - -/* Read RAM in the EMS page frame */ -static uint8_t ems_read_ram(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return 0xFF; - addr = regs->page_exec[pg] + (addr & 0x3FFF); - return ram[addr]; -} - - - - -static uint16_t ems_read_ramw(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return 0xFF; - //t3100e_log("ems_read_ramw addr=%05x ", addr); - addr = regs->page_exec[pg] + (addr & 0x3FFF); - //t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); - return *(uint16_t *)&ram[addr]; -} - - -static uint32_t ems_read_raml(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return 0xFF; - addr = regs->page_exec[pg] + (addr & 0x3FFF); - return *(uint32_t *)&ram[addr]; -} - -/* Write RAM in the EMS page frame */ -static void ems_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - addr = regs->page_exec[pg] + (addr & 0x3FFF); - ram[addr] = val; -} - - -static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - //t3100e_log("ems_write_ramw addr=%05x ", addr); - addr = regs->page_exec[pg] + (addr & 0x3FFF); - //t3100e_log("-> %06x val=%04x\n", addr, val); - - *(uint16_t *)&ram[addr] = val; -} - - -static void ems_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - addr = regs->page_exec[pg] + (addr & 0x3FFF); - *(uint32_t *)&ram[addr] = val; -} - - - -/* Read RAM in the upper area. This is basically what the 'remapped' - * mapping in mem.c does, except that the upper area can move around */ -static uint8_t upper_read_ram(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return ram[addr]; -} - -static uint16_t upper_read_ramw(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return *(uint16_t *)&ram[addr]; -} - -static uint32_t upper_read_raml(uint32_t addr, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return *(uint32_t *)&ram[addr]; -} - - -static void upper_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - ram[addr] = val; -} - - -static void upper_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - *(uint16_t *)&ram[addr] = val; -} - - - -static void upper_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - - addr = (addr - (1024 * mem_size)) + regs->upper_base; - *(uint32_t *)&ram[addr] = val; -} - - - - -void machine_at_t3100e_init(const machine_t *model) -{ - int pg; - - memset(&t3100e_ems, 0, sizeof(t3100e_ems)); - - machine_at_common_ide_init(model); - - device_add(&keyboard_at_toshiba_device); - device_add(&fdc_at_device); - - /* Hook up system control port */ - io_sethandler(0x8084, 0x0001, - t3100e_sys_in, NULL, NULL, - t3100e_sys_out, NULL, NULL, &t3100e_ems); - - /* Start monitoring all 16 EMS registers */ - for (pg = 0; pg < 16; pg++) - { - io_sethandler(t3100e_ems_page_reg[pg], 0x0001, - t3100e_ems_in, NULL, NULL, - t3100e_ems_out, NULL, NULL, &t3100e_ems); - } - - /* Map the EMS page frame */ - for (pg = 0; pg < 4; pg++) - { - t3100e_log("Adding memory map at %x for page %d\n", page_to_addr(pg), pg); - mem_mapping_add(&t3100e_ems.mapping[pg], - page_to_addr(pg), 16384, - ems_read_ram, ems_read_ramw, ems_read_raml, - ems_write_ram, ems_write_ramw, ems_write_raml, - NULL, MEM_MAPPING_EXTERNAL, - &t3100e_ems); - /* Start them all off disabled */ - mem_mapping_disable(&t3100e_ems.mapping[pg]); - } - /* Mapping for upper RAM when in use as XMS*/ - mem_mapping_add(&t3100e_ems.upper_mapping, mem_size * 1024, 384 * 1024, - upper_read_ram, upper_read_ramw, upper_read_raml, - upper_write_ram, upper_write_ramw, upper_write_raml, - NULL, MEM_MAPPING_INTERNAL, &t3100e_ems); - mem_mapping_disable(&t3100e_ems.upper_mapping); - - device_add(&t3100e_device); -} diff --git a/src - Cópia/machine/m_at_t3100e.h b/src - Cópia/machine/m_at_t3100e.h deleted file mode 100644 index e92d23b73..000000000 --- a/src - Cópia/machine/m_at_t3100e.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 Toshiba T3100e system. - * - * Version: @(#)m_at_t3100e.h 1.0.3 2018/03/18 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 MACHINE_T3100E_H -# define MACHINE_T3100E_H - - -extern const device_t t3100e_device; - - -extern void t3100e_notify_set(uint8_t value); -extern void t3100e_display_set(uint8_t value); -extern uint8_t t3100e_display_get(void); -extern uint8_t t3100e_config_get(void); -extern void t3100e_turbo_set(uint8_t value); -extern uint8_t t3100e_mono_get(void); -extern void t3100e_mono_set(uint8_t value); - -extern void t3100e_video_options_set(uint8_t options); -extern void t3100e_display_set(uint8_t internal); - - -#endif /*MACHINE_T3100E_H*/ diff --git a/src - Cópia/machine/m_at_t3100e_vid.c b/src - Cópia/machine/m_at_t3100e_vid.c deleted file mode 100644 index 55abf3149..000000000 --- a/src - Cópia/machine/m_at_t3100e_vid.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * 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. - * - * Implementation of the Toshiba 3100e plasma display. - * This display has a fixed 640x400 resolution. - * - * T3100e CRTC regs (from the ROM): - * - * Selecting a character height of 3 seems to be sufficient to - * convert the 640x200 graphics mode to 640x400 (and, by - * analogy, 320x200 to 320x400). - * - * Horiz-----> Vert------> I ch - * 38 28 2D 0A 1F 06 19 1C 02 07 06 07 CO40 - * 71 50 5A 0A 1F 06 19 1C 02 07 06 07 CO80 - * 38 28 2D 0A 7F 06 64 70 02 01 06 07 Graphics - * 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO - * 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400 - * - * Version: @(#)m_at_t3100e_vid.c 1.0.6 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#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 "m_at_t3100e.h" - - -#define T3100E_XSIZE 640 -#define T3100E_YSIZE 400 - - -/* Mapping of attributes to colours */ -static uint32_t amber, black; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ -static uint32_t blinkcols[256][2]; -static uint32_t normcols[256][2]; - -/* Video options set by the motherboard; they will be picked up by the card - * on the next poll. - * - * Bit 3: Disable built-in video (for add-on card) - * Bit 2: Thin font - * Bits 0,1: Font set (not currently implemented) - */ -static uint8_t st_video_options; -static int8_t st_display_internal = -1; - -void t3100e_video_options_set(uint8_t options) -{ - st_video_options = options; -} - -void t3100e_display_set(uint8_t internal) -{ - st_display_internal = internal; -} - -uint8_t t3100e_display_get() -{ - return st_display_internal; -} - - -typedef struct t3100e_t -{ - mem_mapping_t mapping; - - cga_t cga; /* The CGA is used for the external - * display; most of its registers are - * ignored by the plasma display. */ - - int font; /* Current font, 0-3 */ - int enabled; /* Hardware enabled, 0 or 1 */ - int internal; /* Using internal display? */ - uint8_t attrmap; /* Attribute mapping register */ - - int dispontime, dispofftime; - - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; - - uint8_t *vram; -} t3100e_t; - - -void t3100e_recalctimings(t3100e_t *t3100e); -void t3100e_write(uint32_t addr, uint8_t val, void *p); -uint8_t t3100e_read(uint32_t addr, void *p); -void t3100e_recalcattrs(t3100e_t *t3100e); - - -void t3100e_out(uint16_t addr, uint8_t val, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - switch (addr) - { - /* Emulated CRTC, register select */ - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - cga_out(addr, val, &t3100e->cga); - break; - - /* Emulated CRTC, value */ - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - /* Register 0x12 controls the attribute mappings for the - * plasma screen. */ - if (t3100e->cga.crtcreg == 0x12) - { - t3100e->attrmap = val; - t3100e_recalcattrs(t3100e); - return; - } - cga_out(addr, val, &t3100e->cga); - - t3100e_recalctimings(t3100e); - return; - - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t3100e->cga); - return; - /* CGA colour register */ - case 0x3D9: - cga_out(addr, val, &t3100e->cga); - return; - } -} - -uint8_t t3100e_in(uint16_t addr, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - uint8_t val; - - switch (addr) - { - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - if (t3100e->cga.crtcreg == 0x12) - { - val = t3100e->attrmap & 0x0F; - if (t3100e->internal) val |= 0x30; /* Plasma / CRT */ - return val; - } - } - - return cga_in(addr, &t3100e->cga); -} - - - - -void t3100e_write(uint32_t addr, uint8_t val, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - egawrites++; - - t3100e->vram[addr & 0x7fff] = val; - cycles -= 4; -} - - - -uint8_t t3100e_read(uint32_t addr, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - egareads++; - cycles -= 4; - - return t3100e->vram[addr & 0x7fff]; -} - - - -void t3100e_recalctimings(t3100e_t *t3100e) -{ - double disptime; - double _dispontime, _dispofftime; - - if (!t3100e->internal) - { - cga_recalctimings(&t3100e->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t3100e->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t3100e->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -/* Draw a row of text in 80-column mode */ -void t3100e_text_row80(t3100e_t *t3100e) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; - - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2; - ma += (t3100e->displine >> 4) * 80; - - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); - } - for (x = 0; x < 80; x++) - { - chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; - attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && - (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t3100e->video_options & 4) - bold = boldcols[attr] ? chr + 256 : chr; - else - bold = boldcols[attr] ? chr : chr + 256; - bold += 512 * (t3100e->video_options & 3); - - if (t3100e->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -void t3100e_text_row40(t3100e_t *t3100e) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; - - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2; - ma += (t3100e->displine >> 4) * 40; - - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); - } - for (x = 0; x < 40; x++) - { - chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; - attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && - (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t3100e->video_options & 4) - bold = boldcols[attr] ? chr + 256 : chr; - else bold = boldcols[attr] ? chr : chr + 256; - bold += 512 * (t3100e->video_options & 3); - - if (t3100e->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } - else - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2+1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - - - - -/* Draw a line in CGA 640x200 or T3100e 640x400 mode */ -void t3100e_cgaline6(t3100e_t *t3100e) -{ - int x, c; - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (t3100e->cga.cgacol & 0x0F) ? amber : black; - uint32_t bg = black; - - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - - if (t3100e->cga.crtc[9] == 3) /* 640*400 */ - { - addr = ((t3100e->displine) & 1) * 0x2000 + - ((t3100e->displine >> 1) & 1) * 0x4000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - else - { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - for (x = 0; x < 80; x++) - { - dat = t3100e->vram[addr & 0x7FFF]; - addr++; - - for (c = 0; c < 8; c++) - { - ink = (dat & 0x80) ? fg : bg; - if (!(t3100e->cga.cgamode & 8)) ink = black; - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+c] = ink; - dat = dat << 1; - } - } -} - - -/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to - * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ -void t3100e_cgaline4(t3100e_t *t3100e) -{ - int x, c; - uint8_t dat, pattern; - uint32_t ink0 = 0, ink1 = 0; - uint16_t addr; - - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - if (t3100e->cga.crtc[9] == 3) /* 320*400 undocumented */ - { - addr = ((t3100e->displine) & 1) * 0x2000 + - ((t3100e->displine >> 1) & 1) * 0x4000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - else /* 320*200 */ - { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - for (x = 0; x < 80; x++) - { - dat = t3100e->vram[addr & 0x7FFF]; - addr++; - - for (c = 0; c < 4; c++) - { - pattern = (dat & 0xC0) >> 6; - if (!(t3100e->cga.cgamode & 8)) pattern = 0; - - switch (pattern & 3) - { - case 0: ink0 = ink1 = black; break; - case 1: if (t3100e->displine & 1) - { - ink0 = black; ink1 = black; - } - else - { - ink0 = amber; ink1 = black; - } - break; - case 2: if (t3100e->displine & 1) - { - ink0 = black; ink1 = amber; - } - else - { - ink0 = amber; ink1 = black; - } - break; - case 3: ink0 = ink1 = amber; break; - - } - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c] = ink0; - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c+1] = ink1; - dat = dat << 2; - } - } -} - - - - - - -void t3100e_poll(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - if (t3100e->video_options != st_video_options) - { - t3100e->video_options = st_video_options; - - if (t3100e->video_options & 8) /* Disable internal CGA */ - mem_mapping_disable(&t3100e->mapping); - else mem_mapping_enable(&t3100e->mapping); - - /* Set the font used for the external display */ - t3100e->cga.fontbase = (512 * (t3100e->video_options & 3)) - + ((t3100e->video_options & 4) ? 256 : 0); - - } - /* Switch between internal plasma and external CRT display. */ - if (st_display_internal != -1 && st_display_internal != t3100e->internal) - { - t3100e->internal = st_display_internal; - t3100e_recalctimings(t3100e); - } - if (!t3100e->internal) - { - cga_poll(&t3100e->cga); - return; - } - - - if (!t3100e->linepos) - { - t3100e->cga.vidtime += t3100e->dispofftime; - t3100e->cga.cgastat |= 1; - t3100e->linepos = 1; - if (t3100e->dispon) - { - if (t3100e->displine == 0) - { - video_wait_for_buffer(); - } - - /* Graphics */ - if (t3100e->cga.cgamode & 0x02) - { - if (t3100e->cga.cgamode & 0x10) - t3100e_cgaline6(t3100e); - else t3100e_cgaline4(t3100e); - } - else - if (t3100e->cga.cgamode & 0x01) /* High-res text */ - { - t3100e_text_row80(t3100e); - } - else - { - t3100e_text_row40(t3100e); - } - } - t3100e->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (t3100e->displine == 400) /* Start of VSYNC */ - { - t3100e->cga.cgastat |= 8; - t3100e->dispon = 0; - } - if (t3100e->displine == 416) /* End of VSYNC */ - { - t3100e->displine = 0; - t3100e->cga.cgastat &= ~8; - t3100e->dispon = 1; - } - } - else - { - if (t3100e->dispon) - { - t3100e->cga.cgastat &= ~1; - } - t3100e->cga.vidtime += t3100e->dispontime; - t3100e->linepos = 0; - - if (t3100e->displine == 400) - { -/* Hardcode 640x400 window size */ - if (T3100E_XSIZE != xsize || T3100E_YSIZE != ysize) - { - xsize = T3100E_XSIZE; - ysize = T3100E_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 640x400 resolution */ - video_res_x = T3100E_XSIZE; - video_res_y = T3100E_YSIZE; - - if (t3100e->cga.cgamode & 0x02) - { - if (t3100e->cga.cgamode & 0x10) - video_bpp = 1; - else video_bpp = 2; - - } - else video_bpp = 0; - t3100e->cga.cgablink++; - } - } -} - - - -void t3100e_recalcattrs(t3100e_t *t3100e) -{ - int n; - - /* val behaves as follows: - * Bit 0: Attributes 01-06, 08-0E are inverse video - * Bit 1: Attributes 01-06, 08-0E are bold - * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are inverse video - * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are bold */ - - /* Set up colours */ - amber = makecol(0xf7, 0x7C, 0x34); - black = makecol(0x17, 0x0C, 0x00); - - /* Initialise the attribute mapping. Start by defaulting everything - * to black on amber, and with bold set by bit 3 */ - for (n = 0; n < 256; n++) - { - boldcols[n] = (n & 8) != 0; - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } - - /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the - * passed value. Exclude x0 and x8, which are always black on - * amber. */ - for (n = 0x11; n <= 0xFF; n++) - { - if ((n & 7) == 0) continue; - if (t3100e->attrmap & 4) /* Inverse */ - { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } - else /* Normal */ - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - } - if (t3100e->attrmap & 8) boldcols[n] = 1; /* Bold */ - } - /* Set up the 01-0E range, controlled by bits 0 and 1 of the - * passed value. When blinking is enabled this also affects 81-8E. */ - for (n = 0x01; n <= 0x0E; n++) - { - if (n == 7) continue; - if (t3100e->attrmap & 1) - { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - blinkcols[n+128][0] = amber; - blinkcols[n+128][1] = black; - } - else - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = black; - blinkcols[n+128][1] = amber; - } - if (t3100e->attrmap & 2) boldcols[n] = 1; - } - /* Colours 07 and 0F are always amber on black. If blinking is - * enabled so are 87 and 8F. */ - for (n = 0x07; n <= 0x0F; n += 8) - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = black; - blinkcols[n+128][1] = amber; - } - /* When not blinking, colours 81-8F are always amber on black. */ - for (n = 0x81; n <= 0x8F; n ++) - { - normcols[n][0] = black; - normcols[n][1] = amber; - boldcols[n] = (n & 0x08) != 0; - } - - - /* Finally do the ones which are solid black. These differ between - * the normal and blinking mappings */ - for (n = 0; n <= 0xFF; n += 0x11) - { - normcols[n][0] = normcols[n][1] = black; - } - /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */ - for (n = 0; n <= 0x77; n += 0x11) - { - blinkcols[n][0] = blinkcols[n][1] = black; - blinkcols[n+128][0] = blinkcols[n+128][1] = black; - } -} - - -void *t3100e_init(const device_t *info) -{ - t3100e_t *t3100e = malloc(sizeof(t3100e_t)); - memset(t3100e, 0, sizeof(t3100e_t)); - cga_init(&t3100e->cga); - - t3100e->internal = 1; - - /* 32k video RAM */ - t3100e->vram = malloc(0x8000); - - timer_add(t3100e_poll, &t3100e->cga.vidtime, TIMER_ALWAYS_ENABLED, t3100e); - - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, t3100e_in, NULL, NULL, t3100e_out, NULL, NULL, t3100e); - - /* Default attribute mapping is 4 */ - t3100e->attrmap = 4; - t3100e_recalcattrs(t3100e); - -/* Start off in 80x25 text mode */ - t3100e->cga.cgastat = 0xF4; - t3100e->cga.vram = t3100e->vram; - t3100e->enabled = 1; - t3100e->video_options = 0xFF; - return t3100e; -} - -void t3100e_close(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - free(t3100e->vram); - free(t3100e); -} - -void t3100e_speed_changed(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - t3100e_recalctimings(t3100e); -} - -const device_t t3100e_device = -{ - "Toshiba T3100e", - 0, - 0, - t3100e_init, - t3100e_close, - NULL, - NULL, - t3100e_speed_changed, - NULL -}; diff --git a/src - Cópia/machine/m_at_wd76c10.c b/src - Cópia/machine/m_at_wd76c10.c deleted file mode 100644 index 670edb6d9..000000000 --- a/src - Cópia/machine/m_at_wd76c10.c +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_paradise.h" -#include "machine.h" - - -static uint16_t wd76c10_0092; -static uint16_t wd76c10_2072; -static uint16_t wd76c10_2872; -static uint16_t wd76c10_5872; - - -static fdc_t *wd76c10_fdc; - - -static uint16_t -wd76c10_read(uint16_t port, void *priv) -{ - switch (port) - { - case 0x0092: - return wd76c10_0092; - - case 0x2072: - return wd76c10_2072; - - case 0x2872: - return wd76c10_2872; - - case 0x5872: - return wd76c10_5872; - } - return 0; -} - - -static void -wd76c10_write(uint16_t port, uint16_t val, void *priv) -{ - switch (port) - { - case 0x0092: - wd76c10_0092 = val; - - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - - case 0x2072: - wd76c10_2072 = val; - - serial_remove(1); - if (!(val & 0x10)) - { - switch ((val >> 5) & 7) - { - case 1: serial_setup(1, 0x3f8, 4); break; - case 2: serial_setup(1, 0x2f8, 4); break; - case 3: serial_setup(1, 0x3e8, 4); break; - case 4: serial_setup(1, 0x2e8, 4); break; - default: serial_remove(1); break; - } - } - serial_remove(2); - if (!(val & 0x01)) - { - switch ((val >> 1) & 7) - { - case 1: serial_setup(2, 0x3f8, 3); break; - case 2: serial_setup(2, 0x2f8, 3); break; - case 3: serial_setup(2, 0x3e8, 3); break; - case 4: serial_setup(2, 0x2e8, 3); break; - default: serial_remove(1); break; - } - } - break; - - case 0x2872: - wd76c10_2872 = val; - - fdc_remove(wd76c10_fdc); - if (!(val & 1)) - fdc_set_base(wd76c10_fdc, 0x03f0); - break; - - case 0x5872: - wd76c10_5872 = val; - break; - } -} - - -static uint8_t -wd76c10_readb(uint16_t port, void *priv) -{ - if (port & 1) - return wd76c10_read(port & ~1, priv) >> 8; - return wd76c10_read(port, priv) & 0xff; -} - - -static void -wd76c10_writeb(uint16_t port, uint8_t val, void *priv) -{ - uint16_t temp = wd76c10_read(port, priv); - if (port & 1) - wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv); - else - wd76c10_write(port , (temp & 0xff00) | val, priv); -} - - -static void wd76c10_init(void) -{ - io_sethandler(0x0092, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2072, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2872, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x5872, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); -} - - -void -machine_at_wd76c10_init(const machine_t *model) -{ - machine_at_common_ide_init(model); - - device_add(&keyboard_ps2_quadtel_device); - wd76c10_fdc = device_add(&fdc_at_device); - - wd76c10_init(); - - device_add(¶dise_wd90c11_megapc_device); -} diff --git a/src - Cópia/machine/m_europc.c b/src - Cópia/machine/m_europc.c deleted file mode 100644 index 8a6f94d43..000000000 --- a/src - Cópia/machine/m_europc.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * 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. - * - * Implementation of the Schneider EuroPC system. - * - * NOTES: BIOS info (taken from MAME, thanks guys!!) - * - * f000:e107 bios checksum test - * memory test - * f000:e145 irq vector init - * f000:e156 - * f000:e169-d774 test of special registers 254/354 - * f000:e16c-e817 - * f000:e16f - * f000:ec08 test of special registers 800a rtc time - * or date error, rtc corrected - * f000:ef66 0xf - * f000:db3e 0x8..0xc - * f000:d7f8 - * f000:db5f - * f000:e172 - * f000:ecc5 801a video setup error - * f000:d6c9 copyright output - * f000:e1b7 - * f000:e1be DI bits set mean output text!!! (801a) - * f000: 0x8000 output - * 1 rtc error - * 2 rtc time or date error - * 4 checksum error in setup - * 8 rtc status corrected - * 10 video setup error - * 20 video ram bad - * 40 monitor type not recogniced - * 80 mouse port enabled - * 100 joystick port enabled - * f000:e1e2-dc0c CPU speed is 4.77 mhz - * f000:e1e5-f9c0 keyboard processor error - * f000:e1eb-c617 external lpt1 at 0x3bc - * f000:e1ee-e8ee external coms at - * - * Routines: - * f000:c92d output text at bp - * f000:db3e RTC read reg cl - * f000:e8ee piep - * f000:e95e RTC write reg cl - * polls until JIM 0xa is zero, - * output cl at jim 0xa - * write ah hinibble as lownibble into jim 0xa - * write ah lownibble into jim 0xa - * f000:ef66 RTC read reg cl - * polls until jim 0xa is zero, - * output cl at jim 0xa - * read low 4 nibble at jim 0xa - * read low 4 nibble at jim 0xa - * return first nibble<<4|second nibble in ah - * f000:f046 seldom compares ret - * f000:fe87 0 -> ds - * - * Memory: - * 0000:0469 bit 0: b0000 memory available - * bit 1: b8000 memory available - * 0000:046a: 00 jim 250 01 jim 350 - * - * WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK. - * - * Version: @(#)europc.c 1.0.6 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Inspired by the "jim.c" file originally present, but a - * fully re-written module, based on the information from - * Schneider's schematics and technical manuals, and the - * input from people with real EuroPC hardware. - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../nmi.h" -#include "../mem.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 "machine.h" - - -#define EUROPC_DEBUG 0 /* current debugging level */ - - -/* M3002 RTC chip registers. */ -#define MRTC_SECONDS 0x00 /* BCD, 00-59 */ -#define MRTC_MINUTES 0x01 /* BCD, 00-59 */ -#define MRTC_HOURS 0x02 /* BCD, 00-23 */ -#define MRTC_DAYS 0x03 /* BCD, 01-31 */ -#define MRTC_MONTHS 0x04 /* BCD, 01-12 */ -#define MRTC_YEARS 0x05 /* BCD, 00-99 (year only) */ -#define MRTC_WEEKDAY 0x06 /* BCD, 01-07 */ -#define MRTC_WEEKNO 0x07 /* BCD, 01-52 */ -#define MRTC_CONF_A 0x08 /* EuroPC config, binary */ -#define MRTC_CONF_B 0x09 /* EuroPC config, binary */ -#define MRTC_CONF_C 0x0a /* EuroPC config, binary */ -#define MRTC_CONF_D 0x0b /* EuroPC config, binary */ -#define MRTC_CONF_E 0x0c /* EuroPC config, binary */ -#define MRTC_CHECK_LO 0x0d /* Checksum, low byte */ -#define MRTC_CHECK_HI 0x0e /* Checksum, high byte */ -#define MRTC_CTRLSTAT 0x0f /* RTC control/status, binary */ - -typedef struct { - uint16_t jim; /* JIM base address */ - - uint8_t regs[16]; /* JIM internal regs (8) */ - - nvr_t nvr; /* NVR */ - uint8_t nvr_stat; - uint8_t nvr_addr; -} europc_t; - - -static europc_t europc; - - -#ifdef ENABLE_EUROPC_LOG -int europc_do_log = ENABLE_EUROPC_LOG; -#endif - - -static void -europc_log(const char *fmt, ...) -{ -#ifdef ENABLE_EUROPC_LOG - va_list ap; - - if (europc_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* - * This is called every second through the NVR/RTC hook. - * - * We fake a 'running' RTC by updating its registers on - * each passing second. Not exactly accurate, but good - * enough. - * - * Note that this code looks nasty because of all the - * BCD to decimal vv going on. - * - * FIXME: should we mark NVR as dirty? - */ -static void -rtc_tick(nvr_t *nvr) -{ - uint8_t *regs; - int mon, yr; - - /* Only if RTC is running.. */ - regs = nvr->regs; - if (! (regs[MRTC_CTRLSTAT] & 0x01)) return; - - regs[MRTC_SECONDS] = RTC_BCDINC(nvr->regs[MRTC_SECONDS], 1); - if (regs[MRTC_SECONDS] >= RTC_BCD(60)) { - regs[MRTC_SECONDS] = RTC_BCD(0); - regs[MRTC_MINUTES] = RTC_BCDINC(regs[MRTC_MINUTES], 1); - if (regs[MRTC_MINUTES] >= RTC_BCD(60)) { - regs[MRTC_MINUTES] = RTC_BCD(0); - regs[MRTC_HOURS] = RTC_BCDINC(regs[MRTC_HOURS], 1); - if (regs[MRTC_HOURS] >= RTC_BCD(24)) { - regs[MRTC_HOURS] = RTC_BCD(0); - regs[MRTC_DAYS] = RTC_BCDINC(regs[MRTC_DAYS], 1); - mon = RTC_DCB(regs[MRTC_MONTHS]); - yr = RTC_DCB(regs[MRTC_YEARS]) + 1900; - if (RTC_DCB(regs[MRTC_DAYS]) > nvr_get_days(mon, yr)) { - regs[MRTC_DAYS] = RTC_BCD(1); - regs[MRTC_MONTHS] = RTC_BCDINC(regs[MRTC_MONTHS], 1); - if (regs[MRTC_MONTHS] > RTC_BCD(12)) { - regs[MRTC_MONTHS] = RTC_BCD(1); - regs[MRTC_YEARS] = RTC_BCDINC(regs[MRTC_YEARS], 1) & 0xff; - } - } - } - } - } -} - - -/* Get the current NVR time. */ -static void -rtc_time_get(uint8_t *regs, struct tm *tm) -{ - /* NVR is in BCD data mode. */ - tm->tm_sec = RTC_DCB(regs[MRTC_SECONDS]); - tm->tm_min = RTC_DCB(regs[MRTC_MINUTES]); - tm->tm_hour = RTC_DCB(regs[MRTC_HOURS]); - tm->tm_wday = (RTC_DCB(regs[MRTC_WEEKDAY]) - 1); - tm->tm_mday = RTC_DCB(regs[MRTC_DAYS]); - tm->tm_mon = (RTC_DCB(regs[MRTC_MONTHS]) - 1); - tm->tm_year = RTC_DCB(regs[MRTC_YEARS]); -#if USE_Y2K - tm->tm_year += (RTC_DCB(regs[MRTC_CENTURY]) * 100) - 1900; -#endif -} - - -/* Set the current NVR time. */ -static void -rtc_time_set(uint8_t *regs, struct tm *tm) -{ - /* NVR is in BCD data mode. */ - regs[MRTC_SECONDS] = RTC_BCD(tm->tm_sec); - regs[MRTC_MINUTES] = RTC_BCD(tm->tm_min); - regs[MRTC_HOURS] = RTC_BCD(tm->tm_hour); - regs[MRTC_WEEKDAY] = RTC_BCD(tm->tm_wday + 1); - regs[MRTC_DAYS] = RTC_BCD(tm->tm_mday); - regs[MRTC_MONTHS] = RTC_BCD(tm->tm_mon + 1); - regs[MRTC_YEARS] = RTC_BCD(tm->tm_year % 100); -#if USE_Y2K - regs[MRTC_CENTURY] = RTC_BCD((tm->tm_year+1900) / 100); -#endif -} - - -static void -rtc_start(nvr_t *nvr) -{ - struct tm tm; - - /* Initialize the internal and chip times. */ - if (enable_sync) { - /* Use the internal clock's time. */ - nvr_time_get(&tm); - rtc_time_set(nvr->regs, &tm); - } else { - /* Set the internal clock from the chip time. */ - rtc_time_get(nvr->regs, &tm); - nvr_time_set(&tm); - } - -#if 0 - /* Start the RTC - BIOS will do this. */ - nvr->regs[MRTC_CTRLSTAT] = 0x01; -#endif -} - - -/* Create a valid checksum for the current NVR data. */ -static uint8_t -rtc_checksum(uint8_t *ptr) -{ - uint8_t sum; - int i; - - /* Calculate all bytes with XOR. */ - sum = 0x00; - for (i=MRTC_CONF_A; i<=MRTC_CONF_E; i++) - sum += ptr[i]; - - return(sum); -} - - -/* Reset the machine's NVR to a sane state. */ -static void -rtc_reset(nvr_t *nvr) -{ - /* Initialize the RTC to a known state. */ - nvr->regs[MRTC_SECONDS] = RTC_BCD(0); /* seconds */ - nvr->regs[MRTC_MINUTES] = RTC_BCD(0); /* minutes */ - nvr->regs[MRTC_HOURS] = RTC_BCD(0); /* hours */ - nvr->regs[MRTC_DAYS] = RTC_BCD(1); /* days */ - nvr->regs[MRTC_MONTHS] = RTC_BCD(1); /* months */ - nvr->regs[MRTC_YEARS] = RTC_BCD(80); /* years */ - nvr->regs[MRTC_WEEKDAY] = RTC_BCD(1); /* weekday */ - nvr->regs[MRTC_WEEKNO] = RTC_BCD(1); /* weekno */ - - /* - * EuroPC System Configuration: - * - * [A] unknown - * - * [B] 7 1 bootdrive extern - * 0 bootdribe intern - * 6:5 11 invalid hard disk type - * 10 hard disk installed, type 2 - * 01 hard disk installed, type 1 - * 00 hard disk not installed - * 4:3 11 invalid external drive type - * 10 external drive 720K - * 01 external drive 360K - * 00 external drive disabled - * 2 unknown - * 1:0 11 invalid internal drive type - * 10 internal drive 360K - * 01 internal drive 720K - * 00 internal drive disabled - * - * [C] 7:6 unknown - * 5 monitor detection OFF - * 4 unknown - * 3:2 11 illegal memory size - * 10 512K - * 01 256K - * 00 640K - * 1:0 11 illegal game port - * 10 gameport as mouse port - * 01 gameport as joysticks - * 00 gameport disabled - * - * [D] 7:6 10 9MHz CPU speed - * 01 7MHz CPU speed - * 00 4.77 MHz CPU - * 5 unknown - * 4 external: color, internal: mono - * 3 unknown - * 2 internal video ON - * 1:0 11 mono - * 10 color80 - * 01 color40 - * 00 special (EGA,VGA etc) - * - * [E] 7:4 unknown - * 3:0 country (00=Deutschland, 0A=ASCII) - */ - nvr->regs[MRTC_CONF_A] = 0x00; /* CONFIG A */ - nvr->regs[MRTC_CONF_B] = 0x0A; /* CONFIG B */ - nvr->regs[MRTC_CONF_C] = 0x28; /* CONFIG C */ - nvr->regs[MRTC_CONF_D] = 0x12; /* CONFIG D */ - nvr->regs[MRTC_CONF_E] = 0x0A; /* CONFIG E */ - - nvr->regs[MRTC_CHECK_LO] = 0x00; /* checksum (LO) */ - nvr->regs[MRTC_CHECK_HI] = 0x00; /* checksum (HI) */ - - nvr->regs[MRTC_CTRLSTAT] = 0x01; /* status/control */ - - /* Generate a valid checksum. */ - nvr->regs[MRTC_CHECK_LO] = rtc_checksum(nvr->regs); -} - - -/* Execute a JIM control command. */ -static void -jim_set(europc_t *sys, uint8_t reg, uint8_t val) -{ - switch(reg) { - case 0: /* MISC control (WO) */ - // bit0: enable MOUSE - // bit1: enable joystick - break; - - case 2: /* AGA control */ - if (! (val & 0x80)) { - /* Reset AGA. */ - break; - } - - switch (val) { - case 0x1f: /* 0001 1111 */ - case 0x0b: /* 0000 1011 */ - //europc_jim.mode=AGA_MONO; - europc_log("EuroPC: AGA Monochrome mode!\n"); - break; - - case 0x18: /* 0001 1000 */ - case 0x1a: /* 0001 1010 */ - //europc_jim.mode=AGA_COLOR; - break; - - case 0x0e: /* 0000 1100 */ - /*80 columns? */ - europc_log("EuroPC: AGA 80-column mode!\n"); - break; - - case 0x0d: /* 0000 1011 */ - /*40 columns? */ - europc_log("EuroPC: AGA 40-column mode!\n"); - break; - - default: - //europc_jim.mode=AGA_OFF; - break; - } - break; - - case 4: /* CPU Speed control */ - switch(val & 0xc0) { - case 0x00: /* 4.77 MHz */ -// cpu_set_clockscale(0, 1.0/2); - break; - - case 0x40: /* 7.16 MHz */ -// cpu_set_clockscale(0, 3.0/4); - break; - - default: /* 9.54 MHz */ -// cpu_set_clockscale(0, 1);break; - break; - } - break; - - default: - break; - } - - sys->regs[reg] = val; -} - - -/* Write to one of the JIM registers. */ -static void -jim_write(uint16_t addr, uint8_t val, void *priv) -{ - europc_t *sys = (europc_t *)priv; - uint8_t b; - -#if EUROPC_DEBUG > 1 - europc_log("EuroPC: jim_wr(%04x, %02x)\n", addr, val); -#endif - - switch (addr & 0x000f) { - case 0x00: /* JIM internal registers (WRONLY) */ - case 0x01: - case 0x02: - case 0x03: - case 0x04: /* JIM internal registers (R/W) */ - case 0x05: - case 0x06: - case 0x07: - jim_set(sys, (addr & 0x07), val); - break; - - case 0x0a: /* M3002 RTC INDEX/DATA register */ - switch(sys->nvr_stat) { - case 0: /* save index */ - sys->nvr_addr = val & 0x0f; - sys->nvr_stat++; - break; - - case 1: /* save data HI nibble */ - b = sys->nvr.regs[sys->nvr_addr] & 0x0f; - b |= (val << 4); - sys->nvr.regs[sys->nvr_addr] = b; - sys->nvr_stat++; - nvr_dosave++; - break; - - case 2: /* save data LO nibble */ - b = sys->nvr.regs[sys->nvr_addr] & 0xf0; - b |= (val & 0x0f); - sys->nvr.regs[sys->nvr_addr] = b; - sys->nvr_stat = 0; - nvr_dosave++; - break; - } - break; - - default: - europc_log("EuroPC: invalid JIM write %02x, val %02x\n", addr, val); - break; - } -} - - -/* Read from one of the JIM registers. */ -static uint8_t -jim_read(uint16_t addr, void *priv) -{ - europc_t *sys = (europc_t *)priv; - uint8_t r = 0xff; - - switch (addr & 0x000f) { - case 0x00: /* JIM internal registers (WRONLY) */ - case 0x01: - case 0x02: - case 0x03: - r = 0x00; - break; - - case 0x04: /* JIM internal registers (R/W) */ - case 0x05: - case 0x06: - case 0x07: - r = sys->regs[addr & 0x07]; - break; - - case 0x0a: /* M3002 RTC INDEX/DATA register */ - switch(sys->nvr_stat) { - case 0: - r = 0x00; - break; - - case 1: /* read data HI nibble */ - r = (sys->nvr.regs[sys->nvr_addr] >> 4); - sys->nvr_stat++; - break; - - case 2: /* read data LO nibble */ - r = (sys->nvr.regs[sys->nvr_addr] & 0x0f); - sys->nvr_stat = 0; - break; - } - break; - - default: - europc_log("EuroPC: invalid JIM read %02x\n", addr); - break; - } - -#if EUROPC_DEBUG > 1 - europc_log("EuroPC: jim_rd(%04x): %02x\n", addr, r); -#endif - - return(r); -} - - -/* Initialize the mainboard 'device' of the machine. */ -static void * -europc_boot(const device_t *info) -{ - europc_t *sys = &europc; - uint8_t b; - -#if EUROPC_DEBUG - europc_log("EuroPC: booting mainboard..\n"); -#endif - - europc_log("EuroPC: NVR=[ %02x %02x %02x %02x %02x ] %sVALID\n", - sys->nvr.regs[MRTC_CONF_A], sys->nvr.regs[MRTC_CONF_B], - sys->nvr.regs[MRTC_CONF_C], sys->nvr.regs[MRTC_CONF_D], - sys->nvr.regs[MRTC_CONF_E], - (sys->nvr.regs[MRTC_CHECK_LO]!=rtc_checksum(sys->nvr.regs))?"IN":""); - - /* - * Now that we have initialized the NVR (either from file, - * or by setting it to defaults) we can start overriding it - * with values set by the user. - */ - b = (sys->nvr.regs[MRTC_CONF_D] & ~0x17); - switch(gfxcard) { - case GFX_CGA: /* Color, CGA */ - case GFX_COLORPLUS: /* Color, Hercules ColorPlus */ - b |= 0x12; /* external video, CGA80 */ - break; - - case GFX_MDA: /* Monochrome, MDA */ - case GFX_HERCULES: /* Monochrome, Hercules */ - case GFX_INCOLOR: /* Color, ? */ - b |= 0x03; /* external video, mono */ - break; - - default: /* EGA, VGA etc */ - b |= 0x10; /* external video, special */ - - } - sys->nvr.regs[MRTC_CONF_D] = b; - - /* Update the memory size. */ - b = (sys->nvr.regs[MRTC_CONF_C] & 0xf3); - switch(mem_size) { - case 256: - b |= 0x04; - break; - - case 512: - b |= 0x08; - break; - - case 640: - b |= 0x00; - break; - } - sys->nvr.regs[MRTC_CONF_C] = b; - - /* Update CPU speed. */ - b = (sys->nvr.regs[MRTC_CONF_D] & 0x3f); - switch(cpu) { - case 0: /* 8088, 4.77 MHz */ - b |= 0x00; - break; - - case 1: /* 8088, 7.15 MHz */ - b |= 0x40; - break; - - case 2: /* 8088, 9.56 MHz */ - b |= 0x80; - break; - } - sys->nvr.regs[MRTC_CONF_D] = b; - - /* Set up game port. */ - b = (sys->nvr.regs[MRTC_CONF_C] & 0xfc); - if (mouse_type == MOUSE_TYPE_LOGIBUS) { - b |= 0x01; /* enable port as MOUSE */ - } else if (joystick_type != 7) { - b |= 0x02; /* enable port as joysticks */ - device_add(&gameport_device); - } - sys->nvr.regs[MRTC_CONF_C] = b; - -#if 0 - /* Set up floppy types. */ - sys->nvr.regs[MRTC_CONF_B] = 0x2a; -#endif - - /* Validate the NVR checksum and save. */ - sys->nvr.regs[MRTC_CHECK_LO] = rtc_checksum(sys->nvr.regs); - nvr_dosave++; - - /* - * Allocate the system's I/O handlers. - * - * The first one is for the JIM. Note that although JIM usually - * resides at 0x0250, a special solder jumper on the mainboard - * (JS9) can be used to "move" it to 0x0350, to get it out of - * the way of other cards that need this range. - */ - io_sethandler(sys->jim, 16, - jim_read,NULL,NULL, jim_write,NULL,NULL, sys); - - /* Only after JIM has been initialized. */ - (void)device_add(&keyboard_xt_device); - - /* Enable and set up the FDC. */ - (void)device_add(&fdc_xt_device); - - /* - * Set up and enable the HD20 disk controller. - * - * We only do this if we have not configured another one. - */ - if (hdc_current == 1) - (void)device_add(&xta_hd20_device); - - return(sys); -} - - -static void -europc_close(void *priv) -{ - nvr_t *nvr = &europc.nvr; - - if (nvr->fn != NULL) - free(nvr->fn); -} - - -static const device_config_t europc_config[] = { - { - "js9", "JS9 Jumper (JIM)", CONFIG_INT, "", 0, - { - { - "Disabled (250h)", 0 - }, - { - "Enabled (350h)", 1 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - - -const device_t europc_device = { - "EuroPC System Board", - 0, 0, - europc_boot, europc_close, NULL, - NULL, NULL, NULL, - europc_config -}; - - -/* - * This function sets up the Scheider EuroPC machine. - * - * Its task is to allocate a clean machine data block, - * and then simply enable the mainboard "device" which - * allows it to reset (dev init) and configured by the - * user. - */ -void -machine_europc_init(const machine_t *model) -{ - machine_common_init(model); - nmi_init(); - - /* Clear the machine state. */ - memset(&europc, 0x00, sizeof(europc_t)); - europc.jim = 0x0250; - - mem_add_bios(); - - /* This is machine specific. */ - europc.nvr.size = model->nvrmask + 1; - europc.nvr.irq = -1; - - /* Set up any local handlers here. */ - europc.nvr.reset = rtc_reset; - europc.nvr.start = rtc_start; - europc.nvr.tick = rtc_tick; - - /* Initialize the actual NVR. */ - nvr_init(&europc.nvr); - - /* Enable and set up the mainboard device. */ - device_add(&europc_device); -} diff --git a/src - Cópia/machine/m_olivetti_m24.c b/src - Cópia/machine/m_olivetti_m24.c deleted file mode 100644 index 57a28d7ea..000000000 --- a/src - Cópia/machine/m_olivetti_m24.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the Olivetti M24. - * - * Version: @(#)m_olivetti_m24.c 1.0.14 2018/04/26 - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../nmi.h" -#include "../mem.h" -#include "../timer.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.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 "machine.h" - - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - - -typedef struct { - /* Video stuff. */ - mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; - uint8_t monitor_type, port_23c6; - uint8_t *vram; - uint8_t charbuffer[256]; - uint8_t ctrl; - uint32_t base; - uint8_t cgamode, cgacol; - uint8_t stat; - int linepos, displine; - int sc, vc; - int con, coff, cursoron, blink; - int64_t vsynctime; - int vadj; - int lineff; - uint16_t ma, maback; - int dispon; - int64_t dispontime, dispofftime; - int64_t vidtime; - int firstline, lastline; - - /* Keyboard stuff. */ - int wantirq; - uint8_t command; - uint8_t status; - uint8_t out; - uint8_t output_port; - int param, - param_total; - uint8_t params[16]; - uint8_t scan[7]; - - /* Mouse stuff. */ - int mouse_mode; - int x, y, b; -} olim24_t; - - -static uint8_t crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static uint8_t key_queue[16]; -static int key_queue_start = 0, - key_queue_end = 0; - - - -#ifdef ENABLE_M24VID_LOG -int m24vid_do_log = ENABLE_M24VID_LOG; -#endif - - -static void -m24_log(const char *fmt, ...) -{ -#ifdef ENABLE_M24VID_LOG - va_list ap; - - if (m24vid_do_log) { - va_start(ap, fmt); - vfprintf(stdlog, fmt, ap); - va_end(ap); - fflush(stdlog); - } -#endif -} - -static void -recalc_timings(olim24_t *m24) -{ - double _dispontime, _dispofftime, disptime; - - if (m24->cgamode & 1) { - disptime = m24->crtc[0] + 1; - _dispontime = m24->crtc[1]; - } else { - disptime = (m24->crtc[0] + 1) << 1; - _dispontime = m24->crtc[1] << 1; - } - - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST / 2; - _dispofftime *= CGACONST / 2; - m24->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - m24->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void -vid_out(uint16_t addr, uint8_t val, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - uint8_t old; - - switch (addr) { - case 0x3d4: - m24->crtcreg = val & 31; - break; - - case 0x3d5: - old = m24->crtc[m24->crtcreg]; - m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg]; - if (old != val) { - if (m24->crtcreg < 0xe || m24->crtcreg > 0x10) { - fullchange = changeframecount; - recalc_timings(m24); - } - } - break; - - case 0x3d8: - m24->cgamode = val; - break; - - case 0x3d9: - m24->cgacol = val; - break; - - case 0x3de: - m24->ctrl = val; - m24->base = (val & 0x08) ? 0x4000 : 0; - break; - - case 0x13c6: - m24->monitor_type = val; - break; - - case 0x23c6: - m24->port_23c6 = val; - break; - } -} - - -static uint8_t -vid_in(uint16_t addr, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0x3d4: - ret = m24->crtcreg; - break; - - case 0x3d5: - ret = m24->crtc[m24->crtcreg]; - break; - - case 0x3da: - ret = m24->stat; - break; - - case 0x13c6: - ret = m24->monitor_type; - break; - - case 0x23c6: - ret = m24->port_23c6; - break; - } - - return(ret); -} - - -static void -vid_write(uint32_t addr, uint8_t val, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - m24->vram[addr & 0x7FFF]=val; - m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val; - m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val; -} - - -static uint8_t -vid_read(uint32_t addr, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - return(m24->vram[addr & 0x7FFF]); -} - - -static void -vid_poll(void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - uint16_t ca = (m24->crtc[15] | (m24->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat, dat2; - int cols[4]; - int col; - int oldsc; - - if (!m24->linepos) { - m24->vidtime += m24->dispofftime; - m24->stat |= 1; - m24->linepos = 1; - oldsc = m24->sc; - if ((m24->crtc[8] & 3) == 3) - m24->sc = (m24->sc << 1) & 7; - if (m24->dispon) { - if (m24->displine < m24->firstline) { - m24->firstline = m24->displine; - } - m24->lastline = m24->displine; - for (c = 0; c < 8; c++) - { - if ((m24->cgamode & 0x12) == 0x12) { - buffer->line[m24->displine][c] = 0; - if (m24->cgamode & 1) - buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0; - else - buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0; - } else { - buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16; - if (m24->cgamode & 1) - buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16; - else - buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16; - } - } - if (m24->cgamode & 1) { - for (x = 0; x < m24->crtc[1]; x++) { - chr = m24->charbuffer[ x << 1]; - attr = m24->charbuffer[(x << 1) + 1]; - drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); - if (m24->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } - m24->ma++; - } - } else if (!(m24->cgamode & 2)) { - for (x = 0; x < m24->crtc[1]; x++) { - chr = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base]; - attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base]; - drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); - if (m24->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((m24->blink & 16) && (attr & 0x80)) - cols[1] = cols[0]; - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - m24->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } else if (!(m24->cgamode & 16)) { - cols[0] = (m24->cgacol & 15) | 16; - col = (m24->cgacol & 16) ? 24 : 16; - if (m24->cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (m24->cgacol & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < m24->crtc[1]; x++) { - dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) | - m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base]; - m24->ma++; - for (c = 0; c < 8; c++) { - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - if (m24->ctrl & 1 || ((m24->monitor_type & 8) && (m24->port_23c6 & 1))) { - dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000); - cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16; - } else { - dat2 = (m24->sc & 1) * 0x2000; - cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16; - } - - for (x = 0; x < m24->crtc[1]; x++) { - dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1]; - m24->ma++; - for (c = 0; c < 16; c++) { - buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16; - if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]); - } - - if (m24->cgamode & 1) - x = (m24->crtc[1] << 3) + 16; - else - x = (m24->crtc[1] << 4) + 16; - - m24->sc = oldsc; - if (m24->vc == m24->crtc[7] && !m24->sc) - m24->stat |= 8; - m24->displine++; - if (m24->displine >= 720) m24->displine = 0; - } else { - m24->vidtime += m24->dispontime; - if (m24->dispon) m24->stat &= ~1; - m24->linepos = 0; - m24->lineff ^= 1; - if (m24->lineff) { - m24->ma = m24->maback; - } else { - if (m24->vsynctime) { - m24->vsynctime--; - if (!m24->vsynctime) - m24->stat &= ~8; - } - if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1))) { - m24->con = 0; - m24->coff = 1; - } - if (m24->vadj) { - m24->sc++; - m24->sc &= 31; - m24->ma = m24->maback; - m24->vadj--; - if (!m24->vadj) { - m24->dispon = 1; - m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff; - m24->sc = 0; - } - } else if (m24->sc == m24->crtc[9] || ((m24->crtc[8] & 3) == 3 && m24->sc == (m24->crtc[9] >> 1))) { - m24->maback = m24->ma; - m24->sc = 0; - oldvc = m24->vc; - m24->vc++; - m24->vc &= 127; - - if (m24->vc == m24->crtc[6]) - m24->dispon=0; - - if (oldvc == m24->crtc[4]) { - m24->vc = 0; - m24->vadj = m24->crtc[5]; - if (!m24->vadj) m24->dispon = 1; - if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff; - if ((m24->crtc[10] & 0x60) == 0x20) - m24->cursoron = 0; - else - m24->cursoron = m24->blink & 16; - } - - if (m24->vc == m24->crtc[7]) { - m24->dispon = 0; - m24->displine = 0; - m24->vsynctime = (m24->crtc[3] >> 4) + 1; - if (m24->crtc[7]) { - if (m24->cgamode & 1) - x = (m24->crtc[1] << 3) + 16; - else - x = (m24->crtc[1] << 4) + 16; - m24->lastline++; - if ((x != xsize) || ((m24->lastline - m24->firstline) != ysize) || video_force_resize_get()) { - xsize = x; - ysize = m24->lastline - m24->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize + 16); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - video_blit_memtoscreen_8(0, m24->firstline - 8, 0, (m24->lastline - m24->firstline) + 16, xsize, (m24->lastline - m24->firstline) + 16); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (m24->cgamode & 1) { - video_res_x /= 8; - video_res_y /= (m24->crtc[9] + 1) * 2; - video_bpp = 0; - } else if (!(m24->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= (m24->crtc[9] + 1) * 2; - video_bpp = 0; - } else if (!(m24->cgamode & 16)) { - video_res_x /= 2; - video_res_y /= 2; - video_bpp = 2; - } else if (!(m24->ctrl & 1)) { - video_res_y /= 2; - video_bpp = 1; - } - } - m24->firstline = 1000; - m24->lastline = 0; - m24->blink++; - } - } else { - m24->sc++; - m24->sc &= 31; - m24->ma = m24->maback; - } - if ((m24->sc == (m24->crtc[10] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[10] & 31) >> 1)))) - m24->con = 1; - } - if (m24->dispon && (m24->cgamode & 1)) { - for (x = 0; x < (m24->crtc[1] << 1); x++) - m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base]; - } - } -} - - -static void -speed_changed(void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - recalc_timings(m24); -} - - -static void -kbd_poll(void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - keyboard_delay += (1000LL * TIMER_USEC); - if (m24->wantirq) { - m24->wantirq = 0; - picint(2); -#if ENABLE_KEYBOARD_LOG - m24_log("M24: take IRQ\n"); -#endif - } - - if (!(m24->status & STAT_OFULL) && key_queue_start != key_queue_end) { -#if ENABLE_KEYBOARD_LOG - m24_log("Reading %02X from the key queue at %i\n", - m24->out, key_queue_start); -#endif - m24->out = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - m24->status |= STAT_OFULL; - m24->status &= ~STAT_IFULL; - m24->wantirq = 1; - } -} - - -static void -kbd_adddata(uint16_t val) -{ - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; -} - - -static void -kbd_adddata_ex(uint16_t val) -{ - kbd_adddata_process(val, kbd_adddata); -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - -#if ENABLE_KEYBOARD_LOG - m24_log("M24: write %04X %02X\n", port, val); -#endif - -#if 0 - if (ram[8] == 0xc3) { - output = 3; - } -#endif - switch (port) { - case 0x60: - if (m24->param != m24->param_total) { - m24->params[m24->param++] = val; - if (m24->param == m24->param_total) { - switch (m24->command) { - case 0x11: - m24->mouse_mode = 0; - m24->scan[0] = m24->params[0]; - m24->scan[1] = m24->params[1]; - m24->scan[2] = m24->params[2]; - m24->scan[3] = m24->params[3]; - m24->scan[4] = m24->params[4]; - m24->scan[5] = m24->params[5]; - m24->scan[6] = m24->params[6]; - break; - - case 0x12: - m24->mouse_mode = 1; - m24->scan[0] = m24->params[0]; - m24->scan[1] = m24->params[1]; - m24->scan[2] = m24->params[2]; - break; - - default: - m24_log("M24: bad keyboard command complete %02X\n", m24->command); - } - } - } else { - m24->command = val; - switch (val) { - case 0x01: /*Self-test*/ - break; - - case 0x05: /*Read ID*/ - kbd_adddata(0x00); - break; - - case 0x11: - m24->param = 0; - m24->param_total = 9; - break; - - case 0x12: - m24->param = 0; - m24->param_total = 4; - break; - - default: - m24_log("M24: bad keyboard command %02X\n", val); - } - } - break; - - case 0x61: - ppi.pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); - break; - } -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x60: - ret = m24->out; - if (key_queue_start == key_queue_end) { - m24->status &= ~STAT_OFULL; - m24->wantirq = 0; - } else { - m24->out = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - m24->status |= STAT_OFULL; - m24->status &= ~STAT_IFULL; - m24->wantirq = 1; - } - break; - - case 0x61: - ret = ppi.pb; - break; - - case 0x64: - ret = m24->status; - m24->status &= ~(STAT_RTIMEOUT | STAT_TTIMEOUT); - break; - - default: - m24_log("\nBad M24 keyboard read %04X\n", port); - } - - return(ret); -} - - -static int -ms_poll(int x, int y, int z, int b, void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - m24->x += x; - m24->y += y; - - if (((key_queue_end - key_queue_start) & 0xf) > 14) return(0xff); - - if ((b & 1) && !(m24->b & 1)) - kbd_adddata(m24->scan[0]); - if (!(b & 1) && (m24->b & 1)) - kbd_adddata(m24->scan[0] | 0x80); - m24->b = (m24->b & ~1) | (b & 1); - - if (((key_queue_end - key_queue_start) & 0xf) > 14) return(0xff); - - if ((b & 2) && !(m24->b & 2)) - kbd_adddata(m24->scan[2]); - if (!(b & 2) && (m24->b & 2)) - kbd_adddata(m24->scan[2] | 0x80); - m24->b = (m24->b & ~2) | (b & 2); - - if (((key_queue_end - key_queue_start) & 0xf) > 14) return(0xff); - - if ((b & 4) && !(m24->b & 4)) - kbd_adddata(m24->scan[1]); - if (!(b & 4) && (m24->b & 4)) - kbd_adddata(m24->scan[1] | 0x80); - m24->b = (m24->b & ~4) | (b & 4); - - if (m24->mouse_mode) { - if (((key_queue_end - key_queue_start) & 0xf) > 12) return(0xff); - - if (!m24->x && !m24->y) return(0xff); - - m24->y = -m24->y; - - if (m24->x < -127) m24->x = -127; - if (m24->x > 127) m24->x = 127; - if (m24->x < -127) m24->x = 0x80 | ((-m24->x) & 0x7f); - - if (m24->y < -127) m24->y = -127; - if (m24->y > 127) m24->y = 127; - if (m24->y < -127) m24->y = 0x80 | ((-m24->y) & 0x7f); - - kbd_adddata(0xfe); - kbd_adddata(m24->x); - kbd_adddata(m24->y); - - m24->x = m24->y = 0; - } else { - while (m24->x < -4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return(0xff); - m24->x += 4; - kbd_adddata(m24->scan[3]); - } - while (m24->x > 4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return(0xff); - m24->x -= 4; - kbd_adddata(m24->scan[4]); - } - while (m24->y < -4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return(0xff); - m24->y += 4; - kbd_adddata(m24->scan[5]); - } - while (m24->y > 4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return(0xff); - m24->y -= 4; - kbd_adddata(m24->scan[6]); - } - } - - return(0); -} - - -static uint8_t -m24_read(uint16_t port, void *priv) -{ - switch (port) { - case 0x66: - return 0x00; - case 0x67: - return 0x20 | 0x40 | 0x0C; - } - - return(0xff); -} - -static void -vid_close(void *priv) -{ - olim24_t *m24 = (olim24_t *)priv; - - free(m24->vram); - - free(m24); -} - -const device_t m24_device = { - "Olivetti M24", - 0, 0, - NULL, vid_close, NULL, - NULL, - speed_changed, - NULL, - NULL -}; - - -void -machine_olim24_init(const machine_t *model) -{ - olim24_t *m24; - - m24 = (olim24_t *)malloc(sizeof(olim24_t)); - memset(m24, 0x00, sizeof(olim24_t)); - - machine_common_init(model); - device_add(&fdc_xt_device); - - io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, m24); - - /* Initialize the video adapter. */ - m24->vram = malloc(0x8000); - overscan_x = overscan_y = 16; - mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, - vid_read, NULL, NULL, - vid_write, NULL, NULL, NULL, 0, m24); - io_sethandler(0x03d0, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, m24); - timer_add(vid_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24); - device_add_ex(&m24_device, m24); - - /* Initialize the keyboard. */ - m24->status = STAT_LOCK | STAT_CD; - m24->scan[0] = 0x1c; - m24->scan[1] = 0x53; - m24->scan[2] = 0x01; - m24->scan[3] = 0x4b; - m24->scan[4] = 0x4d; - m24->scan[5] = 0x48; - m24->scan[6] = 0x50; - io_sethandler(0x0060, 2, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24); - io_sethandler(0x0064, 1, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24); - keyboard_set_table(scancode_xt); - keyboard_send = kbd_adddata_ex; - keyboard_scan = 1; - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, m24); - - /* Tell mouse driver about our internal mouse. */ - mouse_reset(); - mouse_set_poll(ms_poll, m24); - - if (joystick_type != 7) - device_add(&gameport_device); - - /* FIXME: make sure this is correct?? */ - device_add(&at_nvr_device); - - nmi_init(); -} - -void machine_olim24_video_init(void) { - olim24_t *m24; - - m24 = (olim24_t *)malloc(sizeof(olim24_t)); - memset(m24, 0x00, sizeof(olim24_t)); - - /* Initialize the video adapter. */ - m24->vram = malloc(0x8000); - overscan_x = overscan_y = 16; - mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, - vid_read, NULL, NULL, - vid_write, NULL, NULL, NULL, 0, m24); - io_sethandler(0x03d0, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, m24); - io_sethandler(0x13c6, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, m24); - io_sethandler(0x23c6, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, m24); - timer_add(vid_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24); - device_add_ex(&m24_device, m24); -} diff --git a/src - Cópia/machine/m_pcjr.c b/src - Cópia/machine/m_pcjr.c deleted file mode 100644 index 52979f72e..000000000 --- a/src - Cópia/machine/m_pcjr.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the IBM PCjr. - * - * Version: @(#)m_pcjr.c 1.0.8 2018/04/29 - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../timer.h" -#include "../device.h" -#include "../serial.h" -#include "../keyboard.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 "machine.h" - - -#define PCJR_RGB 0 -#define PCJR_COMPOSITE 1 - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - - -typedef struct { - /* Video Controller stuff. */ - mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; - int array_index; - uint8_t array[32]; - int array_ff; - int memctrl; - uint8_t stat; - int addr_mode; - uint8_t *vram, - *b8000; - int linepos, displine; - int sc, vc; - int dispon; - int con, coff, cursoron, blink; - int64_t vsynctime; - int vadj; - uint16_t ma, maback; - int64_t dispontime, dispofftime, vidtime; - int firstline, lastline; - int composite; - - /* Keyboard Controller stuff. */ - int latched; - int data; - int serial_data[44]; - int serial_pos; - uint8_t pa; - uint8_t pb; -} pcjr_t; - - -static uint8_t crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static uint8_t key_queue[16]; -static int key_queue_start = 0, - key_queue_end = 0; - - -static void -recalc_address(pcjr_t *pcjr) -{ - if ((pcjr->memctrl & 0xc0) == 0xc0) { - pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11]; - } else { - pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11]; - } -} - - -static void -recalc_timings(pcjr_t *pcjr) -{ - double _dispontime, _dispofftime, disptime; - - if (pcjr->array[0] & 1) { - disptime = pcjr->crtc[0] + 1; - _dispontime = pcjr->crtc[1]; - } else { - disptime = (pcjr->crtc[0] + 1) << 1; - _dispontime = pcjr->crtc[1] << 1; - } - - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - pcjr->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - pcjr->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void -vid_out(uint16_t addr, uint8_t val, void *p) -{ - pcjr_t *pcjr = (pcjr_t *)p; - uint8_t old; - - switch (addr) { - case 0x3d4: - pcjr->crtcreg = val & 0x1f; - return; - - case 0x3d5: - old = pcjr->crtc[pcjr->crtcreg]; - pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; - if (old != val) { - if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) { - fullchange = changeframecount; - recalc_timings(pcjr); - } - } - return; - - case 0x3da: - if (!pcjr->array_ff) - pcjr->array_index = val & 0x1f; - else { - if (pcjr->array_index & 0x10) - val &= 0x0f; - pcjr->array[pcjr->array_index & 0x1f] = val; - if (!(pcjr->array_index & 0x1f)) - update_cga16_color(val); - } - pcjr->array_ff = !pcjr->array_ff; - break; - - case 0x3df: - pcjr->memctrl = val; - pcjr->addr_mode = val >> 6; - recalc_address(pcjr); - break; - } -} - - -static uint8_t -vid_in(uint16_t addr, void *p) -{ - pcjr_t *pcjr = (pcjr_t *)p; - uint8_t ret = 0xff; - - switch (addr) { - case 0x3d4: - ret = pcjr->crtcreg; - break; - - case 0x3d5: - ret = pcjr->crtc[pcjr->crtcreg]; - break; - - case 0x3da: - pcjr->array_ff = 0; - pcjr->stat ^= 0x10; - ret = pcjr->stat; - break; - } - - return(ret); -} - - -static void -vid_write(uint32_t addr, uint8_t val, void *p) -{ - pcjr_t *pcjr = (pcjr_t *)p; - - if (pcjr->memctrl == -1) return; - - egawrites++; - pcjr->b8000[addr & 0x3fff] = val; -} - - -static uint8_t -vid_read(uint32_t addr, void *p) -{ - pcjr_t *pcjr = (pcjr_t *)p; - - if (pcjr->memctrl == -1) return(0xff); - - egareads++; - return(pcjr->b8000[addr & 0x3fff]); -} - - -static void -vid_poll(void *p) -{ - pcjr_t *pcjr = (pcjr_t *)p; - uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int cols[4]; - int oldsc; - - if (! pcjr->linepos) { - pcjr->vidtime += pcjr->dispofftime; - pcjr->stat &= ~1; - pcjr->linepos = 1; - oldsc = pcjr->sc; - if ((pcjr->crtc[8] & 3) == 3) - pcjr->sc = (pcjr->sc << 1) & 7; - if (pcjr->dispon) { - uint16_t offset = 0; - uint16_t mask = 0x1fff; - - if (pcjr->displine < pcjr->firstline) { - pcjr->firstline = pcjr->displine; - video_wait_for_buffer(); - } - pcjr->lastline = pcjr->displine; - cols[0] = (pcjr->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - buffer->line[pcjr->displine][c] = cols[0]; - if (pcjr->array[0] & 1) - buffer->line[pcjr->displine][c + (pcjr->crtc[1] << 3) + 8] = cols[0]; - else - buffer->line[pcjr->displine][c + (pcjr->crtc[1] << 4) + 8] = cols[0]; - } - - switch (pcjr->addr_mode) { - case 0: /*Alpha*/ - offset = 0; - mask = 0x3fff; - break; - case 1: /*Low resolution graphics*/ - offset = (pcjr->sc & 1) * 0x2000; - break; - case 3: /*High resolution graphics*/ - offset = (pcjr->sc & 3) * 0x2000; - break; - } - switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { - case 0x13: /*320x200x16*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - buffer->line[pcjr->displine][(x << 3) + 8] = - buffer->line[pcjr->displine][(x << 3) + 9] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 10] = - buffer->line[pcjr->displine][(x << 3) + 11] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 12] = - buffer->line[pcjr->displine][(x << 3) + 13] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 14] = - buffer->line[pcjr->displine][(x << 3) + 15] = pcjr->array[(dat & pcjr->array[1]) + 16] + 16; - } - break; - case 0x12: /*160x200x16*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - buffer->line[pcjr->displine][(x << 4) + 8] = - buffer->line[pcjr->displine][(x << 4) + 9] = - buffer->line[pcjr->displine][(x << 4) + 10] = - buffer->line[pcjr->displine][(x << 4) + 11] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 12] = - buffer->line[pcjr->displine][(x << 4) + 13] = - buffer->line[pcjr->displine][(x << 4) + 14] = - buffer->line[pcjr->displine][(x << 4) + 15] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 16] = - buffer->line[pcjr->displine][(x << 4) + 17] = - buffer->line[pcjr->displine][(x << 4) + 18] = - buffer->line[pcjr->displine][(x << 4) + 19] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 20] = - buffer->line[pcjr->displine][(x << 4) + 21] = - buffer->line[pcjr->displine][(x << 4) + 22] = - buffer->line[pcjr->displine][(x << 4) + 23] = pcjr->array[(dat & pcjr->array[1]) + 16] + 16; - } - break; - case 0x03: /*640x200x4*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - buffer->line[pcjr->displine][(x << 3) + 8 + c] = pcjr->array[(chr & pcjr->array[1]) + 16] + 16; - dat <<= 1; - } - } - break; - case 0x01: /*80 column text*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset]; - attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); - if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; - } - if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 3) + c + 8] ^= 15; - } - pcjr->ma++; - } - break; - case 0x00: /*40 column text*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset]; - attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); - if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; - } - pcjr->ma++; - if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 16; c++) - buffer->line[pcjr->displine][(x << 4) + c + 8] ^= 15; - } - } - break; - case 0x02: /*320x200x4*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; - cols[2] = pcjr->array[2 + 16] + 16; - cols[3] = pcjr->array[3 + 16] + 16; - for (x = 0; x < pcjr->crtc[1]; x++) { - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - for (c = 0; c < 8; c++) { - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - break; - case 0x102: /*640x200x2*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; - for (x = 0; x < pcjr->crtc[1]; x++) { - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - for (c = 0; c < 16; c++) { - buffer->line[pcjr->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - break; - } - } else { - if (pcjr->array[3] & 4) { - if (pcjr->array[0] & 1) hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, (pcjr->array[2] & 0xf) + 16); - else hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, (pcjr->array[2] & 0xf) + 16); - } else { - cols[0] = pcjr->array[0 + 16] + 16; - if (pcjr->array[0] & 1) hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, cols[0]); - } - } - if (pcjr->array[0] & 1) x = (pcjr->crtc[1] << 3) + 16; - else x = (pcjr->crtc[1] << 4) + 16; - if (pcjr->composite) { - for (c = 0; c < x; c++) - buffer32->line[pcjr->displine][c] = buffer->line[pcjr->displine][c] & 0xf; - - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); - } - pcjr->sc = oldsc; - if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { - pcjr->stat |= 8; - } - pcjr->displine++; - if (pcjr->displine >= 360) - pcjr->displine = 0; - } else { - pcjr->vidtime += pcjr->dispontime; - if (pcjr->dispon) - pcjr->stat |= 1; - pcjr->linepos = 0; - if (pcjr->vsynctime) { - pcjr->vsynctime--; - if (!pcjr->vsynctime) { - pcjr->stat &= ~8; - } - } - if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) { - pcjr->con = 0; - pcjr->coff = 1; - } - if (pcjr->vadj) { - pcjr->sc++; - pcjr->sc &= 31; - pcjr->ma = pcjr->maback; - pcjr->vadj--; - if (!pcjr->vadj) { - pcjr->dispon = 1; - pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; - pcjr->sc = 0; - } - } else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) { - pcjr->maback = pcjr->ma; - pcjr->sc = 0; - oldvc = pcjr->vc; - pcjr->vc++; - pcjr->vc &= 127; - if (pcjr->vc == pcjr->crtc[6]) - pcjr->dispon = 0; - if (oldvc == pcjr->crtc[4]) { - pcjr->vc = 0; - pcjr->vadj = pcjr->crtc[5]; - if (!pcjr->vadj) - pcjr->dispon = 1; - if (!pcjr->vadj) - pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; - if ((pcjr->crtc[10] & 0x60) == 0x20) pcjr->cursoron = 0; - else pcjr->cursoron = pcjr->blink & 16; - } - if (pcjr->vc == pcjr->crtc[7]) { - pcjr->dispon = 0; - pcjr->displine = 0; - pcjr->vsynctime = 16; - picint(1 << 5); - if (pcjr->crtc[7]) { - if (pcjr->array[0] & 1) x = (pcjr->crtc[1] << 3) + 16; - else x = (pcjr->crtc[1] << 4) + 16; - pcjr->lastline++; - if ((x != xsize) || ((pcjr->lastline - pcjr->firstline) != ysize) || video_force_resize_get()) { - xsize = x; - ysize = pcjr->lastline - pcjr->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if (pcjr->composite) - video_blit_memtoscreen(0, pcjr->firstline-4, 0, (pcjr->lastline - pcjr->firstline) + 8, xsize, (pcjr->lastline - pcjr->firstline) + 8); - else - video_blit_memtoscreen_8(0, pcjr->firstline-4, 0, (pcjr->lastline - pcjr->firstline) + 8, xsize, (pcjr->lastline - pcjr->firstline) + 8); - - frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - } - pcjr->firstline = 1000; - pcjr->lastline = 0; - pcjr->blink++; - } - } else { - pcjr->sc++; - pcjr->sc &= 31; - pcjr->ma = pcjr->maback; - } - if ((pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1)))) - pcjr->con = 1; - } -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - pcjr_t *pcjr = (pcjr_t *)priv; - - switch (port) { - case 0x60: - pcjr->pa = val; - break; - - case 0x61: - pcjr->pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); - sn76489_mute = speaker_mute = 1; - switch (val & 0x60) { - case 0x00: - speaker_mute = 0; - break; - - case 0x60: - sn76489_mute = 0; - break; - } - break; - - case 0xa0: - nmi_mask = val & 0x80; - pit_set_using_timer(&pit, 1, !(val & 0x20)); - break; - } -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - pcjr_t *pcjr = (pcjr_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x60: - ret = pcjr->pa; - break; - - case 0x61: - ret = pcjr->pb; - break; - - case 0x62: - ret = (pcjr->latched ? 1 : 0); - ret |= 0x02; /*Modem card not installed*/ - ret |= (ppispeakon ? 0x10 : 0); - ret |= (ppispeakon ? 0x20 : 0); - ret |= (pcjr->data ? 0x40: 0); - if (pcjr->data) - ret |= 0x40; - break; - - case 0xa0: - pcjr->latched = 0; - ret = 0; - break; - } - - return(ret); -} - - -static void -kbd_poll(void *priv) -{ - pcjr_t *pcjr = (pcjr_t *)priv; - int c, p = 0, key; - - keyboard_delay += (220LL * TIMER_USEC); - - if (key_queue_start != key_queue_end && - !pcjr->serial_pos && !pcjr->latched) { - key = key_queue[key_queue_start]; - - key_queue_start = (key_queue_start + 1) & 0xf; - - pcjr->latched = 1; - pcjr->serial_data[0] = 1; /*Start bit*/ - pcjr->serial_data[1] = 0; - - for (c = 0; c < 8; c++) { - if (key & (1 << c)) { - pcjr->serial_data[(c + 1) * 2] = 1; - pcjr->serial_data[(c + 1) * 2 + 1] = 0; - p++; - } else { - pcjr->serial_data[(c + 1) * 2] = 0; - pcjr->serial_data[(c + 1) * 2 + 1] = 1; - } - } - - if (p & 1) { /*Parity*/ - pcjr->serial_data[9 * 2] = 1; - pcjr->serial_data[9 * 2 + 1] = 0; - } else { - pcjr->serial_data[9 * 2] = 0; - pcjr->serial_data[9 * 2 + 1] = 1; - } - - for (c = 0; c < 11; c++) { /*11 stop bits*/ - pcjr->serial_data[(c + 10) * 2] = 0; - pcjr->serial_data[(c + 10) * 2 + 1] = 0; - } - - pcjr->serial_pos++; - } - - if (pcjr->serial_pos) { - pcjr->data = pcjr->serial_data[pcjr->serial_pos - 1]; - nmi = pcjr->data; - pcjr->serial_pos++; - if (pcjr->serial_pos == 42+1) - pcjr->serial_pos = 0; - } -} - - -static void -kbd_adddata(uint16_t val) -{ - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; -} - - - - -static void -kbd_adddata_ex(uint16_t val) -{ - kbd_adddata_process(val, kbd_adddata); -} - - -static void -speed_changed(void *priv) -{ - pcjr_t *pcjr = (pcjr_t *)priv; - - recalc_timings(pcjr); -} - - -static const device_config_t pcjr_config[] = { - { - "display_type", "Display type", CONFIG_SELECTION, "", PCJR_RGB, - { - { - "RGB", PCJR_RGB - }, - { - "Composite", PCJR_COMPOSITE - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_t pcjr_device = { - "IBM PCjr", - 0, 0, - NULL, NULL, NULL, - NULL, - speed_changed, - NULL, - pcjr_config -}; - - -const device_t * -pcjr_get_device(void) -{ - return &pcjr_device; -} - - -void -machine_pcjr_init(const machine_t *model) -{ - int display_type; - pcjr_t *pcjr; - - pcjr = malloc(sizeof(pcjr_t)); - memset(pcjr, 0x00, sizeof(pcjr_t)); - pcjr->memctrl = -1; - display_type = machine_get_config_int("display_type"); - pcjr->composite = (display_type != PCJR_RGB); - - pic_init(); - pit_init(); - pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); - - if (serial_enabled[0]) - serial_setup(1, 0x2f8, 3); - - /* Initialize the video controller. */ - mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, - vid_read, NULL, NULL, - vid_write, NULL, NULL, NULL, 0, pcjr); - io_sethandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr); - timer_add(vid_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr); - device_add_ex(&pcjr_device, pcjr); - - /* Initialize the keyboard. */ - key_queue_start = key_queue_end = 0; - io_sethandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, pcjr); - io_sethandler(0x00a0, 8, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, pcjr); - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, pcjr); - keyboard_set_table(scancode_xt); - keyboard_send = kbd_adddata_ex; - - device_add(&sn76489_device); - - nmi_mask = 0x80; - - device_add(&fdc_pcjr_device); -} diff --git a/src - Cópia/machine/m_ps1.c b/src - Cópia/machine/m_ps1.c deleted file mode 100644 index 46086b9a6..000000000 --- a/src - Cópia/machine/m_ps1.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the IBM PS/1 models 2011, 2121 and 2133. - * - * Model 2011: The initial model, using a 10MHz 80286. - * - * Model 2121: This is similar to model 2011 but some of the functionality - * has moved to a chip at ports 0xe0 (index)/0xe1 (data). The - * only functions I have identified are enables for the first - * 512K and next 128K of RAM, in bits 0 of registers 0 and 1 - * respectively. - * - * Port 0x105 has bit 7 forced high. Without this 128K of - * memory will be missed by the BIOS on cold boots. - * - * The reserved 384K is remapped to the top of extended memory. - * If this is not done then you get an error on startup. - * - * NOTES: Floppy does not seem to work. --FvK - * The "ROM DOS" shell does not seem to work. We do have the - * correct BIOS images now, and they do load, but they do not - * boot. Sometimes, they do, and then it shows an "Incorrect - * DOS" error message?? --FvK - * - * Version: @(#)m_ps1.c 1.0.9 2018/04/26 - * - * 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. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../timer.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 "machine.h" - - -typedef struct { - sn76489_t sn76489; - uint8_t status, ctrl; - int64_t timer_latch, timer_count, timer_enable; - uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; - int fifo_threshold; - uint8_t dac_val; - int16_t buffer[SOUNDBUFLEN]; - int pos; -} ps1snd_t; - -typedef struct { - int model; - - rom_t high_rom; - - uint8_t ps1_91, - ps1_92, - ps1_94, - ps1_102, - ps1_103, - ps1_104, - ps1_105, - ps1_190; - int ps1_e0_addr; - uint8_t ps1_e0_regs[256]; -} ps1_t; - - -static void -update_irq_status(ps1snd_t *snd) -{ - if (((snd->status & snd->ctrl) & 0x12) && (snd->ctrl & 0x01)) - picint(1 << 7); - else - picintc(1 << 7); -} - - -static uint8_t -snd_read(uint16_t port, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: /* ADC data */ - snd->status &= ~0x10; - update_irq_status(snd); - ret = 0; - break; - - case 2: /* status */ - ret = snd->status; - ret |= (snd->ctrl & 0x01); - if ((snd->fifo_write_idx - snd->fifo_read_idx) >= 2048) - ret |= 0x08; /* FIFO full */ - if (snd->fifo_read_idx == snd->fifo_write_idx) - ret |= 0x04; /* FIFO empty */ - break; - - case 3: /* FIFO timer */ - /* - * The PS/1 Technical Reference says this should return - * thecurrent value, but the PS/1 BIOS and Stunt Island - * expect it not to change. - */ - ret = snd->timer_latch; - break; - - case 4: - case 5: - case 6: - case 7: - ret = 0; - } - - return(ret); -} - - -static void -snd_write(uint16_t port, uint8_t val, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - switch (port & 7) { - case 0: /* DAC output */ - if ((snd->fifo_write_idx - snd->fifo_read_idx) < 2048) { - snd->fifo[snd->fifo_write_idx & 2047] = val; - snd->fifo_write_idx++; - } - break; - - case 2: /* control */ - snd->ctrl = val; - if (! (val & 0x02)) - snd->status &= ~0x02; - update_irq_status(snd); - break; - - case 3: /* timer reload value */ - snd->timer_latch = val; - snd->timer_count = (int64_t) ((0xff-val) * TIMER_USEC); - snd->timer_enable = (val != 0); - break; - - case 4: /* almost empty */ - snd->fifo_threshold = val * 4; - break; - } -} - - -static void -snd_update(ps1snd_t *snd) -{ - for (; snd->pos < sound_pos_global; snd->pos++) - snd->buffer[snd->pos] = (int8_t)(snd->dac_val ^ 0x80) * 0x20; -} - - -static void -snd_callback(void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - snd_update(snd); - - if (snd->fifo_read_idx != snd->fifo_write_idx) { - snd->dac_val = snd->fifo[snd->fifo_read_idx & 2047]; - snd->fifo_read_idx++; - } - - if ((snd->fifo_write_idx - snd->fifo_read_idx) == snd->fifo_threshold) - snd->status |= 0x02; /*FIFO almost empty*/ - - snd->status |= 0x10; /*ADC data ready*/ - update_irq_status(snd); - - snd->timer_count += snd->timer_latch * TIMER_USEC; -} - - -static void -snd_get_buffer(int32_t *buffer, int len, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - int c; - - snd_update(snd); - - for (c = 0; c < len * 2; c++) - buffer[c] += snd->buffer[c >> 1]; - - snd->pos = 0; -} - - -static void * -snd_init(const device_t *info) -{ - ps1snd_t *snd; - - snd = malloc(sizeof(ps1snd_t)); - memset(snd, 0x00, sizeof(ps1snd_t)); - - sn76489_init(&snd->sn76489, 0x0205, 0x0001, SN76496, 4000000); - - io_sethandler(0x0200, 1, snd_read,NULL,NULL, snd_write,NULL,NULL, snd); - io_sethandler(0x0202, 6, snd_read,NULL,NULL, snd_write,NULL,NULL, snd); - - timer_add(snd_callback, &snd->timer_count, &snd->timer_enable, snd); - - sound_add_handler(snd_get_buffer, snd); - - return(snd); -} - - -static void -snd_close(void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - free(snd); -} - - -static const device_t snd_device = { - "PS/1 Audio Card", - 0, 0, - snd_init, snd_close, NULL, - NULL, - NULL, - NULL -}; - - -static void -recalc_memory(ps1_t *ps) -{ - /* Enable first 512K */ - mem_set_mem_state(0x00000, 0x80000, - (ps->ps1_e0_regs[0] & 0x01) ? - (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : - (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - - /* Enable 512-640K */ - mem_set_mem_state(0x80000, 0x20000, - (ps->ps1_e0_regs[1] & 0x01) ? - (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : - (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); -} - - -static void -ps1_write(uint16_t port, uint8_t val, void *priv) -{ - ps1_t *ps = (ps1_t *)priv; - - switch (port) { - case 0x0092: - if (ps->model != 2011) { - if (val & 1) { - softresetx86(); - cpu_set_edx(); - } - ps->ps1_92 = val & ~1; - } else { - ps->ps1_92 = val; - } - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - - case 0x0094: - ps->ps1_94 = val; - break; - - case 0x00e0: - if (ps->model != 2011) { - ps->ps1_e0_addr = val; - } - break; - - case 0x00e1: - if (ps->model != 2011) { - ps->ps1_e0_regs[ps->ps1_e0_addr] = val; - recalc_memory(ps); - } - break; - - case 0x0102: - lpt1_remove(); - if (val & 0x04) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_remove(1); - if (val & 0x10) { - switch ((val >> 5) & 3) { - case 0: - lpt1_init(0x03bc); - break; - case 1: - lpt1_init(0x0378); - break; - case 2: - lpt1_init(0x0278); - break; - } - } - ps->ps1_102 = val; - break; - - case 0x0103: - ps->ps1_103 = val; - break; - - case 0x0104: - ps->ps1_104 = val; - break; - - case 0x0105: - ps->ps1_105 = val; - break; - - case 0x0190: - ps->ps1_190 = val; - break; - } -} - - -static uint8_t -ps1_read(uint16_t port, void *priv) -{ - ps1_t *ps = (ps1_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x0091: - ret = ps->ps1_91; - ps->ps1_91 = 0; - break; - - case 0x0092: - ret = ps->ps1_92; - break; - - case 0x0094: - ret = ps->ps1_94; - break; - - case 0x00e1: - if (ps->model != 2011) { - ret = ps->ps1_e0_regs[ps->ps1_e0_addr]; - } - break; - - case 0x0102: - if (ps->model == 2011) - ret = ps->ps1_102 | 0x08; - else - ret = ps->ps1_102; - break; - - case 0x0103: - ret = ps->ps1_103; - break; - - case 0x0104: - ret = ps->ps1_104; - break; - - case 0x0105: - if (ps->model == 2011) - ret = ps->ps1_105; - else - ret = ps->ps1_105 | 0x80; - break; - - case 0x0190: - ret = ps->ps1_190; - break; - - default: - break; - } - - return(ret); -} - - -static void -ps1_setup(int model) -{ - ps1_t *ps; - void *priv; - - ps = (ps1_t *)malloc(sizeof(ps1_t)); - memset(ps, 0x00, sizeof(ps1_t)); - ps->model = model; - - io_sethandler(0x0091, 1, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - io_sethandler(0x0092, 1, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - io_sethandler(0x0094, 1, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - io_sethandler(0x0102, 4, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - io_sethandler(0x0190, 1, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - - lpt1_remove(); - lpt1_init(0x3bc); - - if (model == 2011) { - rom_init(&ps->high_rom, - L"roms/machines/ibmps1es/f80000.bin", - 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); - - lpt2_remove(); - - serial_remove(1); - serial_remove(2); - - /* Enable the PS/1 VGA controller. */ - if (model == 2011) - device_add(&ps1vga_device); - else - device_add(&ibm_ps1_2121_device); - - device_add(&snd_device); - - device_add(&fdc_at_actlow_device); - - /* Enable the builtin HDC. */ - if (hdc_current == 1) { - priv = device_add(&ps1_hdc_device); - - ps1_hdc_inform(priv, ps); - } - } - - if (model == 2121) { - io_sethandler(0x00e0, 2, - ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); - -#if 0 - rom_init(&ps->high_rom, - L"roms/machines/ibmps1_2121/fc0000.bin", - 0xfc0000, 0x20000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL); -#endif - - /* Initialize the video controller. */ - if (gfxcard == GFX_INTERNAL) - device_add(&ibm_ps1_2121_device); - - device_add(&fdc_at_ps1_device); - - device_add(&ide_isa_device); - - device_add(&snd_device); - } - - if (model == 2133) { - device_add(&fdc_at_device); - - device_add(&ide_isa_device); - } -} - - -static void -ps1_common_init(const machine_t *model) -{ - machine_common_init(model); - - mem_remap_top_384k(); - - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - - dma16_init(); - pic2_init(); - - device_add(&ps_nvr_device); - - device_add(&keyboard_ps2_device); - - /* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */ - if (joystick_type != 7) - device_add(&gameport_201_device); -} - - -/* Set the Card Selected Flag */ -void -ps1_set_feedback(void *priv) -{ - ps1_t *ps = (ps1_t *)priv; - - ps->ps1_91 |= 0x01; -} - - -void -machine_ps1_m2011_init(const machine_t *model) -{ - ps1_common_init(model); - - ps1_setup(2011); -} - - -void -machine_ps1_m2121_init(const machine_t *model) -{ - ps1_common_init(model); - - ps1_setup(2121); -} - - -void -machine_ps1_m2133_init(const machine_t *model) -{ - ps1_common_init(model); - - ps1_setup(2133); - - nmi_mask = 0x80; -} diff --git a/src - Cópia/machine/m_ps1_hdc.c b/src - Cópia/machine/m_ps1_hdc.c deleted file mode 100644 index 096e720b6..000000000 --- a/src - Cópia/machine/m_ps1_hdc.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * 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. - * - * Implementation of the PS/1 Model 2011 disk controller. - * - * XTA is the acronym for 'XT-Attached', which was basically - * the XT-counterpart to what we know now as IDE (which is - * also named ATA - AT Attachment.) The basic ideas was to - * put the actual drive controller electronics onto the drive - * itself, and have the host machine just talk to that using - * a simpe, standardized I/O path- hence the name IDE, for - * Integrated Drive Electronics. - * - * In the ATA version of IDE, the programming interface of - * the IBM PC/AT (which used the Western Digitial 1002/1003 - * controllers) was kept, and, so, ATA-IDE assumes a 16bit - * data path: it reads and writes 16bit words of data. The - * disk drives for this bus commonly have an 'A' suffix to - * identify them as 'ATBUS'. - * - * In XTA-IDE, which is slightly older, the programming - * interface of the IBM PC/XT (which used the MFM controller - * from Xebec) was kept, and, so, it uses an 8bit data path. - * Disk drives for this bus commonly have the 'X' suffix to - * mark them as being for this XTBUS variant. - * - * So, XTA and ATA try to do the same thing, but they use - * different ways to achive their goal. - * - * Also, XTA is **not** the same as XTIDE. XTIDE is a modern - * variant of ATA-IDE, but retro-fitted for use on 8bit XT - * systems: an extra register is used to deal with the extra - * data byte per transfer. XTIDE uses regular IDE drives, - * and uses the regular ATA/IDE programming interface, just - * with the extra register. - * - * NOTE: We should probably find a nicer way to integrate our Disk - * Type table with the main code, so the user can only select - * items from that list... - * - * Version: @(#)m_ps1_hdc.c 1.0.6 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Based on my earlier HD20 driver for the EuroPC. - * Thanks to Marco Bortolin for the help and feedback !! - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../device.h" -#include "../timer.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" -#include "../ui.h" -#include "machine.h" - - -#define HDC_TIME (200*TIMER_USEC) -#define HDC_TYPE_USER 47 /* user drive type */ - - -enum { - STATE_IDLE = 0, - STATE_RECV, - STATE_RDATA, - STATE_RDONE, - STATE_SEND, - STATE_SDATA, - STATE_SDONE, - STATE_FINIT, - STATE_FDONE -}; - - -/* Command values. These deviate from the XTA ones. */ -#define CMD_READ_SECTORS 0x01 /* regular read-date */ -#define CMD_READ_VERIFY 0x02 /* read for verify, no data */ -#define CMD_READ_EXT 0x03 /* read extended (ecc) */ -#define CMD_READ_ID 0x05 /* read ID mark on cyl */ -#define CMD_RECALIBRATE 0x08 /* recalibrate to track0 */ -#define CMD_WRITE_SECTORS 0x09 /* regular write-data */ -#define CMD_WRITE_VERIFY 0x0a /* write-data with verify */ -#define CMD_WRITE_EXT 0x0b /* write extended (ecc) */ -#define CMD_FORMAT_DRIVE 0x0d /* format entire disk */ -#define CMD_SEEK 0x0e /* seek */ -#define CMD_FORMAT_TRACK 0x0f /* format one track */ - -/* Attachment Status register (reg 2R) values (IBM PS/1 2011.) */ -#define ASR_TX_EN 0x01 /* transfer enable */ -#define ASR_INT_REQ 0x02 /* interrupt request */ -#define ASR_BUSY 0x04 /* busy */ -#define ASR_DIR 0x08 /* direction */ -#define ASR_DATA_REQ 0x10 /* data request */ - -/* Attachment Control register (2W) values (IBM PS/1 2011.) */ -#define ACR_DMA_EN 0x01 /* DMA enable */ -#define ACR_INT_EN 0x02 /* interrupt enable */ -#define ACR_RESET 0x80 /* reset */ - -/* Interrupt Status register (4R) values (IBM PS/1 2011.) */ -#define ISR_EQUIP_CHECK 0x01 /* internal hardware error */ -#define ISR_ERP_INVOKED 0x02 /* error recovery invoked */ -#define ISR_CMD_REJECT 0x20 /* command reject */ -#define ISR_INVALID_CMD 0x40 /* invalid command */ -#define ISR_TERMINATION 0x80 /* termination error */ - -/* Attention register (4W) values (IBM PS/1 2011.) */ -#define ATT_DATA 0x10 /* data request */ -#define ATT_SSB 0x20 /* sense summary block */ -#define ATT_CSB 0x40 /* command specify block */ -#define ATT_CCB 0x80 /* command control block */ - - -/* - * Define the Sense Summary Block. - * - * The sense summary block contains the current status of the - * drive. The information in the summary block is updated after - * each command is completed, after an error, or before the - * block is transferred. - */ -#pragma pack(push,1) -typedef struct { - /* Status byte 0. */ - uint8_t track_0 :1, /* T0 */ - mbz1 :1, /* 0 */ - mbz2 :1, /* 0 */ - cylinder_err :1, /* CE */ - write_fault :1, /* WF */ - mbz3 :1, /* 0 */ - seek_end :1, /* SE */ - not_ready :1; /* NR */ - - /* Status byte 1. */ - uint8_t id_not_found :1, /* ID */ - mbz4 :1, /* 0 */ - mbz5 :1, /* 0 */ - wrong_cyl :1, /* WC */ - all_bit_set :1, /* BT */ - mark_not_found :1, /* AM */ - ecc_crc_err :1, /* ET */ - ecc_crc_field :1; /* EF */ - - /* Status byte 2. */ - uint8_t headsel_state :4, /* headsel state[4] */ - defective_sector:1, /* DS */ - retried_ok :1, /* RG */ - need_reset :1, /* RR */ -#if 1 - valid :1; /* 0 (abused as VALID) */ -#else - mbz6 :1; /* 0 */ -#endif - - /* Most recent ID field seen. */ - uint8_t last_cyl_low; /* Cyl_Low[8] */ - uint8_t last_head :4, /* HD[4] */ - mbz7 :1, /* 0 */ - last_cyl_high :2, /* Cyl_high[2] */ - last_def_sect :1; /* DS */ - uint8_t last_sect; /* Sect[8] */ - - uint8_t sect_size; /* Size[8] = 02 */ - - /* Current position. */ - uint8_t curr_cyl_high :2, /* Cyl_High_[2] */ - mbz8 :1, /* 0 */ - mbz9 :1, /* 0 */ - curr_head :4; /* HD_2[4] */ - uint8_t curr_cyl_low; /* Cyl_Low_2[8] */ - - uint8_t sect_corr; /* sectors corrected */ - - uint8_t retries; /* retries */ - - /* - * This byte shows the progress of the controller through the - * last command. It allows the system to monitor the controller - * and determine if a reset is needed. When the transfer of the - * control block is started, the value is set to hex 00. The - * progress indicated by this byte is: - * - * 1. Set to hex 01 after the control block is successfully - * transferred. - * - * 2. Set to hex 02 when the command is valid and the drive - * is ready. - * - * 3. Set to hex 03 when the head is in the correct track. - * The most-significant four bits (high nibble) are then - * used to indicate the successful stages of the data - * transfer: - * - * Bit 7 A sector was transferred between the system - * and the sector buffer. - * - * Bit 6 A sector was transferred between the controller - * and the sector buffer. - * - * Bit 5 An error was detected and error recovery - * procedures have been started. - * - * Bit 4 The controller has completed the operation - * and is now not busy. - * - * 4. When the transfer is complete, the low nibble equals hex 4 - * and the high nibble is unchanged. - */ - uint8_t cmd_syndrome; /* command syndrome */ - - uint8_t drive_type; /* drive type */ - - uint8_t rsvd; /* reserved byte */ -} ssb_t; -#pragma pack(pop) - -/* - * Define the Format Control Block. - * - * The format control block (FCB) specifies the ID data used - * in formatting the track. It is used by the Format Track - * and Format Disk commands and contains five bytes for each - * sector formatted on that track. - * - * When the Format Disk command is used, the control block - * contains the sector information of all sectors for head 0, - * cylinder 0. The drive will use the same block to format - * the rest of the disk and automatically increment the head - * number and cylinder number for the remaining tracks. The - * sector numbers, sector size, and the fill byte will be - * the same for each track. - * - * The drive formats the sector IDs on the disk in the same - * order as they are specified in the control block. - * Therefore, sector interleaving is accomplished by filling - * in the control block with the desired interleave. - * - * For example, when formatting 17 sectors per track with an - * interleave of 2, the control block has the first 5 bytes - * with a sector number of 1, the second with a sector number - * of 10, the third with a sector number of 2, and continuing - * until all 17 sectors for that track are defined. - * - * The format for the format control block is described in - * the following. The five bytes are repeated for each - * sector on the track. The control block must contain an - * even number of bytes. If an odd number of sectors are - * being formatted, an additional byte is sent with all - * bits 0. - */ -#pragma pack(push,1) -typedef struct { - uint8_t cyl_high :2, /* cylinder [9:8] bits */ - defective_sector:1, /* DS */ - mbz1 :1, /* 0 */ - head :4; /* head number */ - - uint8_t cyl_low; /* cylinder [7:0] bits */ - - uint8_t sector; /* sector number */ - - uint8_t mbz2 :1, /* 0 */ - mbo :1, /* 1 */ - mbz3 :6; /* 000000 */ - - uint8_t fill; /* filler byte */ -} fcb_t; -#pragma pack(pop) - -/* - * Define the Command Control Block. - * - * The system specifies the operation by sending the 6-byte - * command control block to the controller. It can be sent - * through a DMA or PIO operation. - */ -#pragma pack(push,1) -typedef struct { - uint8_t ec_p :1, /* EC/P (ecc/park) */ - mbz1 :1, /* 0 */ - auto_seek :1, /* AS (auto-seek) */ - no_data :1, /* ND (no data) */ - cmd :4; /* command code[4] */ - - uint8_t cyl_high :2, /* cylinder [9:8] bits */ - mbz2 :2, /* 00 */ - head :4; /* head number */ - - uint8_t cyl_low; /* cylinder [7:0] bits */ - - uint8_t sector; /* sector number */ - - uint8_t mbz3 :1, /* 0 */ - mbo1 :1, /* 1 */ - mbz4 :6; /* 000000 */ - - uint8_t count; /* blk count/interleave */ -} ccb_t; -#pragma pack(pop) - -/* Define the hard drive geometry table. */ -typedef struct { - uint16_t cyl; - uint8_t hpc; - uint8_t spt; - int16_t wpc; - int16_t lz; -} geom_t; - -/* Define an attached drive. */ -typedef struct { - int8_t id, /* drive ID on bus */ - present, /* drive is present */ - hdd_num, /* index to global disk table */ - type; /* drive type ID */ - - uint16_t cur_cyl; /* last known position of heads */ - - uint8_t spt, /* active drive parameters */ - hpc; - uint16_t tracks; - - uint8_t cfg_spt, /* configured drive parameters */ - cfg_hpc; - uint16_t cfg_tracks; -} drive_t; - - -typedef struct { - uint16_t base; /* controller base I/O address */ - int8_t irq; /* controller IRQ channel */ - int8_t dma; /* controller DMA channel */ - - /* Registers. */ - uint8_t attn, /* ATTENTION register */ - ctrl, /* Control register (ACR) */ - status, /* Status register (ASR) */ - intstat; /* Interrupt Status register (ISR) */ - - void *sys; /* handle to system board */ - - /* Controller state. */ - int64_t callback; - int8_t state, /* controller state */ - reset; /* reset state counter */ - - /* Data transfer. */ - int16_t buf_idx, /* buffer index and pointer */ - buf_len; - uint8_t *buf_ptr; - - /* Current operation parameters. */ - ssb_t ssb; /* sense block */ - ccb_t ccb; /* command control block */ - uint16_t track; /* requested track# */ - uint8_t head, /* requested head# */ - sector; /* requested sector# */ - int count; /* requested sector count */ - - drive_t drives[XTA_NUM]; /* the attached drive(s) */ - - uint8_t data[512]; /* data buffer */ - uint8_t sector_buf[512]; /* sector buffer */ -} hdc_t; - - -/* - * IBM hard drive types 1-44. - * - * We need these to translate the selected disk's - * geometry back to a valid type through the SSB. - * - * Cyl. Head Sect. Write Land - * p-comp Zone - */ -static const geom_t ibm_type_table[] = { - { 0, 0, 0, 0, 0 }, /* 0 (none) */ - { 306, 4, 17, 128, 305 }, /* 1 10 MB */ - { 615, 4, 17, 300, 615 }, /* 2 20 MB */ - { 615, 6, 17, 300, 615 }, /* 3 31 MB */ - { 940, 8, 17, 512, 940 }, /* 4 62 MB */ - { 940, 6, 17, 512, 940 }, /* 5 47 MB */ - { 615, 4, 17, -1, 615 }, /* 6 20 MB */ - { 462, 8, 17, 256, 511 }, /* 7 31 MB */ - { 733, 5, 17, -1, 733 }, /* 8 30 MB */ - { 900, 15, 17, -1, 901 }, /* 9 112 MB */ - { 820, 3, 17, -1, 820 }, /* 10 20 MB */ - { 855, 5, 17, -1, 855 }, /* 11 35 MB */ - { 855, 7, 17, -1, 855 }, /* 12 50 MB */ - { 306, 8, 17, 128, 319 }, /* 13 20 MB */ - { 733, 7, 17, -1, 733 }, /* 14 43 MB */ - { 0, 0, 0, 0, 0 }, /* 15 (rsvd) */ - { 612, 4, 17, 0, 663 }, /* 16 20 MB */ - { 977, 5, 17, 300, 977 }, /* 17 41 MB */ - { 977, 7, 17, -1, 977 }, /* 18 57 MB */ - { 1024, 7, 17, 512, 1023 }, /* 19 59 MB */ - { 733, 5, 17, 300, 732 }, /* 20 30 MB */ - { 733, 7, 17, 300, 732 }, /* 21 43 MB */ - { 733, 5, 17, 300, 733 }, /* 22 30 MB */ - { 306, 4, 17, 0, 336 }, /* 23 10 MB */ - { 612, 4, 17, 305, 663 }, /* 24 20 MB */ - { 306, 4, 17, -1, 340 }, /* 25 10 MB */ - { 612, 4, 17, -1, 670 }, /* 26 20 MB */ - { 698, 7, 17, 300, 732 }, /* 27 41 MB */ - { 976, 5, 17, 488, 977 }, /* 28 40 MB */ - { 306, 4, 17, 0, 340 }, /* 29 10 MB */ - { 611, 4, 17, 306, 663 }, /* 30 20 MB */ - { 732, 7, 17, 300, 732 }, /* 31 43 MB */ - { 1023, 5, 17, -1, 1023 }, /* 32 42 MB */ - { 614, 4, 25, -1, 663 }, /* 33 30 MB */ - { 775, 2, 27, -1, 900 }, /* 34 20 MB */ - { 921, 2, 33, -1, 1000 }, /* 35 30 MB * */ - { 402, 4, 26, -1, 460 }, /* 36 20 MB */ - { 580, 6, 26, -1, 640 }, /* 37 44 MB */ - { 845, 2, 36, -1, 1023 }, /* 38 30 MB * */ - { 769, 3, 36, -1, 1023 }, /* 39 41 MB * */ - { 531, 4, 39, -1, 532 }, /* 40 40 MB */ - { 577, 2, 36, -1, 1023 }, /* 41 20 MB */ - { 654, 2, 32, -1, 674 }, /* 42 20 MB */ - { 923, 5, 36, -1, 1023 }, /* 43 81 MB */ - { 531, 8, 39, -1, 532 } /* 44 81 MB */ -}; - - -#ifdef ENABLE_PS1_HDC_LOG -int ps1_hdc_do_log = ENABLE_PS1_HDC_LOG; -#endif - - -static void -ps1_hdc_log(const char *fmt, ...) -{ -#ifdef ENABLE_PS1_HDC_LOG - va_list ap; - - if (ps1_hdc_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* FIXME: we should use the disk/hdd_table.c code with custom tables! */ -static int -ibm_drive_type(drive_t *drive) -{ - const geom_t *ptr; - int i; - - for (i = 0; i < (sizeof(ibm_type_table) / sizeof(geom_t)); i++) { - ptr = &ibm_type_table[i]; - if ((drive->tracks == ptr->cyl) && - (drive->hpc == ptr->hpc) && (drive->spt == ptr->spt)) return(i); - } - - return(HDC_TYPE_USER); -} - - -static void -set_intr(hdc_t *dev, int raise) -{ - if (raise) { - dev->status |= ASR_INT_REQ; - if (dev->ctrl & ACR_INT_EN) - picint(1 << dev->irq); - } else { - dev->status &= ~ASR_INT_REQ; - picintc(1 << dev->irq); - } -} - - -/* Get the logical (block) address of a CHS triplet. */ -static int -get_sector(hdc_t *dev, drive_t *drive, off64_t *addr) -{ - if (drive->cur_cyl != dev->track) { - ps1_hdc_log("HDC: get_sector: wrong cylinder %d/%d\n", - drive->cur_cyl, dev->track); - dev->ssb.wrong_cyl = 1; - return(1); - } - - if (dev->head >= drive->hpc) { - ps1_hdc_log("HDC: get_sector: past end of heads\n"); - dev->ssb.cylinder_err = 1; - return(1); - } - - if (dev->sector > drive->spt) { - ps1_hdc_log("HDC: get_sector: past end of sectors\n"); - dev->ssb.mark_not_found = 1; - return(1); - } - - /* Calculate logical address (block number) of desired sector. */ - *addr = ((((off64_t) dev->track*drive->hpc) + \ - dev->head)*drive->spt) + dev->sector - 1; - - return(0); -} - - -static void -next_sector(hdc_t *dev, drive_t *drive) -{ - if (++dev->sector > drive->spt) { - dev->sector = 1; - if (++dev->head >= drive->hpc) { - dev->head = 0; - dev->track++; - if (++drive->cur_cyl >= drive->tracks) { - drive->cur_cyl = drive->tracks-1; - dev->ssb.cylinder_err = 1; - } - } - } -} - - -/* Finish up. Repeated all over, so a function it is now. */ -static void -do_finish(hdc_t *dev) -{ - dev->state = STATE_IDLE; - - dev->attn &= ~(ATT_CCB | ATT_DATA); - - dev->status = 0x00; - - set_intr(dev, 1); -} - - -/* Seek to a cylinder. */ -static int -do_seek(hdc_t *dev, drive_t *drive, uint16_t cyl) -{ - if (cyl >= drive->tracks) { - dev->ssb.cylinder_err = 1; - return(1); - } - - dev->track = cyl; - drive->cur_cyl = dev->track; - - return(0); -} - - -/* Format a track or an entire drive. */ -static void -do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) -{ - int start_cyl, end_cyl; - int intr = 0, val; - off64_t addr; -#if 0 - fcb_t *fcb; -#endif - - /* Get the parameters from the CCB. */ - if (ccb->cmd == CMD_FORMAT_DRIVE) { - start_cyl = 0; - end_cyl = drive->tracks; - } else { - start_cyl = (ccb->cyl_low | (ccb->cyl_high << 8)); - end_cyl = start_cyl + 1; - } - - switch (dev->state) { - case STATE_IDLE: - /* Ready to transfer the FCB data in. */ - dev->state = STATE_RDATA; - dev->buf_idx = 0; - dev->buf_ptr = dev->data; - dev->buf_len = ccb->count * sizeof(fcb_t); - if (dev->buf_len & 1) - dev->buf_len++; /* must be even */ - - /* Enable for PIO or DMA, as needed. */ -#if NOT_USED - if (dev->ctrl & ACR_DMA_EN) - dev->callback = HDC_TIME; - else -#endif - dev->status |= ASR_DATA_REQ; - break; - - case STATE_RDATA: - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - dev->intstat |= ISR_EQUIP_CHECK; - dev->ssb.need_reset = 1; - intr = 1; - break; - } - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - dev->state = STATE_RDONE; - dev->callback = HDC_TIME; - break; - - case STATE_RDONE: - if (! (dev->ctrl & ACR_DMA_EN)) - dev->status &= ~ASR_DATA_REQ; - - /* Point to the FCB we got. */ -#if 0 - fcb = (fcb_t *)dev->data; -#endif - dev->state = STATE_FINIT; - /*FALLTHROUGH*/ - - case STATE_FINIT: -do_fmt: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); - - /* Seek to cylinder. */ - if (do_seek(dev, drive, start_cyl)) { - intr = 1; - break; - } - dev->head = ccb->head; - dev->sector = 1; - - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) { - intr = 1; - break; - } - - /* - * For now, we don't use the info from - * the FCB, although we should at least - * use it's "filler byte" value... - */ -#if 0 - hdd_image_zero_ex(drive->hdd_num, addr, fcb->fill, drive->spt); -#else - hdd_image_zero(drive->hdd_num, addr, drive->spt); -#endif - - /* Done with this track. */ - dev->state = STATE_FDONE; - /*FALLTHROUGH*/ - - case STATE_FDONE: - /* One more track done. */ - if (++start_cyl == end_cyl) { - intr = 1; - break; - } - - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - /* This saves us a LOT of code. */ - dev->state = STATE_FINIT; - goto do_fmt; - } - - /* If we errored out, go back idle. */ - if (intr) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - do_finish(dev); - } -} - - -/* Execute the CCB we just received. */ -static void -hdc_callback(void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - ccb_t *ccb = &dev->ccb; - drive_t *drive; - off64_t addr; - int no_data = 0; - int val; - - /* Cancel timer. */ - dev->callback = 0; - - /* Clear the SSB error bits. */ - dev->ssb.track_0 = 0; - dev->ssb.cylinder_err = 0; - dev->ssb.write_fault = 0; - dev->ssb.seek_end = 0; - dev->ssb.not_ready = 0; - dev->ssb.id_not_found = 0; - dev->ssb.wrong_cyl = 0; - dev->ssb.all_bit_set = 0; - dev->ssb.mark_not_found = 0; - dev->ssb.ecc_crc_err = 0; - dev->ssb.ecc_crc_field = 0; - dev->ssb.valid = 1; - - /* We really only support one drive, but ohwell. */ - drive = &dev->drives[0]; - - switch (ccb->cmd) { - case CMD_READ_VERIFY: - no_data = 1; - /*FALLTHROUGH*/ - - case CMD_READ_SECTORS: - if (! drive->present) { - dev->ssb.not_ready = 1; - do_finish(dev); - return; - } - - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder if requested. */ - if (ccb->auto_seek) { - if (do_seek(dev, drive, - (ccb->cyl_low|(ccb->cyl_high<<8)))) { - do_finish(dev); - return; - } - } - dev->head = ccb->head; - dev->sector = ccb->sector; - - /* Get sector count and size. */ - dev->count = (int)ccb->count; - dev->buf_len = (128 << dev->ssb.sect_size); - - dev->state = STATE_SEND; - /*FALLTHROUGH*/ - - case STATE_SEND: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); - -do_send: - /* Get address of sector to load. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - do_finish(dev); - return; - } - - /* Read the block from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - - /* Ready to transfer the data out. */ - dev->state = STATE_SDATA; - dev->buf_idx = 0; - if (no_data) { - /* Delay a bit, no actual transfer. */ - dev->callback = HDC_TIME; - } else { - if (dev->ctrl & ACR_DMA_EN) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - dev->callback = HDC_TIME; - } else { - /* No DMA, do PIO. */ - dev->status |= (ASR_DATA_REQ|ASR_DIR); - - /* Copy from sector to data. */ - memcpy(dev->data, - dev->sector_buf, - (128<ssb.sect_size)); - dev->buf_ptr = dev->data; - } - } - break; - - case STATE_SDATA: - if (! no_data) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_write(dev->dma, - *dev->buf_ptr++); - if (val == DMA_NODATA) { - ps1_hdc_log("HDC: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->buf_idx, dev->buf_len); - - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - dev->intstat |= ISR_EQUIP_CHECK; - dev->ssb.need_reset = 1; - do_finish(dev); - return; - } - dev->buf_idx++; - } - } - dev->state = STATE_SDONE; - dev->callback = HDC_TIME; - break; - - case STATE_SDONE: - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - if (! (dev->ctrl & ACR_DMA_EN)) - dev->status &= ~(ASR_DATA_REQ|ASR_DIR); - dev->ssb.cmd_syndrome = 0xD4; - do_finish(dev); - return; - } - - /* Addvance to next sector. */ - next_sector(dev, drive); - - /* This saves us a LOT of code. */ - dev->state = STATE_SEND; - goto do_send; - } - break; - - case CMD_READ_EXT: /* READ_EXT */ - case CMD_READ_ID: /* READ_ID */ - if (! drive->present) { - dev->ssb.not_ready = 1; - do_finish(dev); - return; - } - - dev->intstat |= ISR_INVALID_CMD; - do_finish(dev); - break; - - case CMD_RECALIBRATE: /* RECALIBRATE */ - if (drive->present) { - dev->track = drive->cur_cyl = 0; - } else { - dev->ssb.not_ready = 1; - dev->intstat |= ISR_TERMINATION; - } - - do_finish(dev); - break; - - case CMD_WRITE_VERIFY: - no_data = 1; - /*FALLTHROUGH*/ - - case CMD_WRITE_SECTORS: - if (! drive->present) { - dev->ssb.not_ready = 1; - do_finish(dev); - return; - } - - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder if requested. */ - if (ccb->auto_seek) { - if (do_seek(dev, drive, - (ccb->cyl_low|(ccb->cyl_high<<8)))) { - do_finish(dev); - return; - } - } - dev->head = ccb->head; - dev->sector = ccb->sector; - - /* Get sector count and size. */ - dev->count = (int)ccb->count; - dev->buf_len = (128 << dev->ssb.sect_size); - - dev->state = STATE_RECV; - /*FALLTHROUGH*/ - - case STATE_RECV: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); -do_recv: - /* Ready to transfer the data in. */ - dev->state = STATE_RDATA; - dev->buf_idx = 0; - if (no_data) { - /* Delay a bit, no actual transfer. */ - dev->callback = HDC_TIME; - } else { - if (dev->ctrl & ACR_DMA_EN) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - dev->callback = HDC_TIME; - } else { - /* No DMA, do PIO. */ - dev->buf_ptr = dev->data; - dev->status |= ASR_DATA_REQ; - } - } - break; - - case STATE_RDATA: - if (! no_data) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - ps1_hdc_log("HDC: CMD_WRITE_SECTORS out of data (idx=%d, len=%d)!\n", dev->buf_idx, dev->buf_len); - - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - dev->intstat |= ISR_EQUIP_CHECK; - dev->ssb.need_reset = 1; - do_finish(dev); - return; - } - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - } - dev->state = STATE_RDONE; - dev->callback = HDC_TIME; - break; - - case STATE_RDONE: - /* Copy from data to sector if PIO. */ - if (! (dev->ctrl & ACR_DMA_EN)) - memcpy(dev->sector_buf, dev->data, - (128<ssb.sect_size)); - - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - do_finish(dev); - return; - } - - /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - - if (! (dev->ctrl & ACR_DMA_EN)) - dev->status &= ~ASR_DATA_REQ; - dev->ssb.cmd_syndrome = 0xD4; - do_finish(dev); - return; - } - - /* Advance to next sector. */ - next_sector(dev, drive); - - /* This saves us a LOT of code. */ - dev->state = STATE_RECV; - goto do_recv; - } - break; - - case CMD_FORMAT_DRIVE: - case CMD_FORMAT_TRACK: - do_format(dev, drive, ccb); - break; - - case CMD_SEEK: - if (! drive->present) { - dev->ssb.not_ready = 1; - do_finish(dev); - return; - } - - if (ccb->ec_p == 1) { - /* Park the heads. */ - val = do_seek(dev, drive, drive->tracks-1); - } else { - /* Seek to cylinder. */ - val = do_seek(dev, drive, - (ccb->cyl_low|(ccb->cyl_high<<8))); - } - if (! val) - dev->ssb.seek_end = 1; - do_finish(dev); - break; - - default: - dev->intstat |= ISR_INVALID_CMD; - do_finish(dev); - } -} - - -/* Prepare to send the SSB block. */ -static void -hdc_send_ssb(hdc_t *dev) -{ - drive_t *drive; - - /* We only support one drive, really, but ohwell. */ - drive = &dev->drives[0]; - - if (! dev->ssb.valid) { - /* Create a valid SSB. */ - memset(&dev->ssb, 0x00, sizeof(dev->ssb)); - dev->ssb.sect_size = 0x02; /* 512 bytes */ - dev->ssb.drive_type = drive->type; - } - - /* Update position fields. */ - dev->ssb.track_0 = !!(dev->track == 0); - dev->ssb.last_cyl_low = dev->ssb.curr_cyl_low; - dev->ssb.last_cyl_high = dev->ssb.curr_cyl_high; - dev->ssb.last_head = dev->ssb.curr_head; - dev->ssb.curr_cyl_high = ((dev->track >> 8) & 0x03); - dev->ssb.curr_cyl_low = (dev->track & 0xff); - dev->ssb.curr_head = (dev->head & 0x0f); - - dev->ssb.headsel_state = dev->ssb.curr_head; - dev->ssb.last_sect = dev->sector; - - /* We abuse an unused MBZ bit, so clear it. */ - dev->ssb.valid = 0; - - /* Set up the transfer buffer for the SSB. */ - dev->buf_idx = 0; - dev->buf_len = sizeof(dev->ssb); - dev->buf_ptr = (uint8_t *)&dev->ssb; - - /* Done with the SSB. */ - dev->attn &= ~ATT_SSB; -} - - -/* Read one of the controller registers. */ -static uint8_t -hdc_read(uint16_t port, void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - uint8_t ret = 0xff; - - /* TRM: tell system board we are alive. */ - ps1_set_feedback(dev->sys); - - switch (port & 7) { - case 0: /* DATA register */ - if (dev->state == STATE_SDATA) { - if (dev->buf_idx > dev->buf_len) { - ps1_hdc_log("HDC: read with empty buffer!\n"); - dev->state = STATE_IDLE; - dev->intstat |= ISR_INVALID_CMD; - dev->status &= (ASR_TX_EN|ASR_DATA_REQ|ASR_DIR); - set_intr(dev, 1); - break; - } - - ret = dev->buf_ptr[dev->buf_idx]; - if (++dev->buf_idx == dev->buf_len) { - /* Data block sent OK. */ - dev->status &= ~(ASR_TX_EN|ASR_DATA_REQ|ASR_DIR); - dev->state = STATE_IDLE; - } - } - break; - - case 2: /* ASR */ - ret = dev->status; - break; - - case 4: /* ISR */ - ret = dev->intstat; - dev->intstat = 0x00; - break; - } - - return(ret); -} - - -static void -hdc_write(uint16_t port, uint8_t val, void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - - /* TRM: tell system board we are alive. */ - ps1_set_feedback(dev->sys); - - switch (port & 7) { - case 0: /* DATA register */ - if (dev->state == STATE_RDATA) { - if (dev->buf_idx >= dev->buf_len) { - ps1_hdc_log("HDC: write with full buffer!\n"); - dev->intstat |= ISR_INVALID_CMD; - dev->status &= ~ASR_DATA_REQ; - set_intr(dev, 1); - break; - } - - /* Store the data into the buffer. */ - dev->buf_ptr[dev->buf_idx] = val; - if (++dev->buf_idx == dev->buf_len) { - /* We got all the data we need. */ - dev->status &= ~ASR_DATA_REQ; - dev->state = STATE_IDLE; - - /* If we were receiving a CCB, execute it. */ - if (dev->attn & ATT_CCB) { - /* - * If we were already busy with - * a CCB, then it must have had - * some new data using PIO. - */ - if (dev->status & ASR_BUSY) - dev->state = STATE_RDONE; - else - dev->status |= ASR_BUSY; - - /* Schedule command execution. */ - dev->callback = HDC_TIME; - } - } - } - break; - - case 2: /* ACR */ - dev->ctrl = val; - if (val & ACR_INT_EN) - set_intr(dev, 0); /* clear IRQ */ - - if (dev->reset != 0) { - if (++dev->reset == 3) { - dev->reset = 0; - - set_intr(dev, 1); - } - break; - } - - if (val & ACR_RESET) - dev->reset = 1; - break; - - case 4: /* ATTN */ - dev->status &= ~ASR_INT_REQ; - if (val & ATT_DATA) { - /* Dunno. Start PIO/DMA now? */ - } - - if (val & ATT_SSB) { - if (dev->attn & ATT_CCB) { - /* Hey now, we're still busy for you! */ - dev->intstat |= ISR_INVALID_CMD; - set_intr(dev, 1); - break; - } - - /* OK, prepare for sending an SSB. */ - dev->attn |= ATT_SSB; - - /* Grab or initialize an SSB to send. */ - hdc_send_ssb(dev); - - dev->state = STATE_SDATA; - dev->status |= (ASR_TX_EN|ASR_DATA_REQ|ASR_DIR); - set_intr(dev, 1); - } - - if (val & ATT_CCB) { - dev->attn |= ATT_CCB; - - /* Set up the transfer buffer for a CCB. */ - dev->buf_idx = 0; - dev->buf_len = sizeof(dev->ccb); - dev->buf_ptr = (uint8_t *)&dev->ccb; - - dev->state = STATE_RDATA; - dev->status |= ASR_DATA_REQ; - set_intr(dev, 1); - } - break; - } -} - - -static void * -ps1_hdc_init(const device_t *info) -{ - drive_t *drive; - hdc_t *dev; - int c, i; - - /* Allocate and initialize device block. */ - dev = malloc(sizeof(hdc_t)); - memset(dev, 0x00, sizeof(hdc_t)); - - /* Set up controller parameters for PS/1 2011. */ - dev->base = 0x0320; - dev->irq = 14; - dev->dma = 3; - - ps1_hdc_log("HDC: initializing (I/O=%04X, IRQ=%d, DMA=%d)\n", - dev->base, dev->irq, dev->dma); - - /* Load any disks for this device class. */ - c = 0; - for (i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < 1)) { - drive = &dev->drives[hdd[i].xta_channel]; - - if (! hdd_image_load(i)) { - drive->present = 0; - continue; - } - drive->id = c; - - /* These are the "hardware" parameters (from the image.) */ - drive->cfg_spt = (uint8_t)(hdd[i].spt & 0xff); - drive->cfg_hpc = (uint8_t)(hdd[i].hpc & 0xff); - drive->cfg_tracks = (uint16_t)hdd[i].tracks; - - /* Use them as "active" parameters until overwritten. */ - drive->spt = drive->cfg_spt; - drive->hpc = drive->cfg_hpc; - drive->tracks = drive->cfg_tracks; - - drive->type = ibm_drive_type(drive); - drive->hdd_num = i; - drive->present = 1; - - ps1_hdc_log("HDC: drive%d (type %d: cyl=%d,hd=%d,spt=%d), disk %d\n", - hdd[i].xta_channel, drive->type, - drive->tracks, drive->hpc, drive->spt, i); - - if (++c > 1) break; - } - } - - /* Sectors are 1-based. */ - dev->sector = 1; - - /* Enable the I/O block. */ - io_sethandler(dev->base, 5, - hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev); - - /* Create a timer for command delays. */ - timer_add(hdc_callback, &dev->callback, &dev->callback, dev); - - return(dev); -} - - -static void -ps1_hdc_close(void *priv) -{ - hdc_t *dev = (hdc_t *)priv; - drive_t *drive; - int d; - - /* Remove the I/O handler. */ - io_removehandler(dev->base, 5, - hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev); - - /* Close all disks and their images. */ - for (d = 0; d < XTA_NUM; d++) { - drive = &dev->drives[d]; - - if (drive->present) - hdd_image_close(drive->hdd_num); - } - - /* Release the device. */ - free(dev); -} - - -const device_t ps1_hdc_device = { - "PS/1 2011 Fixed Disk Controller", - DEVICE_ISA | DEVICE_PS2, - 0, - ps1_hdc_init, ps1_hdc_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -/* - * Very nasty. - * - * The PS/1 systems employ a feedback system where external - * cards let the system know they were 'addressed' by setting - * their Card Selected Flag (CSF) in register 0x0091. Driver - * software can test this register to see if they are talking - * to hardware or not. - * - * This means, that we must somehow do the same, and yes, I - * agree that the current solution is nasty. - */ -void -ps1_hdc_inform(void *priv, void *arg) -{ - hdc_t *dev = (hdc_t *)priv; - - dev->sys = arg; -} diff --git a/src - Cópia/machine/m_ps2_isa.c b/src - Cópia/machine/m_ps2_isa.c deleted file mode 100644 index 213e06b50..000000000 --- a/src - Cópia/machine/m_ps2_isa.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.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 "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_vga.h" -#include "machine.h" - - -static uint8_t ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; - - -static struct -{ - uint8_t status, int_status; - uint8_t attention, ctrl; -} ps2_hd; - - -static uint8_t ps2_read(uint16_t port, void *p) -{ - uint8_t temp; - - switch (port) - { - case 0x91: - return 0; - case 0x94: - return ps2_94; - case 0x102: - return ps2_102 | 8; - case 0x103: - return ps2_103; - case 0x104: - return ps2_104; - case 0x105: - return ps2_105; - case 0x190: - return ps2_190; - - case 0x322: - temp = ps2_hd.status; - break; - case 0x324: - temp = ps2_hd.int_status; - ps2_hd.int_status &= ~0x02; - break; - - default: - temp = 0xff; - break; - } - - return temp; -} - -static void ps2_write(uint16_t port, uint8_t val, void *p) -{ - switch (port) - { - case 0x94: - ps2_94 = val; - break; - case 0x102: - lpt1_remove(); - if (val & 0x04) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_remove(1); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2_102 = val; - break; - case 0x103: - ps2_103 = val; - break; - case 0x104: - ps2_104 = val; - break; - case 0x105: - ps2_105 = val; - break; - case 0x190: - ps2_190 = val; - break; - - case 0x322: - ps2_hd.ctrl = val; - if (val & 0x80) - ps2_hd.status |= 0x02; - break; - case 0x324: - ps2_hd.attention = val & 0xf0; - if (ps2_hd.attention) - ps2_hd.status = 0x14; - break; - } -} - - -static void ps2board_init(void) -{ - io_sethandler(0x0091, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0094, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0102, 0x0004, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0190, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0320, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0322, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - - port_92_reset(); - - port_92_add(); - - ps2_190 = 0; - - lpt1_init(0x3bc); - - memset(&ps2_hd, 0, sizeof(ps2_hd)); -} - - -void -machine_ps2_m30_286_init(const machine_t *model) -{ - machine_common_init(model); - device_add(&fdc_at_ps1_device); - - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - dma16_init(); - device_add(&keyboard_ps2_device); - device_add(&ps_nvr_device); - pic2_init(); - ps2board_init(); - device_add(&ps1vga_device); -} diff --git a/src - Cópia/machine/m_ps2_mca.c b/src - Cópia/machine/m_ps2_mca.c deleted file mode 100644 index 1d594860d..000000000 --- a/src - Cópia/machine/m_ps2_mca.c +++ /dev/null @@ -1,1256 +0,0 @@ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../cpu/x86.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 "../serial.h" -#include "../video/vid_vga.h" -#include "machine.h" - - -static struct -{ - uint8_t adapter_setup; - uint8_t option[4]; - uint8_t pos_vga; - uint8_t setup; - uint8_t sys_ctrl_port_a; - uint8_t subaddr_lo, subaddr_hi; - - uint8_t memory_bank[8]; - - uint8_t io_id; - - mem_mapping_t shadow_mapping; - mem_mapping_t split_mapping; - mem_mapping_t expansion_mapping; - mem_mapping_t cache_mapping; - - uint8_t (*planar_read)(uint16_t port); - void (*planar_write)(uint16_t port, uint8_t val); - - uint8_t mem_regs[3]; - - uint32_t split_addr, split_size; - uint32_t split_phys; - - uint8_t mem_pos_regs[8]; - uint8_t mem_2mb_pos_regs[8]; - - int pending_cache_miss; -} ps2; - -/*The model 70 type 3/4 BIOS performs cache testing. Since 86Box doesn't have any - proper cache emulation, it's faked a bit here. - - Port E2 is used for cache diagnostics. Bit 7 seems to be set on a cache miss, - toggling bit 2 seems to clear this. The BIOS performs at least the following - tests : - - - Disable RAM, access low 64kb (386) / 8kb (486), execute code from cache to - access low memory and verify that there are no cache misses. - - Write to low memory using DMA, read low memory and verify that all accesses - cause cache misses. - - Read low memory, verify that first access is cache miss. Read again and - verify that second access is cache hit. - - These tests are also performed on the 486 model 70, despite there being no - external cache on this system. Port E2 seems to control the internal cache on - these systems. Presumably this port is connected to KEN#/FLUSH# on the 486. - This behaviour is required to pass the timer interrupt test on the 486 version - - the BIOS uses a fixed length loop that will terminate too early on a 486/25 - if it executes from internal cache. - - To handle this, 86Box uses some basic heuristics : - - If cache is enabled but RAM is disabled, accesses to low memory go directly - to cache memory. - - Reads to cache addresses not 'valid' will set the cache miss flag, and mark - that line as valid. - - Cache flushes will clear the valid array. - - DMA via the undocumented PS/2 command 0xb will clear the valid array. - - Disabling the cache will clear the valid array. - - Disabling the cache will also mark shadowed ROM areas as using ROM timings. - This works around the timing loop mentioned above. -*/ - -static uint8_t ps2_cache[65536]; -static int ps2_cache_valid[65536/8]; - - -#ifdef ENABLE_PS2_MCA_LOG -int ps2_mca_do_log = ENABLE_PS2_MCA_LOG; -#endif - - -static void -ps2_mca_log(const char *format, ...) -{ -#ifdef ENABLE_PS2_MCA_LOG - va_list ap; - - if (ps2_mca_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static uint8_t ps2_read_cache_ram(uint32_t addr, void *priv) -{ - ps2_mca_log("ps2_read_cache_ram: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); - if (!ps2_cache_valid[addr >> 3]) - { - ps2_cache_valid[addr >> 3] = 1; - ps2.mem_regs[2] |= 0x80; - } - else - ps2.pending_cache_miss = 0; - - return ps2_cache[addr]; -} -static uint16_t ps2_read_cache_ramw(uint32_t addr, void *priv) -{ - ps2_mca_log("ps2_read_cache_ramw: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); - if (!ps2_cache_valid[addr >> 3]) - { - ps2_cache_valid[addr >> 3] = 1; - ps2.mem_regs[2] |= 0x80; - } - else - ps2.pending_cache_miss = 0; - - return *(uint16_t *)&ps2_cache[addr]; -} -static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv) -{ - ps2_mca_log("ps2_read_cache_raml: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); - if (!ps2_cache_valid[addr >> 3]) - { - ps2_cache_valid[addr >> 3] = 1; - ps2.mem_regs[2] |= 0x80; - } - else - ps2.pending_cache_miss = 0; - - return *(uint32_t *)&ps2_cache[addr]; -} -static void ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv) -{ - ps2_mca_log("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins); - ps2_cache[addr] = val; -} - -void ps2_cache_clean(void) -{ - memset(ps2_cache_valid, 0, sizeof(ps2_cache_valid)); -} - -static uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_ram(addr, priv); -} -static uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_ramw(addr, priv); -} -static uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_raml(addr, priv); -} -static void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_ram(addr, val, priv); -} -static void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_ramw(addr, val, priv); -} -static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_raml(addr, val, priv); -} - -static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - return mem_read_ram(addr, priv); -} -static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - return mem_read_ramw(addr, priv); -} -static uint32_t ps2_read_split_raml(uint32_t addr, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - return mem_read_raml(addr, priv); -} -static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - mem_write_ram(addr, val, priv); -} -static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - mem_write_ramw(addr, val, priv); -} -static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv) -{ - addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; - mem_write_raml(addr, val, priv); -} - - -#define PS2_SETUP_IO 0x80 -#define PS2_SETUP_VGA 0x20 - -#define PS2_ADAPTER_SETUP 0x08 - -static uint8_t model_50_read(uint16_t port) -{ - switch (port) - { - case 0x100: - return 0xff; - case 0x101: - return 0xfb; - case 0x102: - return ps2.option[0]; - case 0x103: - return ps2.option[1]; - case 0x104: - return ps2.option[2]; - case 0x105: - return ps2.option[3]; - case 0x106: - return ps2.subaddr_lo; - case 0x107: - return ps2.subaddr_hi; - } - return 0xff; -} - -static uint8_t model_55sx_read(uint16_t port) -{ - switch (port) - { - case 0x100: - return 0xff; - case 0x101: - return 0xfb; - case 0x102: - return ps2.option[0]; - case 0x103: - return ps2.option[1]; - case 0x104: - return ps2.memory_bank[ps2.option[3] & 7]; - case 0x105: - return ps2.option[3]; - case 0x106: - return ps2.subaddr_lo; - case 0x107: - return ps2.subaddr_hi; - } - return 0xff; -} - -static uint8_t model_70_type3_read(uint16_t port) -{ - switch (port) - { - case 0x100: - return 0xff; - case 0x101: - return 0xf9; - case 0x102: - return ps2.option[0]; - case 0x103: - return ps2.option[1]; - case 0x104: - return ps2.option[2]; - case 0x105: - return ps2.option[3]; - case 0x106: - return ps2.subaddr_lo; - case 0x107: - return ps2.subaddr_hi; - } - return 0xff; -} - -static uint8_t model_80_read(uint16_t port) -{ - switch (port) - { - case 0x100: - return 0xff; - case 0x101: - return 0xfd; - case 0x102: - return ps2.option[0]; - case 0x103: - return ps2.option[1]; - case 0x104: - return ps2.option[2]; - case 0x105: - return ps2.option[3]; - case 0x106: - return ps2.subaddr_lo; - case 0x107: - return ps2.subaddr_hi; - } - return 0xff; -} - -static void model_50_write(uint16_t port, uint8_t val) -{ - switch (port) - { - case 0x100: - ps2.io_id = val; - break; - case 0x101: - break; - case 0x102: - lpt1_remove(); - serial_remove(1); - if (val & 0x04) - { - if (val & 0x08) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); - } - else - serial_remove(1); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2.option[0] = val; - break; - case 0x103: - ps2.option[1] = val; - break; - case 0x104: - ps2.option[2] = val; - break; - case 0x105: - ps2.option[3] = val; - break; - case 0x106: - ps2.subaddr_lo = val; - break; - case 0x107: - ps2.subaddr_hi = val; - break; - } -} - -static void model_55sx_write(uint16_t port, uint8_t val) -{ - switch (port) - { - case 0x100: - ps2.io_id = val; - break; - case 0x101: - break; - case 0x102: - lpt1_remove(); - serial_remove(1); - if (val & 0x04) - { - if (val & 0x08) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); - } - else - serial_remove(1); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2.option[0] = val; - break; - case 0x103: - ps2.option[1] = val; - break; - case 0x104: - ps2.memory_bank[ps2.option[3] & 7] &= ~0xf; - ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf); - ps2_mca_log("Write memory bank %i %02x\n", ps2.option[3] & 7, val); - break; - case 0x105: - ps2_mca_log("Write POS3 %02x\n", val); - ps2.option[3] = val; - shadowbios = !(val & 0x10); - shadowbios_write = val & 0x10; - - if (shadowbios) - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - mem_mapping_disable(&ps2.shadow_mapping); - } - else - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_enable(&ps2.shadow_mapping); - } - - if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20)) - mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 0x106: - ps2.subaddr_lo = val; - break; - case 0x107: - ps2.subaddr_hi = val; - break; - } -} - -static void model_70_type3_write(uint16_t port, uint8_t val) -{ - switch (port) - { - case 0x100: - break; - case 0x101: - break; - case 0x102: - lpt1_remove(); - serial_remove(1); - if (val & 0x04) - { - if (val & 0x08) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); - } - else - serial_remove(1); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2.option[0] = val; - break; - case 0x105: - ps2.option[3] = val; - break; - case 0x106: - ps2.subaddr_lo = val; - break; - case 0x107: - ps2.subaddr_hi = val; - break; - } -} - - -static void model_80_write(uint16_t port, uint8_t val) -{ - switch (port) - { - case 0x100: - break; - case 0x101: - break; - case 0x102: - lpt1_remove(); - serial_remove(1); - if (val & 0x04) - { - if (val & 0x08) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); - } - else - serial_remove(1); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2.option[0] = val; - break; - case 0x103: - ps2.option[1] = (ps2.option[1] & 0x0f) | (val & 0xf0); - break; - case 0x104: - ps2.option[2] = val; - break; - case 0x105: - ps2.option[3] = val; - break; - case 0x106: - ps2.subaddr_lo = val; - break; - case 0x107: - ps2.subaddr_hi = val; - break; - } -} - -uint8_t ps2_mca_read(uint16_t port, void *p) -{ - uint8_t temp; - - switch (port) - { - case 0x91: - fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); - case 0x94: - temp = ps2.setup; - break; - case 0x96: - temp = ps2.adapter_setup | 0x70; - break; - case 0x100: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if (!(ps2.setup & PS2_SETUP_VGA)) - temp = 0xfd; - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x101: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if (!(ps2.setup & PS2_SETUP_VGA)) - temp = 0xef; - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x102: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if (!(ps2.setup & PS2_SETUP_VGA)) - temp = ps2.pos_vga; - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x103: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x104: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x105: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x106: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - temp = mca_read(port); - else - temp = 0xff; - break; - case 0x107: - if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.planar_read(port); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - temp = mca_read(port); - else - temp = 0xff; - break; - - default: - temp = 0xff; - break; - } - - ps2_mca_log("ps2_read: port=%04x temp=%02x\n", port, temp); - - return temp; -} - -static void ps2_mca_write(uint16_t port, uint8_t val, void *p) -{ - ps2_mca_log("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); - - switch (port) - { - case 0x94: - ps2.setup = val; - break; - case 0x96: - ps2.adapter_setup = val; - mca_set_index(val & 7); - break; - case 0x100: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - mca_write(port, val); - break; - case 0x101: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) - mca_write(port, val); - break; - case 0x102: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (!(ps2.setup & PS2_SETUP_VGA)) - ps2.pos_vga = val; - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - case 0x103: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - case 0x104: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - case 0x105: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - case 0x106: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - case 0x107: - if (!(ps2.setup & PS2_SETUP_IO)) - ps2.planar_write(port, val); - else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) - mca_write(port, val); - break; - } -} - -static void ps2_mca_board_common_init() -{ - io_sethandler(0x0091, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); - io_sethandler(0x0094, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); - io_sethandler(0x0096, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); - io_sethandler(0x0100, 0x0008, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); - - port_92_reset(); - - port_92_add(); - - ps2.setup = 0xff; - - lpt1_init(0x3bc); -} - -static uint8_t ps2_mem_expansion_read(int port, void *p) -{ - return ps2.mem_pos_regs[port & 7]; -} - -static void ps2_mem_expansion_write(int port, uint8_t val, void *p) -{ - if (port < 0x102 || port == 0x104) - return; - - ps2.mem_pos_regs[port & 7] = val; - - if (ps2.mem_pos_regs[2] & 1) - mem_mapping_enable(&ps2.expansion_mapping); - else - mem_mapping_disable(&ps2.expansion_mapping); -} - -static void ps2_mca_mem_fffc_init(int start_mb) -{ - uint32_t planar_size, expansion_start; - - if (start_mb == 2) { - planar_size = 0x160000; - expansion_start = 0x260000; - } else { - planar_size = (start_mb - 1) << 20; - expansion_start = start_mb << 20; - } - - mem_mapping_set_addr(&ram_high_mapping, 0x100000, planar_size); - - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; - - switch ((mem_size / 1024) - start_mb) - { - case 1: - ps2.mem_pos_regs[4] = 0xfc; /* 11 11 11 00 = 0 0 0 1 */ - break; - case 2: - ps2.mem_pos_regs[4] = 0xfe; /* 11 11 11 10 = 0 0 0 2 */ - break; - case 3: - ps2.mem_pos_regs[4] = 0xf2; /* 11 11 00 10 = 0 0 1 2 */ - break; - case 4: - ps2.mem_pos_regs[4] = 0xfa; /* 11 11 10 10 = 0 0 2 2 */ - break; - case 5: - ps2.mem_pos_regs[4] = 0xca; /* 11 00 10 10 = 0 1 2 2 */ - break; - case 6: - ps2.mem_pos_regs[4] = 0xea; /* 11 10 10 10 = 0 2 2 2 */ - break; - case 7: - ps2.mem_pos_regs[4] = 0x2a; /* 00 10 10 10 = 1 2 2 2 */ - break; - case 8: - ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ - break; - } - - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); - mem_mapping_add(&ps2.expansion_mapping, - expansion_start, - (mem_size - (start_mb << 10)) << 10, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[expansion_start], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); -} - -static void ps2_mca_board_model_50_init() -{ - ps2_mca_board_common_init(); - - mem_remap_top_384k(); - mca_init(4); - - ps2.planar_read = model_50_read; - ps2.planar_write = model_50_write; - - if (mem_size > 2048) - { - /* Only 2 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(2); - } - - device_add(&ps1vga_device); -} - -static void ps2_mca_board_model_55sx_init() -{ - ps2_mca_board_common_init(); - - mem_mapping_add(&ps2.shadow_mapping, - (mem_size+256) * 1024, - 128*1024, - ps2_read_shadow_ram, - ps2_read_shadow_ramw, - ps2_read_shadow_raml, - ps2_write_shadow_ram, - ps2_write_shadow_ramw, - ps2_write_shadow_raml, - &ram[0xe0000], - MEM_MAPPING_INTERNAL, - NULL); - - - mem_remap_top_256k(); - ps2.option[3] = 0x10; - - memset(ps2.memory_bank, 0xf0, 8); - switch (mem_size/1024) - { - case 1: - ps2.memory_bank[0] = 0x61; - break; - case 2: - ps2.memory_bank[0] = 0x51; - break; - case 3: - ps2.memory_bank[0] = 0x51; - ps2.memory_bank[1] = 0x61; - break; - case 4: - ps2.memory_bank[0] = 0x51; - ps2.memory_bank[1] = 0x51; - break; - case 5: - ps2.memory_bank[0] = 0x01; - ps2.memory_bank[1] = 0x61; - break; - case 6: - ps2.memory_bank[0] = 0x01; - ps2.memory_bank[1] = 0x51; - break; - case 7: /*Not supported*/ - ps2.memory_bank[0] = 0x01; - ps2.memory_bank[1] = 0x51; - break; - case 8: - ps2.memory_bank[0] = 0x01; - ps2.memory_bank[1] = 0x01; - break; - } - - mca_init(4); - - ps2.planar_read = model_55sx_read; - ps2.planar_write = model_55sx_write; - - device_add(&ps1vga_device); -} - -static void mem_encoding_update() -{ - mem_mapping_disable(&ps2.split_mapping); - - ps2.split_addr = ((uint32_t) (ps2.mem_regs[0] & 0xf)) << 20; - - if (ps2.mem_regs[1] & 2) { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - ps2_mca_log("PS/2 Model 80-111: ROM space enabled\n"); - } else { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - ps2_mca_log("PS/2 Model 80-111: ROM space disabled\n"); - } - - if (ps2.mem_regs[1] & 4) { - mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0x80000); - ps2_mca_log("PS/2 Model 80-111: 00080000- 0009FFFF disabled\n"); - } else { - mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0xa0000); - ps2_mca_log("PS/2 Model 80-111: 00080000- 0009FFFF enabled\n"); - } - - if (!(ps2.mem_regs[1] & 8)) - { - if (ps2.mem_regs[1] & 4) { - ps2.split_size = 384; - ps2.split_phys = 0x80000; - } else { - ps2.split_size = 256; - ps2.split_phys = 0xa0000; - } - - mem_mapping_set_exec(&ps2.split_mapping, &ram[ps2.split_phys]); - mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, ps2.split_size << 10); - - ps2_mca_log("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); - } else - ps2_mca_log("PS/2 Model 80-111: Split memory block disabled\n"); -} - -static uint8_t mem_encoding_read(uint16_t addr, void *p) -{ - switch (addr) - { - case 0xe0: - return ps2.mem_regs[0]; - case 0xe1: - return ps2.mem_regs[1]; - } - return 0xff; -} -static void mem_encoding_write(uint16_t addr, uint8_t val, void *p) -{ - switch (addr) - { - case 0xe0: - ps2.mem_regs[0] = val; - break; - case 0xe1: - ps2.mem_regs[1] = val; - break; - } - mem_encoding_update(); -} - -static uint8_t mem_encoding_read_cached(uint16_t addr, void *p) -{ - switch (addr) - { - case 0xe0: - return ps2.mem_regs[0]; - case 0xe1: - return ps2.mem_regs[1]; - case 0xe2: - return ps2.mem_regs[2]; - } - return 0xff; -} - -static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p) -{ - uint8_t old; - - switch (addr) - { - case 0xe0: - ps2.mem_regs[0] = val; - break; - case 0xe1: - ps2.mem_regs[1] = val; - break; - case 0xe2: - old = ps2.mem_regs[2]; - ps2.mem_regs[2] = (ps2.mem_regs[2] & 0x80) | (val & ~0x88); - if (val & 2) - { - ps2_mca_log("Clear latch - %i\n", ps2.pending_cache_miss); - if (ps2.pending_cache_miss) - ps2.mem_regs[2] |= 0x80; - else - ps2.mem_regs[2] &= ~0x80; - ps2.pending_cache_miss = 0; - } - - if ((val & 0x21) == 0x20 && (old & 0x21) != 0x20) - ps2.pending_cache_miss = 1; - if ((val & 0x21) == 0x01 && (old & 0x21) != 0x01) - ps2_cache_clean(); - if (val & 0x01) - ram_mid_mapping.flags |= MEM_MAPPING_ROM; - else - ram_mid_mapping.flags &= ~MEM_MAPPING_ROM; - break; - } - ps2_mca_log("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]); - mem_encoding_update(); - if ((ps2.mem_regs[1] & 0x10) && (ps2.mem_regs[2] & 0x21) == 0x20) - { - mem_mapping_disable(&ram_low_mapping); - mem_mapping_enable(&ps2.cache_mapping); - flushmmucache(); - } - else - { - mem_mapping_disable(&ps2.cache_mapping); - mem_mapping_enable(&ram_low_mapping); - flushmmucache(); - } -} - -static void ps2_mca_board_model_70_type34_init(int is_type4) -{ - ps2_mca_board_common_init(); - - ps2.split_addr = mem_size * 1024; - mca_init(4); - - ps2.planar_read = model_70_type3_read; - ps2.planar_write = model_70_type3_write; - - device_add(&ps2_nvr_device); - - io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL); - - ps2.mem_regs[1] = 2; - - switch (mem_size/1024) - { - case 2: - ps2.option[1] = 0xa6; - ps2.option[2] = 0x01; - break; - case 4: - ps2.option[1] = 0xaa; - ps2.option[2] = 0x01; - break; - case 6: - ps2.option[1] = 0xca; - ps2.option[2] = 0x01; - break; - case 8: - default: - ps2.option[1] = 0xca; - ps2.option[2] = 0x02; - break; - } - - if (is_type4) - ps2.option[2] |= 0x04; /*486 CPU*/ - - mem_mapping_add(&ps2.split_mapping, - (mem_size+256) * 1024, - 256*1024, - ps2_read_split_ram, - ps2_read_split_ramw, - ps2_read_split_raml, - ps2_write_split_ram, - ps2_write_split_ramw, - ps2_write_split_raml, - &ram[0xa0000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.split_mapping); - - mem_mapping_add(&ps2.cache_mapping, - 0, - is_type4 ? (8 * 1024) : (64 * 1024), - ps2_read_cache_ram, - ps2_read_cache_ramw, - ps2_read_cache_raml, - ps2_write_cache_ram, - NULL, - NULL, - ps2_cache, - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.cache_mapping); - - if (mem_size > 8192) - { - /* Only 8 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(8); - } - - device_add(&ps1vga_device); -} - -static void ps2_mca_board_model_80_type2_init(int is486) -{ - ps2_mca_board_common_init(); - - ps2.split_addr = mem_size * 1024; - mca_init(8); - - ps2.planar_read = model_80_read; - ps2.planar_write = model_80_write; - - device_add(&ps2_nvr_device); - - io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL); - - ps2.mem_regs[1] = 2; - - /* Note by Kotori: I rewrote this because the original code was using - Model 80 Type 1-style 1 MB memory card settings, which are *NOT* - supported by Model 80 Type 2. */ - switch (mem_size/1024) - { - case 1: - ps2.option[1] = 0x0e; /* 11 10 = 0 2 */ - ps2.mem_regs[1] = 0xd2; /* 01 = 1 (first) */ - ps2.mem_regs[0] = 0xf0; /* 11 = invalid */ - break; - case 2: - ps2.option[1] = 0x0e; /* 11 10 = 0 2 */ - ps2.mem_regs[1] = 0xc2; /* 00 = 2 */ - ps2.mem_regs[0] = 0xf0; /* 11 = invalid */ - break; - case 3: - ps2.option[1] = 0x0a; /* 10 10 = 2 2 */ - ps2.mem_regs[1] = 0xc2; /* 00 = 2 */ - ps2.mem_regs[0] = 0xd0; /* 01 = 1 (first) */ - break; - case 4: - default: - ps2.option[1] = 0x0a; /* 10 10 = 2 2 */ - ps2.mem_regs[1] = 0xc2; /* 00 = 2 */ - ps2.mem_regs[0] = 0xc0; /* 00 = 2 */ - break; - } - - ps2.mem_regs[0] |= ((mem_size/1024) & 0x0f); - - mem_mapping_add(&ps2.split_mapping, - (mem_size+256) * 1024, - 256*1024, - ps2_read_split_ram, - ps2_read_split_ramw, - ps2_read_split_raml, - ps2_write_split_ram, - ps2_write_split_ramw, - ps2_write_split_raml, - &ram[0xa0000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.split_mapping); - - if ((mem_size > 4096) && !is486) - { - /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(4); - } - - device_add(&ps1vga_device); -} - - -static void -machine_ps2_common_init(const machine_t *model) -{ - machine_common_init(model); - device_add(&fdc_at_device); - - dma16_init(); - ps2_dma_init(); - device_add(&keyboard_ps2_mca_device); - device_add(&ps_nvr_device); - pic2_init(); - - pit_ps2_init(); - - nmi_mask = 0x80; -} - - -void -machine_ps2_model_50_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_50_init(); -} - - -void -machine_ps2_model_55sx_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_55sx_init(); -} - -void -machine_ps2_model_70_type3_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_70_type34_init(0); -} - -void -machine_ps2_model_70_type4_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_70_type34_init(1); -} - -void -machine_ps2_model_80_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_80_type2_init(0); -} - - -#ifdef WALTJE -void -machine_ps2_model_80_486_init(const machine_t *model) -{ - machine_ps2_common_init(model); - - ps2_mca_board_model_80_type2_init(1); -} -#endif diff --git a/src - Cópia/machine/m_tandy.c b/src - Cópia/machine/m_tandy.c deleted file mode 100644 index d159d63c8..000000000 --- a/src - Cópia/machine/m_tandy.c +++ /dev/null @@ -1,1781 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of Tandy models 1000, 1000HX and 1000SL2. - * - * Version: @(#)m_tandy.c 1.0.7 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../pit.h" -#include "../nmi.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.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 "machine.h" - - -#define TANDY_RGB 0 -#define TANDY_COMPOSITE 1 - - -enum { - EEPROM_IDLE = 0, - EEPROM_GET_OPERATION, - EEPROM_READ, - EEPROM_WRITE -}; - - -typedef struct { - mem_mapping_t mapping; - mem_mapping_t vram_mapping; - - uint8_t crtc[32]; - int crtcreg; - - int array_index; - uint8_t array[32]; - int memctrl; - uint8_t mode, col; - uint8_t stat; - - uint8_t *vram, *b8000; - uint32_t b8000_mask; - uint32_t b8000_limit; - uint8_t planar_ctrl; - - int linepos, - displine; - int sc, vc; - int dispon; - int con, coff, - cursoron, - blink; - int64_t vsynctime; - int vadj; - uint16_t ma, maback; - - int64_t dispontime, - dispofftime, - vidtime; - int firstline, - lastline; - - int composite; -} t1kvid_t; - -typedef struct { - int romset; - wchar_t *path; - - int state; - int count; - int addr; - int clk; - uint16_t data; - uint16_t store[64]; -} t1keep_t; - -typedef struct { - mem_mapping_t ram_mapping; - mem_mapping_t rom_mapping; /* SL2 */ - - uint8_t *rom; /* SL2 */ - uint8_t ram_bank; - uint8_t rom_bank; /* SL2 */ - int rom_offset; /* SL2 */ - - uint32_t base; - int is_sl2; - - t1kvid_t *vid; -} tandy_t; - - -static const scancode scancode_tandy[512] = { - { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, - { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, - { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, - { {0x06, -1}, {0x86, -1} }, { {0x07, -1}, {0x87, -1} }, - { {0x08, -1}, {0x88, -1} }, { {0x09, -1}, {0x89, -1} }, - { {0x0a, -1}, {0x8a, -1} }, { {0x0b, -1}, {0x8b, -1} }, - { {0x0c, -1}, {0x8c, -1} }, { {0x0d, -1}, {0x8d, -1} }, - { {0x0e, -1}, {0x8e, -1} }, { {0x0f, -1}, {0x8f, -1} }, - { {0x10, -1}, {0x90, -1} }, { {0x11, -1}, {0x91, -1} }, - { {0x12, -1}, {0x92, -1} }, { {0x13, -1}, {0x93, -1} }, - { {0x14, -1}, {0x94, -1} }, { {0x15, -1}, {0x95, -1} }, - { {0x16, -1}, {0x96, -1} }, { {0x17, -1}, {0x97, -1} }, - { {0x18, -1}, {0x98, -1} }, { {0x19, -1}, {0x99, -1} }, - { {0x1a, -1}, {0x9a, -1} }, { {0x1b, -1}, {0x9b, -1} }, - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, - { {0x1e, -1}, {0x9e, -1} }, { {0x1f, -1}, {0x9f, -1} }, - { {0x20, -1}, {0xa0, -1} }, { {0x21, -1}, {0xa1, -1} }, - { {0x22, -1}, {0xa2, -1} }, { {0x23, -1}, {0xa3, -1} }, - { {0x24, -1}, {0xa4, -1} }, { {0x25, -1}, {0xa5, -1} }, - { {0x26, -1}, {0xa6, -1} }, { {0x27, -1}, {0xa7, -1} }, - { {0x28, -1}, {0xa8, -1} }, { {0x29, -1}, {0xa9, -1} }, - { {0x2a, -1}, {0xaa, -1} }, { {0x2b, -1}, {0xab, -1} }, - { {0x2c, -1}, {0xac, -1} }, { {0x2d, -1}, {0xad, -1} }, - { {0x2e, -1}, {0xae, -1} }, { {0x2f, -1}, {0xaf, -1} }, - { {0x30, -1}, {0xb0, -1} }, { {0x31, -1}, {0xb1, -1} }, - { {0x32, -1}, {0xb2, -1} }, { {0x33, -1}, {0xb3, -1} }, - { {0x34, -1}, {0xb4, -1} }, { {0x35, -1}, {0xb5, -1} }, - { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, - { {0x38, -1}, {0xb8, -1} }, { {0x39, -1}, {0xb9, -1} }, - { {0x3a, -1}, {0xba, -1} }, { {0x3b, -1}, {0xbb, -1} }, - { {0x3c, -1}, {0xbc, -1} }, { {0x3d, -1}, {0xbd, -1} }, - { {0x3e, -1}, {0xbe, -1} }, { {0x3f, -1}, {0xbf, -1} }, - { {0x40, -1}, {0xc0, -1} }, { {0x41, -1}, {0xc1, -1} }, - { {0x42, -1}, {0xc2, -1} }, { {0x43, -1}, {0xc3, -1} }, - { {0x44, -1}, {0xc4, -1} }, { {0x45, -1}, {0xc5, -1} }, - { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, - { {0x4a, -1}, {0xca, -1} }, { {0x4b, -1}, {0xcb, -1} }, - { {0x4c, -1}, {0xcc, -1} }, { {0x4d, -1}, {0xcd, -1} }, - { {0x4e, -1}, {0xce, -1} }, { {0x4f, -1}, {0xcf, -1} }, - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, - { {0x52, -1}, {0xd2, -1} }, { {0x56, -1}, {0xd6, -1} }, - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*054*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*058*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*05c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*060*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*064*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*068*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*06c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*070*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*074*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*078*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*07c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*080*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*084*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*088*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*08c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*090*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*094*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*098*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*09c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0c8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0cc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*0fc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*100*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*104*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*108*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*10c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*110*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*114*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*118*/ - { {0x57, -1}, {0xd7, -1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*11c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*120*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*124*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*128*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*12c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*130*/ - { {-1}, {-1} }, { {0x35, -1}, {0xb5, -1} }, - { {-1}, {-1} }, { {0x37, -1}, {0xb7, -1} }, /*134*/ - { {0x38, -1}, {0xb8, -1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*138*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*13c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*140*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, /*144*/ - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, - { {-1}, {-1} }, { {0x4b, -1}, {0xcb, -1} }, /*148*/ - { {-1}, {-1} }, { {0x4d, -1}, {0xcd, -1} }, - { {-1}, {-1} }, { {0x4f, -1}, {0xcf, -1} }, /*14c*/ - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, - { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, /*150*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*154*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*158*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*15c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*160*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*164*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*168*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*16c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*170*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*174*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*148*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*17c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*180*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*184*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*88*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*18c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*190*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*194*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*198*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*19c*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1c8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1cc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} }, /*1f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, - { {-1}, {-1} }, { {-1}, {-1} } /*1fc*/ -}; -static uint8_t crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static uint8_t crtcmask_sl[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static int eep_data_out; - - -static uint8_t vid_in(uint16_t addr, void *priv); -static void vid_out(uint16_t addr, uint8_t val, void *priv); - - -#ifdef ENABLE_TANDY_LOG -int tandy_do_log = ENABLE_TANDY_LOG; -#endif - - -static void -tandy_log(const char *fmt, ...) -{ -#ifdef ENABLE_TANDY_LOG - va_list ap; - - if (tandy_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -recalc_mapping(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - mem_mapping_disable(&vid->mapping); - io_removehandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, dev); - - if (vid->planar_ctrl & 4) { - mem_mapping_enable(&vid->mapping); - if (vid->array[5] & 1) - mem_mapping_set_addr(&vid->mapping, 0xa0000, 0x10000); - else - mem_mapping_set_addr(&vid->mapping, 0xb8000, 0x8000); - io_sethandler(0x03d0, 16, vid_in,NULL,NULL, vid_out,NULL,NULL, dev); - } -} - - -static void -recalc_timings(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - double _dispontime, _dispofftime, disptime; - - if (vid->mode & 1) { - disptime = vid->crtc[0] + 1; - _dispontime = vid->crtc[1]; - } else { - disptime = (vid->crtc[0] + 1) << 1; - _dispontime = vid->crtc[1] << 1; - } - - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - vid->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - vid->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void -recalc_address(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - if ((vid->memctrl & 0xc0) == 0xc0) { - vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; - vid->b8000_mask = 0x7fff; - } else { - vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; - vid->b8000_mask = 0x3fff; - } -} - - -static void -recalc_address_sl(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - vid->b8000_limit = 0x8000; - - if (vid->array[5] & 1) { - vid->vram = &ram[((vid->memctrl & 0x04) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x20) << 11) + dev->base]; - } else if ((vid->memctrl & 0xc0) == 0xc0) { - vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; - } else { - vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; - if ((vid->memctrl & 0x38) == 0x38) - vid->b8000_limit = 0x4000; - } -} - - -static void -vid_out(uint16_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - uint8_t old; - - switch (addr) { - case 0x03d4: - vid->crtcreg = val & 0x1f; - break; - - case 0x03d5: - old = vid->crtc[vid->crtcreg]; - if (dev->is_sl2) - vid->crtc[vid->crtcreg] = val & crtcmask_sl[vid->crtcreg]; - else - vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg]; - if (old != val) { - if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { - fullchange = changeframecount; - recalc_timings(dev); - } - } - break; - - case 0x03d8: - vid->mode = val; - if (! dev->is_sl2) - update_cga16_color(vid->mode); - break; - - case 0x03d9: - vid->col = val; - break; - - case 0x03da: - vid->array_index = val & 0x1f; - break; - - case 0x03de: - if (vid->array_index & 16) - val &= 0xf; - vid->array[vid->array_index & 0x1f] = val; - if (dev->is_sl2) { - if ((vid->array_index & 0x1f) == 5) { - recalc_mapping(dev); - recalc_address_sl(dev); - } - } - break; - - case 0x03df: - vid->memctrl = val; - if (dev->is_sl2) - recalc_address_sl(dev); - else - recalc_address(dev); - break; - - case 0x0065: - if (val == 8) return; /*Hack*/ - vid->planar_ctrl = val; - recalc_mapping(dev); - break; - } -} - - -static uint8_t -vid_in(uint16_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - uint8_t ret = 0xff; - - switch (addr) { - case 0x03d4: - ret = vid->crtcreg; - break; - - case 0x03d5: - ret = vid->crtc[vid->crtcreg]; - break; - - case 0x03da: - ret = vid->stat; - break; - } - - return(ret); -} - - -static void -vid_write(uint32_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - - if (vid->memctrl == -1) return; - - egawrites++; - if (dev->is_sl2) { - if (vid->array[5] & 1) - vid->b8000[addr & 0xffff] = val; - else { - if ((addr & 0x7fff) < vid->b8000_limit) - vid->b8000[addr & 0x7fff] = val; - } - } else { - vid->b8000[addr & vid->b8000_mask] = val; - } -} - - -static uint8_t -vid_read(uint32_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - - if (vid->memctrl == -1) return(0xff); - - egareads++; - if (dev->is_sl2) { - if (vid->array[5] & 1) - return(vid->b8000[addr & 0xffff]); - if ((addr & 0x7fff) < vid->b8000_limit) - return(vid->b8000[addr & 0x7fff]); - else - return(0xff); - } else { - return(vid->b8000[addr & vid->b8000_mask]); - } -} - - -static void -vid_poll(void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int cols[4]; - int col; - int oldsc; - - if (! vid->linepos) { - vid->vidtime += vid->dispofftime; - vid->stat |= 1; - vid->linepos = 1; - oldsc = vid->sc; - if ((vid->crtc[8] & 3) == 3) - vid->sc = (vid->sc << 1) & 7; - - if (vid->dispon) { - if (vid->displine < vid->firstline) { - vid->firstline = vid->displine; - video_wait_for_buffer(); - } - vid->lastline = vid->displine; - cols[0] = (vid->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - if (vid->array[3] & 4) { - buffer->line[vid->displine][c] = cols[0]; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = cols[0]; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = cols[0]; - } else if ((vid->mode & 0x12) == 0x12) { - buffer->line[vid->displine][c] = 0; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = 0; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = 0; - } else { - buffer->line[vid->displine][c] = (vid->col & 15) + 16; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; - } - } - - if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - buffer->line[vid->displine][(x << 3) + 8] = - buffer->line[vid->displine][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 10] = - buffer->line[vid->displine][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 12] = - buffer->line[vid->displine][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 14] = - buffer->line[vid->displine][(x << 3) + 15] = vid->array[(dat & vid->array[1]) + 16] + 16; - } - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - buffer->line[vid->displine][(x << 4) + 8] = - buffer->line[vid->displine][(x << 4) + 9] = - buffer->line[vid->displine][(x << 4) + 10] = - buffer->line[vid->displine][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 12] = - buffer->line[vid->displine][(x << 4) + 13] = - buffer->line[vid->displine][(x << 4) + 14] = - buffer->line[vid->displine][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 16] = - buffer->line[vid->displine][(x << 4) + 17] = - buffer->line[vid->displine][(x << 4) + 18] = - buffer->line[vid->displine][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 20] = - buffer->line[vid->displine][(x << 4) + 21] = - buffer->line[vid->displine][(x << 4) + 22] = - buffer->line[vid->displine][(x << 4) + 23] = vid->array[(dat & vid->array[1]) + 16] + 16; - } - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - buffer->line[vid->displine][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16; - dat <<= 1; - } - } - } else if (vid->mode & 1) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[ (vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[ ((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - if (vid->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] ^= 15; - } - vid->ma++; - } - } else if (! (vid->mode & 2)) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[ (vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[ ((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - vid->ma++; - if (vid->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 16; c++) - buffer->line[vid->displine][(x << 4) + c + 8] ^= 15; - } - } - } else if (! (vid->mode& 16)) { - cols[0] = (vid->col & 15) | 16; - col = (vid->col & 16) ? 24 : 16; - if (vid->mode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (vid->col & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16; - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 16; c++) { - buffer->line[vid->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - if (vid->array[3] & 4) { - if (vid->mode & 1) - hline(buffer, 0, vid->displine, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); - else - hline(buffer, 0, vid->displine, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); - } else { - cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16; - if (vid->mode & 1) - hline(buffer, 0, vid->displine, (vid->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer, 0, vid->displine, (vid->crtc[1] << 4) + 16, cols[0]); - } - } - - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - if (vid->composite) { - for (c = 0; c < x; c++) - buffer32->line[vid->displine][c] = buffer->line[vid->displine][c] & 0xf; - - Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine]); - } - vid->sc = oldsc; - if (vid->vc == vid->crtc[7] && !vid->sc) - vid->stat |= 8; - vid->displine++; - if (vid->displine >= 360) - vid->displine = 0; - } else { - vid->vidtime += vid->dispontime; - if (vid->dispon) - vid->stat &= ~1; - vid->linepos = 0; - if (vid->vsynctime) { - vid->vsynctime--; - if (! vid->vsynctime) - vid->stat &= ~8; - } - if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) { - vid->con = 0; - vid->coff = 1; - } - if (vid->vadj) { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - vid->vadj--; - if (! vid->vadj) { - vid->dispon = 1; - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - vid->sc = 0; - } - } else if (vid->sc == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->sc == (vid->crtc[9] >> 1))) { - vid->maback = vid->ma; - vid->sc = 0; - oldvc = vid->vc; - vid->vc++; - vid->vc &= 127; - if (vid->vc == vid->crtc[6]) - vid->dispon = 0; - if (oldvc == vid->crtc[4]) { - vid->vc = 0; - vid->vadj = vid->crtc[5]; - if (! vid->vadj) - vid->dispon = 1; - if (! vid->vadj) - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - if ((vid->crtc[10] & 0x60) == 0x20) - vid->cursoron = 0; - else - vid->cursoron = vid->blink & 16; - } - if (vid->vc == vid->crtc[7]) { - vid->dispon = 0; - vid->displine = 0; - vid->vsynctime = 16; - if (vid->crtc[7]) { - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - vid->lastline++; - if ((x != xsize) || ((vid->lastline - vid->firstline) != ysize) || video_force_resize_get()) { - xsize = x; - ysize = vid->lastline - vid->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - if (video_force_resize_get()) - video_force_resize_set(0); - } - if (vid->composite) - video_blit_memtoscreen(0, vid->firstline-4, 0, (vid->lastline - vid->firstline) + 8, xsize, (vid->lastline - vid->firstline) + 8); - else - video_blit_memtoscreen_8(0, vid->firstline-4, 0, (vid->lastline - vid->firstline) + 8, xsize, (vid->lastline - vid->firstline) + 8); - - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - video_res_x /= 2; - video_bpp = 4; - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - video_res_x /= 4; - video_bpp = 4; - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - video_bpp = 2; - } else if (vid->mode & 1) { - video_res_x /= 8; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->mode & 2)) { - video_res_x /= 16; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->mode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - vid->firstline = 1000; - vid->lastline = 0; - vid->blink++; - } - } else { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - } - if ((vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1)))) - vid->con = 1; - } -} - - -static void -vid_poll_sl(void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - t1kvid_t *vid = dev->vid; - uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int cols[4]; - int col; - int oldsc; - - if (! vid->linepos) { - vid->vidtime += vid->dispofftime; - vid->stat |= 1; - vid->linepos = 1; - oldsc = vid->sc; - if ((vid->crtc[8] & 3) == 3) - vid->sc = (vid->sc << 1) & 7; - if (vid->dispon) { - if (vid->displine < vid->firstline) { - vid->firstline = vid->displine; - video_wait_for_buffer(); - } - vid->lastline = vid->displine; - cols[0] = (vid->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - if (vid->array[3] & 4) { - buffer->line[vid->displine][c] = cols[0]; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = cols[0]; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = cols[0]; - } else if ((vid->mode & 0x12) == 0x12) { - buffer->line[vid->displine][c] = 0; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = 0; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = 0; - } else { - buffer->line[vid->displine][c] = (vid->col & 15) + 16; - if (vid->mode & 1) - buffer->line[vid->displine][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; - else - buffer->line[vid->displine][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; - } - } - if (vid->array[5] & 1) { /*640x200x16*/ - for (x = 0; x < vid->crtc[1]*2; x++) { - dat = (vid->vram[(vid->ma << 1) & 0xffff] << 8) | - vid->vram[((vid->ma << 1) + 1) & 0xffff]; - vid->ma++; - buffer->line[vid->displine][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf)/*vid->array[1])*/ + 16] + 16; - buffer->line[vid->displine][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf)/*vid->array[1])*/ + 16] + 16; - buffer->line[vid->displine][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf)/*vid->array[1])*/ + 16] + 16; - buffer->line[vid->displine][(x << 2) + 11] = vid->array[(dat & 0xf)/*vid->array[1])*/ + 16] + 16; - } - } else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - buffer->line[vid->displine][(x << 3) + 8] = - buffer->line[vid->displine][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 10] = - buffer->line[vid->displine][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 12] = - buffer->line[vid->displine][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 3) + 14] = - buffer->line[vid->displine][(x << 3) + 15] = vid->array[(dat & vid->array[1]) + 16] + 16; - } - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - buffer->line[vid->displine][(x << 4) + 8] = - buffer->line[vid->displine][(x << 4) + 9] = - buffer->line[vid->displine][(x << 4) + 10] = - buffer->line[vid->displine][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 12] = - buffer->line[vid->displine][(x << 4) + 13] = - buffer->line[vid->displine][(x << 4) + 14] = - buffer->line[vid->displine][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 16] = - buffer->line[vid->displine][(x << 4) + 17] = - buffer->line[vid->displine][(x << 4) + 18] = - buffer->line[vid->displine][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1]) + 16] + 16; - buffer->line[vid->displine][(x << 4) + 20] = - buffer->line[vid->displine][(x << 4) + 21] = - buffer->line[vid->displine][(x << 4) + 22] = - buffer->line[vid->displine][(x << 4) + 23] = vid->array[(dat & vid->array[1]) + 16] + 16; - } - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - buffer->line[vid->displine][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16; - dat <<= 1; - } - } - } else if (vid->mode & 1) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[ (vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[ ((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - if (vid->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 3) + c + 8] ^= 15; - } - vid->ma++; - } - } else if (! (vid->mode & 2)) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[ (vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[ ((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - vid->ma++; - if (vid->sc & 8) { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 16; c++) - buffer->line[vid->displine][(x << 4) + c + 8] ^= 15; - } - } - } else if (! (vid->mode & 16)) { - cols[0] = (vid->col & 15) | 16; - col = (vid->col & 16) ? 24 : 16; - if (vid->mode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (vid->col & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = - buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16; - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | - vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 16; c++) { - buffer->line[vid->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - if (vid->array[3] & 4) { - if (vid->mode & 1) - hline(buffer, 0, vid->displine, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); - else - hline(buffer, 0, vid->displine, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); - } else { - cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16; - if (vid->mode & 1) - hline(buffer, 0, vid->displine, (vid->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer, 0, vid->displine, (vid->crtc[1] << 4) + 16, cols[0]); - } - } - - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - vid->sc = oldsc; - - if (vid->vc == vid->crtc[7] && !vid->sc) - vid->stat |= 8; - vid->displine++; - if (vid->displine >= 360) - vid->displine = 0; - } else { - vid->vidtime += vid->dispontime; - if (vid->dispon) - vid->stat &= ~1; - vid->linepos = 0; - if (vid->vsynctime) { - vid->vsynctime--; - if (! vid->vsynctime) - vid->stat &= ~8; - } - if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) { - vid->con = 0; - vid->coff = 1; - } - if (vid->vadj) { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - vid->vadj--; - if (! vid->vadj) { - vid->dispon = 1; - if (vid->array[5] & 1) - vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8); - else - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - vid->sc = 0; - } - } else if (vid->sc == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->sc == (vid->crtc[9] >> 1))) { - vid->maback = vid->ma; - vid->sc = 0; - oldvc = vid->vc; - vid->vc++; - vid->vc &= 255; - if (vid->vc == vid->crtc[6]) - vid->dispon = 0; - if (oldvc == vid->crtc[4]) { - vid->vc = 0; - vid->vadj = vid->crtc[5]; - if (! vid->vadj) - vid->dispon = 1; - if (! vid->vadj) { - if (vid->array[5] & 1) - vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8); - else - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - } - if ((vid->crtc[10] & 0x60) == 0x20) - vid->cursoron = 0; - else - vid->cursoron = vid->blink & 16; - } - if (vid->vc == vid->crtc[7]) { - vid->dispon = 0; - vid->displine = 0; - vid->vsynctime = 16; - if (vid->crtc[7]) { - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - vid->lastline++; - if ((x != xsize) || ((vid->lastline - vid->firstline) != ysize) || video_force_resize_get()) { - xsize = x; - ysize = vid->lastline - vid->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - - set_screen_size(xsize, (ysize << 1) + 16); - if (video_force_resize_get()) - video_force_resize_set(0); - } - - video_blit_memtoscreen_8(0, vid->firstline-4, 0, (vid->lastline - vid->firstline) + 8, xsize, (vid->lastline - vid->firstline) + 8); - - frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - video_res_x /= 2; - video_bpp = 4; - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - video_res_x /= 4; - video_bpp = 4; - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - video_bpp = 2; - } else if (vid->mode & 1) { - video_res_x /= 8; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->mode & 2)) { - video_res_x /= 16; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (! (vid->mode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - vid->firstline = 1000; - vid->lastline = 0; - vid->blink++; - } - } else { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - } - if ((vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1)))) - vid->con = 1; - } -} - - -static void -vid_speed_changed(void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - recalc_timings(dev); -} - - -static void -vid_close(void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - free(dev->vid); - dev->vid = NULL; -} - - -static void -vid_init(tandy_t *dev) -{ - int display_type; - t1kvid_t *vid; - - vid = malloc(sizeof(t1kvid_t)); - memset(vid, 0x00, sizeof(t1kvid_t)); - vid->memctrl = -1; - dev->vid = vid; - - display_type = machine_get_config_int("display_type"); - vid->composite = (display_type != TANDY_RGB); - - cga_comp_init(1); - - if (dev->is_sl2) { - vid->b8000_limit = 0x8000; - vid->planar_ctrl = 4; - overscan_x = overscan_y = 16; - - io_sethandler(0x0065, 1, vid_in,NULL,NULL, vid_out,NULL,NULL, dev); - - timer_add(vid_poll_sl, &vid->vidtime, TIMER_ALWAYS_ENABLED, dev); - } else { - vid->b8000_mask = 0x3fff; - - timer_add(vid_poll, &vid->vidtime, TIMER_ALWAYS_ENABLED, dev); - } - mem_mapping_add(&vid->mapping, 0xb8000, 0x08000, - vid_read,NULL,NULL, vid_write,NULL,NULL, NULL, 0, dev); - io_sethandler(0x03d0, 16, - vid_in,NULL,NULL, vid_out,NULL,NULL, dev); -} - - -static const device_config_t vid_config[] = { - { - "display_type", "Display type", CONFIG_SELECTION, "", TANDY_RGB, - { - { - "RGB", TANDY_RGB - }, - { - "Composite", TANDY_COMPOSITE - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_t vid_device = { - "Tandy 1000", - 0, 0, - NULL, vid_close, NULL, - NULL, - vid_speed_changed, - NULL, - vid_config -}; - -static const device_t vid_device_hx = { - "Tandy 1000 HX", - 0, 0, - NULL, vid_close, NULL, - NULL, - vid_speed_changed, - NULL, - vid_config -}; - -static const device_t vid_device_sl = { - "Tandy 1000SL2", - 0, 1, - NULL, vid_close, NULL, - NULL, - vid_speed_changed, - NULL, - NULL -}; - - -const device_t * -tandy1k_get_device(void) -{ - return &vid_device; -} - - -const device_t * -tandy1k_hx_get_device(void) -{ - return &vid_device_hx; -} - - -static void -eep_write(uint16_t addr, uint8_t val, void *priv) -{ - t1keep_t *eep = (t1keep_t *)priv; - - if ((val & 4) && !eep->clk) switch (eep->state) { - case EEPROM_IDLE: - switch (eep->count) { - case 0: - if (! (val & 3)) - eep->count = 1; - else - eep->count = 0; - break; - - case 1: - if ((val & 3) == 2) - eep->count = 2; - else - eep->count = 0; - break; - - case 2: - if ((val & 3) == 3) - eep->state = EEPROM_GET_OPERATION; - eep->count = 0; - break; - } - break; - - case EEPROM_GET_OPERATION: - eep->data = (eep->data << 1) | (val & 1); - eep->count++; - if (eep->count == 8) { - eep->count = 0; - eep->addr = eep->data & 0x3f; - switch (eep->data & 0xc0) { - case 0x40: - eep->state = EEPROM_WRITE; - break; - - case 0x80: - eep->state = EEPROM_READ; - eep->data = eep->store[eep->addr]; - break; - - default: - eep->state = EEPROM_IDLE; - break; - } - } - break; - - case EEPROM_READ: - eep_data_out = eep->data & 0x8000; - eep->data <<= 1; - eep->count++; - if (eep->count == 16) { - eep->count = 0; - eep->state = EEPROM_IDLE; - } - break; - - case EEPROM_WRITE: - eep->data = (eep->data << 1) | (val & 1); - eep->count++; - if (eep->count == 16) { - eep->count = 0; - eep->state = EEPROM_IDLE; - eep->store[eep->addr] = eep->data; - } - break; - } - - eep->clk = val & 4; -} - - -static void * -eep_init(const device_t *info) -{ - t1keep_t *eep; - FILE *f = NULL; - - eep = (t1keep_t *)malloc(sizeof(t1keep_t)); - memset(eep, 0x00, sizeof(t1keep_t)); - eep->romset = romset; - switch (romset) { - case ROM_TANDY1000HX: - eep->path = L"tandy1000hx.bin"; - break; - - case ROM_TANDY1000SL2: - eep->path = L"tandy1000sl2.bin"; - break; - - } - - f = nvr_fopen(eep->path, L"rb"); - if (f != NULL) { - fread(eep->store, 128, 1, f); - (void)fclose(f); - } - - io_sethandler(0x037c, 1, NULL,NULL,NULL, eep_write,NULL,NULL, eep); - - return(eep); -} - - -static void -eep_close(void *priv) -{ - t1keep_t *eep = (t1keep_t *)priv; - FILE *f = NULL; - - f = nvr_fopen(eep->path, L"rb"); - if (f != NULL) { - (void)fwrite(eep->store, 128, 1, f); - (void)fclose(f); - } - - free(eep); -} - - -static const device_t eep_device = { - "Tandy 1000 EEPROM", - 0, 0, - eep_init, eep_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -static void -tandy_write(uint16_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - switch (addr) { - case 0x00a0: - mem_mapping_set_addr(&dev->ram_mapping, - ((val >> 1) & 7) * 128 * 1024, 0x20000); - dev->ram_bank = val; - break; - - case 0xffe8: - if ((val & 0xe) == 0xe) - mem_mapping_disable(&dev->ram_mapping); - else - mem_mapping_set_addr(&dev->ram_mapping, - ((val >> 1) & 7) * 128 * 1024, - 0x20000); - recalc_address_sl(dev); - dev->ram_bank = val; - break; - - case 0xffea: - dev->rom_bank = val; - dev->rom_offset = ((val ^ 4) & 7) * 0x10000; - mem_mapping_set_exec(&dev->rom_mapping, - &dev->rom[dev->rom_offset]); - } -} - - -static uint8_t -tandy_read(uint16_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0x00a0: - ret = dev->ram_bank; - break; - - case 0xffe8: - ret = dev->ram_bank; - break; - - case 0xffea: - ret = (dev->rom_bank ^ 0x10); - break; - } - - return(ret); -} - - -static void -write_ram(uint32_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - ram[dev->base + (addr & 0x1ffff)] = val; -} - - -static uint8_t -read_ram(uint32_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - return(ram[dev->base + (addr & 0x1ffff)]); -} - - -static uint8_t -read_rom(uint32_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - uint32_t addr2 = (addr & 0xffff) + dev->rom_offset; - - return(dev->rom[addr2]); -} - - -static uint16_t -read_romw(uint32_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - uint32_t addr2 = (addr & 0xffff) + dev->rom_offset; - - return(*(uint16_t *)&dev->rom[addr2]); -} - - -static uint32_t -read_roml(uint32_t addr, void *priv) -{ - tandy_t *dev = (tandy_t *)priv; - - return(*(uint32_t *)&dev->rom[addr]); -} - - -static void -init_rom(tandy_t *dev) -{ - dev->rom = (uint8_t *)malloc(0x80000); - -#if 1 - if (! rom_load_interleaved(L"roms/machines/tandy1000sl2/8079047.hu1", - L"roms/machines/tandy1000sl2/8079048.hu2", - 0x000000, 0x80000, 0, dev->rom)) { - tandy_log("TANDY: unable to load BIOS for 1000/SL2 !\n"); - free(dev->rom); - dev->rom = NULL; - return; - } -#else - f = rom_fopen(L"roms/machines/tandy1000sl2/8079047.hu1", L"rb"); - ff = rom_fopen(L"roms/machines/tandy1000sl2/8079048.hu2", L"rb"); - for (c = 0x0000; c < 0x80000; c += 2) { - dev->rom[c] = getc(f); - dev->rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); -#endif - - mem_mapping_add(&dev->rom_mapping, 0xe0000, 0x10000, - read_rom, read_romw, read_roml, NULL, NULL, NULL, - dev->rom, MEM_MAPPING_EXTERNAL, dev); -} - - -void -machine_tandy1k_init(const machine_t *model) -{ - tandy_t *dev; - - dev = malloc(sizeof(tandy_t)); - memset(dev, 0x00, sizeof(tandy_t)); - - machine_common_init(model); - - nmi_init(); - - /* - * Base 128K mapping is controlled via ports 0xA0 or - * 0xFFE8 (SL2), so we remove it from the main mapping. - */ - dev->base = (mem_size - 128) * 1024; - mem_mapping_add(&dev->ram_mapping, 0x80000, 0x20000, - read_ram,NULL,NULL, write_ram,NULL,NULL, NULL, 0, dev); - mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); - - device_add(&keyboard_tandy_device); - keyboard_set_table(scancode_tandy); - - device_add(&fdc_xt_device); - - switch(romset) { - case ROM_TANDY: - io_sethandler(0x00a0, 1, - tandy_read,NULL,NULL,tandy_write,NULL,NULL,dev); - vid_init(dev); - device_add_ex(&vid_device, dev); - device_add(&sn76489_device); - break; - - case ROM_TANDY1000HX: - io_sethandler(0x00a0, 1, - tandy_read,NULL,NULL,tandy_write,NULL,NULL,dev); - vid_init(dev); - device_add_ex(&vid_device, dev); - device_add(&ncr8496_device); - device_add(&eep_device); - break; - - case ROM_TANDY1000SL2: - dev->is_sl2 = 1; - init_rom(dev); - io_sethandler(0xffe8, 8, - tandy_read,NULL,NULL,tandy_write,NULL,NULL,dev); - vid_init(dev); - device_add_ex(&vid_device_sl, dev); - device_add(&pssj_device); - device_add(&eep_device); - } - - if (joystick_type != 7) - device_add(&gameport_device); - - eep_data_out = 0x0000; -} - - -int -tandy1k_eeprom_read(void) -{ - return(eep_data_out); -} diff --git a/src - Cópia/machine/m_xt.c b/src - Cópia/machine/m_xt.c deleted file mode 100644 index 3878c98b1..000000000 --- a/src - Cópia/machine/m_xt.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../nmi.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "machine.h" - - -void -machine_xt_init(const machine_t *model) -{ - machine_common_init(model); - - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - - device_add(&keyboard_xt_device); - device_add(&fdc_xt_device); - nmi_init(); - if (joystick_type != 7) - device_add(&gameport_device); -} diff --git a/src - Cópia/machine/m_xt_compaq.c b/src - Cópia/machine/m_xt_compaq.c deleted file mode 100644 index 751e45da8..000000000 --- a/src - Cópia/machine/m_xt_compaq.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of various Compaq XT-class PC's. - * - * Version: @(#)m_xt_compaq.c 1.0.4 2018/03/18 - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../nmi.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 "machine.h" - - -void -machine_xt_compaq_init(const machine_t *model) -{ - machine_common_init(model); - - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - - device_add(&keyboard_xt_device); - device_add(&fdc_xt_device); - nmi_init(); - if (joystick_type != 7) - device_add(&gameport_device); - - switch(model->id) { - case ROM_PORTABLE: - lpt1_remove(); - lpt1_init(0x03bc); - break; - } -} diff --git a/src - Cópia/machine/m_xt_laserxt.c b/src - Cópia/machine/m_xt_laserxt.c deleted file mode 100644 index fe5d86606..000000000 --- a/src - Cópia/machine/m_xt_laserxt.c +++ /dev/null @@ -1,140 +0,0 @@ -/*This is the chipset used in the LaserXT series model*/ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "machine.h" - - -static int laserxt_emspage[4]; -static int laserxt_emscontrol[4]; -static mem_mapping_t laserxt_ems_mapping[4]; -static int laserxt_ems_baseaddr_index = 0; - - -static uint32_t get_laserxt_ems_addr(uint32_t addr) -{ - if(laserxt_emspage[(addr >> 14) & 3] & 0x80) - { - addr = (romset == ROM_LTXT ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)) + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); - } - - return addr; -} - - -static void laserxt_write(uint16_t port, uint8_t val, void *priv) -{ - int i; - uint32_t paddr, vaddr; - switch (port) - { - case 0x0208: case 0x4208: case 0x8208: case 0xC208: - laserxt_emspage[port >> 14] = val; - paddr = 0xC0000 + (port & 0xC000) + (((laserxt_ems_baseaddr_index + (4 - (port >> 14))) & 0x0C) << 14); - if(val & 0x80) - { - mem_mapping_enable(&laserxt_ems_mapping[port >> 14]); - vaddr = get_laserxt_ems_addr(paddr); - mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); - } - else - { - mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); - } - flushmmucache(); - break; - case 0x0209: case 0x4209: case 0x8209: case 0xC209: - laserxt_emscontrol[port >> 14] = val; - laserxt_ems_baseaddr_index = 0; - for(i=0; i<4; i++) - { - laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); - } - if(laserxt_ems_baseaddr_index < 3) - { - mem_mapping_disable(&romext_mapping); - } - else - { - mem_mapping_enable(&romext_mapping); - } - - mem_mapping_set_addr(&laserxt_ems_mapping[0], 0xC0000 + (((laserxt_ems_baseaddr_index + 4) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[1], 0xC4000 + (((laserxt_ems_baseaddr_index + 3) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[2], 0xC8000 + (((laserxt_ems_baseaddr_index + 2) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); - flushmmucache(); - break; - } -} - - -static uint8_t laserxt_read(uint16_t port, void *priv) -{ - switch (port) - { - case 0x0208: case 0x4208: case 0x8208: case 0xC208: - return laserxt_emspage[port >> 14]; - case 0x0209: case 0x4209: case 0x8209: case 0xC209: - return laserxt_emscontrol[port >> 14]; - break; - } - return 0xff; -} - - -static void mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) -{ - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - ram[addr] = val; -} - - -static uint8_t mem_read_laserxtems(uint32_t addr, void *priv) -{ - uint8_t val = 0xFF; - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - val = ram[addr]; - return val; -} - - -static void laserxt_init(void) -{ - int i; - - if(mem_size > 640) - { - io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - mem_mapping_set_addr(&ram_low_mapping, 0, romset == ROM_LTXT ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)); - } - - for (i = 0; i < 4; i++) - { - laserxt_emspage[i] = 0x7F; - laserxt_emscontrol[i] = (i == 3) ? 0x00 : 0x80; - mem_mapping_add(&laserxt_ems_mapping[i], 0xE0000 + (i << 14), 0x4000, mem_read_laserxtems, NULL, NULL, mem_write_laserxtems, NULL, NULL, ram + 0xA0000 + (i << 14), 0, NULL); - mem_mapping_disable(&laserxt_ems_mapping[i]); - } - mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); -} - - -void -machine_xt_laserxt_init(const machine_t *model) -{ - machine_xt_init(model); - - laserxt_init(); -} diff --git a/src - Cópia/machine/m_xt_t1000.c b/src - Cópia/machine/m_xt_t1000.c deleted file mode 100644 index 2b5d33186..000000000 --- a/src - Cópia/machine/m_xt_t1000.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * 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. - * - * Implementation of the Toshiba T1000 and T1200 portables. - * - * The T1000 is the T3100e's little brother -- a real laptop - * with a rechargeable battery. - * - * Features: 80C88 at 4.77MHz - * - 512k system RAM - * - 640x200 monochrome LCD - * - 82-key keyboard - * - Real-time clock. Not the normal 146818, but a TC8521, - * which is a 4-bit chip. - * - A ROM drive (128k, 256k or 512k) which acts as a mini - * hard drive and contains a copy of DOS 2.11. - * - 160 bytes of non-volatile RAM for the CONFIG.SYS used - * when booting from the ROM drive. Possibly physically - * located in the keyboard controller RAM. - * - * An optional memory expansion board can be fitted. This adds - * 768k of RAM, which can be used for up to three purposes: - * > Conventional memory -- 128k between 512k and 640k - * > HardRAM -- a battery-backed RAM drive. - * > EMS - * - * This means that there are up to three different - * implementations of non-volatile RAM in the same computer - * (52 nibbles in the TC8521, 160 bytes of CONFIG.SYS, and - * up to 768k of HardRAM). - * - * The T1200 is a slightly upgraded version with a turbo mode - * (double CPU clock, 9.54MHz) and an optional hard drive. - * The interface for this is proprietary both at the physical - * and programming level. - * - * 01F2h: If hard drive is present, low 4 bits are 0Ch [20Mb] - * or 0Dh [10Mb]. - * - * The hard drive is a 20MB (615/2/26) RLL 3.5" drive. - * - * The TC8521 is a 4-bit RTC, so each memory location can only - * hold a single BCD digit. Hence everything has 'ones' and - * 'tens' digits. - * - * NOTE: Still need to figure out a way to load/save ConfigSys and - * HardRAM stuff. Needs to be linked in to the NVR code. - * - * Version: @(#)m_xt_t1000.c 1.0.6 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2018 Miran Grca. - * Copyright 2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.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 "machine.h" -#include "m_xt_t1000.h" - - -#define T1000_ROMSIZE (512*1024UL) /* Maximum ROM drive size is 512k */ - - -enum TC8521_ADDR { - /* Page 0 registers */ - TC8521_SECOND1 = 0, - TC8521_SECOND10, - TC8521_MINUTE1, - TC8521_MINUTE10, - TC8521_HOUR1, - TC8521_HOUR10, - TC8521_WEEKDAY, - TC8521_DAY1, - TC8521_DAY10, - TC8521_MONTH1, - TC8521_MONTH10, - TC8521_YEAR1, - TC8521_YEAR10, - TC8521_PAGE, /* PAGE register */ - TC8521_TEST, /* TEST register */ - TC8521_RESET, /* RESET register */ - - /* Page 1 registers */ - TC8521_24HR = 0x1A, - TC8521_LEAPYEAR = 0x1B -}; - - -typedef struct { - /* ROM drive */ - uint8_t *romdrive; - uint8_t rom_ctl; - uint32_t rom_offset; - mem_mapping_t rom_mapping; - - /* CONFIG.SYS drive. */ - uint8_t t1000_nvram[160]; - uint8_t t1200_nvram[160]; - - /* System control registers */ - uint8_t sys_ctl[16]; - uint8_t syskeys; - uint8_t turbo; - - /* NVRAM control */ - uint8_t nvr_c0; - uint8_t nvr_tick; - int nvr_addr; - uint8_t nvr_active; - mem_mapping_t nvr_mapping; /* T1200 NVRAM mapping */ - - /* EMS data */ - uint8_t ems_reg[4]; - mem_mapping_t mapping[4]; - uint32_t page_exec[4]; - uint8_t ems_port_index; - uint16_t ems_port; - uint8_t is_640k; - uint32_t ems_base; - int32_t ems_pages; - - fdc_t *fdc; - - nvr_t nvr; -} t1000_t; - - -static t1000_t t1000; - - -#ifdef ENABLE_T1000_LOG -int t1000_do_log = ENABLE_T1000_LOG; -#endif - - -static void -t1000_log(const char *fmt, ...) -{ -#ifdef ENABLE_TANDY_LOG - va_list ap; - - if (t1000_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Set the chip time. */ -static void -tc8521_time_set(uint8_t *regs, struct tm *tm) -{ - regs[TC8521_SECOND1] = (tm->tm_sec % 10); - regs[TC8521_SECOND10] = (tm->tm_sec / 10); - regs[TC8521_MINUTE1] = (tm->tm_min % 10); - regs[TC8521_MINUTE10] = (tm->tm_min / 10); - if (regs[TC8521_24HR] & 0x01) { - regs[TC8521_HOUR1] = (tm->tm_hour % 10); - regs[TC8521_HOUR10] = (tm->tm_hour / 10); - } else { - regs[TC8521_HOUR1] = ((tm->tm_hour % 12) % 10); - regs[TC8521_HOUR10] = (((tm->tm_hour % 12) / 10) | - ((tm->tm_hour >= 12) ? 2 : 0)); - } - regs[TC8521_WEEKDAY] = tm->tm_wday; - regs[TC8521_DAY1] = (tm->tm_mday % 10); - regs[TC8521_DAY10] = (tm->tm_mday / 10); - regs[TC8521_MONTH1] = ((tm->tm_mon + 1) % 10); - regs[TC8521_MONTH10] = ((tm->tm_mon + 1) / 10); - regs[TC8521_YEAR1] = ((tm->tm_year - 80) % 10); - regs[TC8521_YEAR10] = (((tm->tm_year - 80) % 100) / 10); -} - - -/* Get the chip time. */ -#define nibbles(a) (regs[(a##1)] + 10 * regs[(a##10)]) -static void -tc8521_time_get(uint8_t *regs, struct tm *tm) -{ - tm->tm_sec = nibbles(TC8521_SECOND); - tm->tm_min = nibbles(TC8521_MINUTE); - if (regs[TC8521_24HR] & 0x01) - tm->tm_hour = nibbles(TC8521_HOUR); - else - tm->tm_hour = ((nibbles(TC8521_HOUR) % 12) + - (regs[TC8521_HOUR10] & 0x02) ? 12 : 0); -//FIXME: wday - tm->tm_mday = nibbles(TC8521_DAY); - tm->tm_mon = (nibbles(TC8521_MONTH) - 1); - tm->tm_year = (nibbles(TC8521_YEAR) + 1980); -} - - -/* This is called every second through the NVR/RTC hook. */ -static void -tc8521_tick(nvr_t *nvr) -{ - t1000_log("TC8521: ping\n"); -} - - -static void -tc8521_start(nvr_t *nvr) -{ - struct tm tm; - - /* Initialize the internal and chip times. */ - if (enable_sync) { - /* Use the internal clock's time. */ - nvr_time_get(&tm); - tc8521_time_set(nvr->regs, &tm); - } else { - /* Set the internal clock from the chip time. */ - tc8521_time_get(nvr->regs, &tm); - nvr_time_set(&tm); - } - -#if 0 - /* Start the RTC - BIOS will do this. */ - nvr->regs[TC8521_PAGE] |= 0x80; -#endif -} - - -/* Write to one of the chip registers. */ -static void -tc8521_write(uint16_t addr, uint8_t val, void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - uint8_t page; - - /* Get to the correct register page. */ - addr &= 0x0f; - page = nvr->regs[0x0d] & 0x03; - if (addr < 0x0d) - addr += (16 * page); - - if (addr >= 0x10 && nvr->regs[addr] != val) - nvr_dosave = 1; - - /* Store the new value. */ - nvr->regs[addr] = val; -} - - -/* Read from one of the chip registers. */ -static uint8_t -tc8521_read(uint16_t addr, void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - uint8_t page; - - /* Get to the correct register page. */ - addr &= 0x0f; - page = nvr->regs[0x0d] & 0x03; - if (addr < 0x0d) - addr += (16 * page); - - /* Grab and return the desired value. */ - return(nvr->regs[addr]); -} - - -/* Reset the 8521 to a default state. */ -static void -tc8521_reset(nvr_t *nvr) -{ - /* Clear the NVRAM. */ - memset(nvr->regs, 0xff, nvr->size); - - /* Reset the RTC registers. */ - memset(nvr->regs, 0x00, 16); - nvr->regs[TC8521_WEEKDAY] = 0x01; - nvr->regs[TC8521_DAY1] = 0x01; - nvr->regs[TC8521_MONTH1] = 0x01; -} - - -static void -tc8521_init(nvr_t *nvr, int size) -{ - /* This is machine specific. */ - nvr->size = size; - nvr->irq = -1; - - /* Set up any local handlers here. */ - nvr->reset = tc8521_reset; - nvr->start = tc8521_start; - nvr->tick = tc8521_tick; - - /* Initialize the actual NVR. */ - nvr_init(nvr); - - io_sethandler(0x02c0, 16, - tc8521_read,NULL,NULL, tc8521_write,NULL,NULL, nvr); -} - - -/* Given an EMS page ID, return its physical address in RAM. */ -static uint32_t -ems_execaddr(t1000_t *sys, int pg, uint16_t val) -{ - if (!(val & 0x80)) return(0); /* Bit 7 reset => not mapped */ - if (!sys->ems_pages) return(0); /* No EMS available: all used by - * HardRAM or conventional RAM */ - val &= 0x7f; - -#if 0 - t1000_log("Select EMS page: %d of %d\n", val, sys->ems_pages); -#endif - if (val < sys->ems_pages) { - /* EMS is any memory above 512k, - with ems_base giving the start address */ - return((512 * 1024) + (sys->ems_base * 0x10000) + (0x4000 * val)); - } - - return(0); -} - - -static uint8_t -ems_in(uint16_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - -#if 0 - t1000_log("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); -#endif - return(sys->ems_reg[(addr >> 14) & 3]); -} - - -static void -ems_out(uint16_t addr, uint8_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = (addr >> 14) & 3; - -#if 0 - t1000_log("ems_out(%04x, %02x) pg=%d\n", addr, val, pg); -#endif - sys->ems_reg[pg] = val; - sys->page_exec[pg] = ems_execaddr(sys, pg, val); - if (sys->page_exec[pg]) { - /* Page present */ - mem_mapping_enable(&sys->mapping[pg]); - mem_mapping_set_exec(&sys->mapping[pg], ram + sys->page_exec[pg]); - } else { - mem_mapping_disable(&sys->mapping[pg]); - } -} - - -/* Hardram size is in 64k units */ -static void -ems_set_hardram(t1000_t *sys, uint8_t val) -{ - int n; - - val &= 0x1f; /* Mask off pageframe address */ - if (val && mem_size > 512) - sys->ems_base = val; - else - sys->ems_base = 0; - -#if 0 - t1000_log("EMS base set to %02x\n", val); -#endif - sys->ems_pages = 48 - 4 * sys->ems_base; - if (sys->ems_pages < 0) sys->ems_pages = 0; - - /* Recalculate EMS mappings */ - for (n = 0; n < 4; n++) - ems_out(n << 14, sys->ems_reg[n], sys); -} - - -static void -ems_set_640k(t1000_t *sys, uint8_t val) -{ - if (val && mem_size >= 640) { - mem_mapping_set_addr(&ram_low_mapping, 0, 640 * 1024); - sys->is_640k = 1; - } else { - mem_mapping_set_addr(&ram_low_mapping, 0, 512 * 1024); - sys->is_640k = 0; - } -} - - -static void -ems_set_port(t1000_t *sys, uint8_t val) -{ - int n; - -#if 0 - t1000_log("ems_set_port(%d)", val & 0x0f); -#endif - if (sys->ems_port) { - for (n = 0; n <= 0xc000; n += 0x4000) { - io_removehandler(sys->ems_port+n, 1, - ems_in,NULL,NULL, ems_out,NULL,NULL, sys); - } - sys->ems_port = 0; - } - - val &= 0x0f; - sys->ems_port_index = val; - if (val == 7) { - /* No EMS */ - sys->ems_port = 0; - } else { - sys->ems_port = 0x208 | (val << 4); - for (n = 0; n <= 0xc000; n += 0x4000) { - io_sethandler(sys->ems_port+n, 1, - ems_in,NULL,NULL, ems_out,NULL,NULL, sys); - } - sys->ems_port = 0; - } - -#if 0 - t1000_log(" -> %04x\n", sys->ems_port); -#endif -} - - -static int -addr_to_page(uint32_t addr) -{ - return((addr - 0xd0000) / 0x4000); -} - - -/* Read RAM in the EMS page frame. */ -static uint8_t -ems_read_ram(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return(0xff); - addr = sys->page_exec[pg] + (addr & 0x3fff); - - return(ram[addr]); -} - - -static uint16_t -ems_read_ramw(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return(0xff); - -#if 0 - t1000_log("ems_read_ramw addr=%05x ", addr); -#endif - addr = sys->page_exec[pg] + (addr & 0x3FFF); - -#if 0 - t1000_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); -#endif - - return(*(uint16_t *)&ram[addr]); -} - - -static uint32_t -ems_read_raml(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return(0xff); - addr = sys->page_exec[pg] + (addr & 0x3fff); - - return(*(uint32_t *)&ram[addr]); -} - - -/* Write RAM in the EMS page frame. */ -static void -ems_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - - addr = sys->page_exec[pg] + (addr & 0x3fff); - if (ram[addr] != val) nvr_dosave = 1; - - ram[addr] = val; -} - - -static void -ems_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - -#if 0 - t1000_log("ems_write_ramw addr=%05x ", addr); -#endif - addr = sys->page_exec[pg] + (addr & 0x3fff); - -#if 0 - t1000_log("-> %06x val=%04x\n", addr, val); -#endif - - if (*(uint16_t *)&ram[addr] != val) nvr_dosave = 1; - - *(uint16_t *)&ram[addr] = val; -} - - -static void -ems_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - int pg = addr_to_page(addr); - - if (pg < 0) return; - - addr = sys->page_exec[pg] + (addr & 0x3fff); - if (*(uint32_t *)&ram[addr] != val) nvr_dosave = 1; - - *(uint32_t *)&ram[addr] = val; -} - - -static uint8_t -read_ctl(uint16_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - uint8_t ret = 0xff; - - switch (addr & 0x0f) { - case 1: - ret = sys->syskeys; - break; - - case 0x0f: /* Detect EMS board */ - switch (sys->sys_ctl[0x0e]) { - case 0x50: - if (mem_size > 512) break; - ret = (0x90 | sys->ems_port_index); - break; - - case 0x51: - /* 0x60 is the page frame address: - (0xd000 - 0xc400) / 0x20 */ - ret = (sys->ems_base | 0x60); - break; - - case 0x52: - ret = (sys->is_640k ? 0x80 : 0); - break; - } - break; - - default: - ret = (sys->sys_ctl[addr & 0x0f]); - } - - return(ret); -} - - -static void -t1200_turbo_set(uint8_t value) -{ - if (value == t1000.turbo) return; - - t1000.turbo = value; - if (! value) - cpu_dynamic_switch(0); - else - cpu_dynamic_switch(cpu); -} - - -static void -write_ctl(uint16_t addr, uint8_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - sys->sys_ctl[addr & 0x0f] = val; - switch (addr & 0x0f) { - case 4: /* Video control */ - if (sys->sys_ctl[3] == 0x5A) { - t1000_video_options_set((val & 0x20) ? 1 : 0); - t1000_display_set((val & 0x40) ? 0 : 1); - if (romset == ROM_T1200) - t1200_turbo_set((val & 0x80) ? 1 : 0); - } - break; - - case 0x0f: /* EMS control */ - switch (sys->sys_ctl[0x0e]) { - case 0x50: - ems_set_port(sys, val); - break; - - case 0x51: - ems_set_hardram(sys, val); - break; - - case 0x52: - ems_set_640k(sys, val); - break; - } - break; - } -} - - -/* Ports 0xC0 to 0xC3 appear to have two purposes: - * - * > Access to the 160 bytes of non-volatile RAM containing CONFIG.SYS - * > Reading the floppy changeline. I don't know why the Toshiba doesn't - * use the normal port 0x3F7 for this, but it doesn't. - * - */ -static uint8_t -t1000_read_nvram(uint16_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - uint8_t tmp = 0xff; - - switch (addr) { - case 0xc2: /* Read next byte from NVRAM */ - if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) - tmp = sys->t1000_nvram[sys->nvr_addr]; - sys->nvr_addr++; - break; - - case 0xc3: /* Read floppy changeline and NVRAM ready state */ - tmp = fdc_read(0x03f7, t1000.fdc); - - tmp = (tmp & 0x80) >> 3; /* Bit 4 is changeline */ - tmp |= (sys->nvr_active & 0xc0);/* Bits 6,7 are r/w mode */ - tmp |= 0x2e; /* Bits 5,3,2,1 always 1 */ - tmp |= (sys->nvr_active & 0x40) >> 6; /* Ready state */ - break; - } - - return(tmp); -} - - -static void -t1000_write_nvram(uint16_t addr, uint8_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - /* - * On the real T1000, port 0xC1 is only usable as the high byte - * of a 16-bit write to port 0xC0, with 0x5A in the low byte. - */ - switch (addr) { - case 0xc0: - sys->nvr_c0 = val; - break; - - case 0xc1: /* Write next byte to NVRAM */ - if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { - if (sys->t1000_nvram[sys->nvr_addr] != val) - nvr_dosave = 1; - sys->t1000_nvram[sys->nvr_addr] = val; - } - sys->nvr_addr++; - break; - - case 0xc2: - break; - - case 0xc3: - /* - * At start of NVRAM read / write, 0x80 is written to - * port 0xC3. This seems to reset the NVRAM address - * counter. A single byte is then written (0xff for - * write, 0x00 for read) which appears to be ignored. - * Simulate that by starting the address counter off - * at -1. - */ - sys->nvr_active = val; - if (val == 0x80) sys->nvr_addr = -1; - break; - } -} - - -static -uint8_t read_t1200_nvram(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - return sys->t1200_nvram[addr & 0x7FF]; -} - - -static void write_t1200_nvram(uint32_t addr, uint8_t value, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - if (sys->t1200_nvram[addr & 0x7FF] != value) - nvr_dosave = 1; - - sys->t1200_nvram[addr & 0x7FF] = value; -} - - -/* Port 0xC8 controls the ROM drive */ -static uint8_t -t1000_read_rom_ctl(uint16_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - return(sys->rom_ctl); -} - - -static void -t1000_write_rom_ctl(uint16_t addr, uint8_t val, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - sys->rom_ctl = val; - if (sys->romdrive && (val & 0x80)) { - /* Enable */ - sys->rom_offset = ((val & 0x7f) * 0x10000) % T1000_ROMSIZE; - mem_mapping_set_addr(&sys->rom_mapping, 0xa0000, 0x10000); - mem_mapping_set_exec(&sys->rom_mapping, sys->romdrive + sys->rom_offset); - mem_mapping_enable(&sys->rom_mapping); - } else { - mem_mapping_disable(&sys->rom_mapping); - } -} - - -/* Read the ROM drive */ -static uint8_t -t1000_read_rom(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - if (! sys->romdrive) return(0xff); - - return(sys->romdrive[sys->rom_offset + (addr & 0xffff)]); -} - - -static uint16_t -t1000_read_romw(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - if (! sys->romdrive) return(0xffff); - - return(*(uint16_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xffff)])); -} - - -static uint32_t -t1000_read_roml(uint32_t addr, void *priv) -{ - t1000_t *sys = (t1000_t *)priv; - - if (! sys->romdrive) return(0xffffffff); - - return(*(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xffff)])); -} - - -const device_t * -t1000_get_device(void) -{ - return(&t1000_video_device); -} - - -void -machine_xt_t1000_init(const machine_t *model) -{ - FILE *f; - int pg; - - memset(&t1000, 0x00, sizeof(t1000)); - t1000.turbo = 0xff; - t1000.ems_port_index = 7; /* EMS disabled */ - - /* Load the T1000 CGA Font ROM. */ - loadfont(L"roms/machines/t1000/t1000font.rom", 2); - - /* - * The ROM drive is optional. - * - * If the file is missing, continue to boot; the BIOS will - * complain 'No ROM drive' but boot normally from floppy. - */ - f = rom_fopen(L"roms/machines/t1000/t1000dos.rom", L"rb"); - if (f != NULL) { - t1000.romdrive = malloc(T1000_ROMSIZE); - if (t1000.romdrive) { - memset(t1000.romdrive, 0xff, T1000_ROMSIZE); - fread(t1000.romdrive, T1000_ROMSIZE, 1, f); - } - fclose(f); - } - mem_mapping_add(&t1000.rom_mapping, 0xa0000, 0x10000, - t1000_read_rom,t1000_read_romw,t1000_read_roml, - NULL,NULL,NULL, NULL, MEM_MAPPING_INTERNAL, &t1000); - mem_mapping_disable(&t1000.rom_mapping); - - /* Map the EMS page frame */ - for (pg = 0; pg < 4; pg++) { - mem_mapping_add(&t1000.mapping[pg], 0xd0000 + (0x4000 * pg), 16384, - ems_read_ram,ems_read_ramw,ems_read_raml, - ems_write_ram,ems_write_ramw,ems_write_raml, - NULL, MEM_MAPPING_EXTERNAL, &t1000); - - /* Start them all off disabled */ - mem_mapping_disable(&t1000.mapping[pg]); - } - - /* Non-volatile RAM for CONFIG.SYS */ - io_sethandler(0xc0, 4, - t1000_read_nvram,NULL,NULL, - t1000_write_nvram,NULL,NULL, &t1000); - - /* ROM drive */ - io_sethandler(0xc8, 1, - t1000_read_rom_ctl,NULL,NULL, - t1000_write_rom_ctl,NULL,NULL, &t1000); - - /* System control functions, and add-on memory board */ - io_sethandler(0xe0, 16, - read_ctl,NULL,NULL, write_ctl,NULL,NULL, &t1000); - - machine_common_init(model); - - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); - t1000.fdc = device_add(&fdc_xt_device); - nmi_init(); - - tc8521_init(&t1000.nvr, model->nvrmask + 1); - - device_add(&t1000_video_device); -} - - -const device_t * -t1200_get_device(void) -{ - return(&t1200_video_device); -} - - -void -machine_xt_t1200_init(const machine_t *model) -{ - int pg; - - memset(&t1000, 0x00, sizeof(t1000)); - t1000.ems_port_index = 7; /* EMS disabled */ - - /* Load the T1200 CGA Font ROM. */ - loadfont(L"roms/machines/t1200/t1000font.bin", 2); - - /* Map the EMS page frame */ - for (pg = 0; pg < 4; pg++) { - mem_mapping_add(&t1000.mapping[pg], - 0xd0000 + (0x4000 * pg), 16384, - ems_read_ram,ems_read_ramw,ems_read_raml, - ems_write_ram,ems_write_ramw,ems_write_raml, - NULL, MEM_MAPPING_EXTERNAL, &t1000); - - /* Start them all off disabled */ - mem_mapping_disable(&t1000.mapping[pg]); - } - - /* System control functions, and add-on memory board */ - io_sethandler(0xe0, 16, - read_ctl,NULL,NULL, write_ctl,NULL,NULL, &t1000); - - machine_common_init(model); - - mem_mapping_add(&t1000.nvr_mapping, - 0x000f0000, 2048, - read_t1200_nvram, NULL, NULL, - write_t1200_nvram, NULL, NULL, - NULL, 0, &t1000); - - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); - t1000.fdc = device_add(&fdc_xt_device); - nmi_init(); - - tc8521_init(&t1000.nvr, model->nvrmask + 1); - - device_add(&t1200_video_device); -} - - -void -t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) -{ - t1000.syskeys &= ~andmask; - t1000.syskeys |= ormask; - t1000.syskeys ^= xormask; -} - - -static void -t1000_configsys_load(void) -{ - FILE *f; - - memset(t1000.t1000_nvram, 0x1a, sizeof(t1000.t1000_nvram)); - f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"rb"); - if (f != NULL) { - fread(t1000.t1000_nvram, sizeof(t1000.t1000_nvram), 1, f); - fclose(f); - } -} - - -static void -t1000_configsys_save(void) -{ - FILE *f; - - f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"wb"); - if (f != NULL) { - fwrite(t1000.t1000_nvram, sizeof(t1000.t1000_nvram), 1, f); - fclose(f); - } -} - - -static void -t1200_state_load(void) -{ - FILE *f; - - memset(t1000.t1200_nvram, 0x1a, sizeof(t1000.t1200_nvram)); - f = plat_fopen(nvr_path(L"t1200_state.nvr"), L"rb"); - if (f != NULL) { - fread(t1000.t1200_nvram, sizeof(t1000.t1200_nvram), 1, f); - fclose(f); - } -} - - -static void -t1200_state_save(void) -{ - FILE *f; - - f = plat_fopen(nvr_path(L"t1200_state.nvr"), L"wb"); - if (f != NULL) { - fwrite(t1000.t1200_nvram, sizeof(t1000.t1200_nvram), 1, f); - fclose(f); - } -} - - -/* All RAM beyond 512k is non-volatile */ -static void -t1000_emsboard_load(void) -{ - FILE *f; - - if (mem_size > 512) { - f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"rb"); - if (f != NULL) { - fread(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); - } - } -} - - -static void -t1000_emsboard_save(void) -{ - FILE *f; - - if (mem_size > 512) { - f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"wb"); - if (f != NULL) { - fwrite(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); - } - } -} - - -void -t1000_nvr_load(void) -{ - t1000_emsboard_load(); - t1000_configsys_load(); -} - - -void -t1000_nvr_save(void) -{ - t1000_emsboard_save(); - t1000_configsys_save(); -} - - -void -t1200_nvr_load(void) -{ - t1000_emsboard_load(); - t1200_state_load(); -} - - -void -t1200_nvr_save(void) -{ - t1000_emsboard_save(); - t1200_state_save(); -} diff --git a/src - Cópia/machine/m_xt_t1000.h b/src - Cópia/machine/m_xt_t1000.h deleted file mode 100644 index 3a345fcbc..000000000 --- a/src - Cópia/machine/m_xt_t1000.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 Toshiba T1000/T1200 machines. - * - * Version: @(#)m_xt_t1000.h 1.0.4 2018/03/19 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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 MACHINE_T1000_H -# define MACHINE_T1000_H - - -extern const device_t t1000_video_device; -extern const device_t t1200_video_device; - - -extern void t1000_video_options_set(uint8_t options); -extern void t1000_display_set(uint8_t internal); - -extern void t1000_syskey(uint8_t amask, uint8_t omask, uint8_t xmask); - -extern void t1000_nvr_load(void); -extern void t1000_nvr_save(void); - -extern void t1200_nvr_load(void); -extern void t1200_nvr_save(void); - - -#endif /*MACHINE_T1000_H*/ diff --git a/src - Cópia/machine/m_xt_t1000_vid.c b/src - Cópia/machine/m_xt_t1000_vid.c deleted file mode 100644 index 01b184fde..000000000 --- a/src - Cópia/machine/m_xt_t1000_vid.c +++ /dev/null @@ -1,749 +0,0 @@ -/* - * 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. - * - * Implementation of the Toshiba T1000 plasma display, which - * has a fixed resolution of 640x200 pixels. - * - * Version: @(#)m_xt_t1000_vid.c 1.0.7 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2018 Miran Grca. - * Copyright 2018 Sarah Walker. - * - * 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. - */ -#include -#include -#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 "m_xt_t1000.h" - - -#define T1000_XSIZE 640 -#define T1000_YSIZE 200 - - -/* Mapping of attributes to colours */ -static uint32_t blue, grey; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ -static uint32_t blinkcols[256][2]; -static uint32_t normcols[256][2]; -static uint8_t language; - - -/* Video options set by the motherboard; they will be picked up by the card - * on the next poll. - * - * Bit 1: Danish - * Bit 0: Thin font - */ -static uint8_t st_video_options; -static int8_t st_display_internal = -1; - -void t1000_video_options_set(uint8_t options) -{ - st_video_options = options & 1; - st_video_options |= language; -} - -void t1000_display_set(uint8_t internal) -{ - st_display_internal = (int8_t)internal; -} - -uint8_t t1000_display_get() -{ - return (uint8_t)st_display_internal; -} - - -typedef struct t1000_t -{ - mem_mapping_t mapping; - - cga_t cga; /* The CGA is used for the external - * display; most of its registers are - * ignored by the plasma display. */ - - int font; /* Current font, 0-3 */ - int enabled; /* Hardware enabled, 0 or 1 */ - int internal; /* Using internal display? */ - uint8_t attrmap; /* Attribute mapping register */ - - int dispontime, dispofftime; - - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; - - uint8_t *vram; -} t1000_t; - - -static void t1000_recalctimings(t1000_t *t1000); -static void t1000_write(uint32_t addr, uint8_t val, void *p); -static uint8_t t1000_read(uint32_t addr, void *p); -static void t1000_recalcattrs(t1000_t *t1000); - - -static void t1000_out(uint16_t addr, uint8_t val, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - switch (addr) - { - /* Emulated CRTC, register select */ - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - cga_out(addr, val, &t1000->cga); - break; - - /* Emulated CRTC, value */ - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - /* Register 0x12 controls the attribute mappings for the - * LCD screen. */ - if (t1000->cga.crtcreg == 0x12) - { - t1000->attrmap = val; - t1000_recalcattrs(t1000); - return; - } - cga_out(addr, val, &t1000->cga); - - t1000_recalctimings(t1000); - return; - - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t1000->cga); - return; - /* CGA colour register */ - case 0x3D9: - cga_out(addr, val, &t1000->cga); - return; - } -} - -static uint8_t t1000_in(uint16_t addr, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - uint8_t val; - - switch (addr) - { - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - if (t1000->cga.crtcreg == 0x12) - { - val = t1000->attrmap & 0x0F; - if (t1000->internal) val |= 0x20; /* LCD / CRT */ - return val; - } - } - - return cga_in(addr, &t1000->cga); -} - - - - -static void t1000_write(uint32_t addr, uint8_t val, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - egawrites++; - - t1000->vram[addr & 0x3fff] = val; - cycles -= 4; -} - -static uint8_t t1000_read(uint32_t addr, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - egareads++; - cycles -= 4; - - return t1000->vram[addr & 0x3fff]; -} - - - -static void t1000_recalctimings(t1000_t *t1000) -{ - double disptime; - double _dispontime, _dispofftime; - - if (!t1000->internal) - { - cga_recalctimings(&t1000->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - -/* Draw a row of text in 80-column mode */ -static void t1000_text_row80(t1000_t *t1000) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; - - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2; - ma += (t1000->displine >> 3) * 80; - - if ((t1000->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && - ((t1000->cga.crtc[11] & 0x0F) >= sc); - } - for (x = 0; x < 80; x++) - { - chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; - attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && - (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); - - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t1000->video_options & 1) - bold = boldcols[attr] ? chr : chr + 256; - else - bold = boldcols[attr] ? chr + 256 : chr; - if (t1000->video_options & 2) - bold += 512; - - if (t1000->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); - } - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -static void t1000_text_row40(t1000_t *t1000) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; - - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2; - ma += (t1000->displine >> 3) * 40; - - if ((t1000->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && - ((t1000->cga.crtc[11] & 0x0F) >= sc); - } - for (x = 0; x < 40; x++) - { - chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; - attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && - (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); - - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t1000->video_options & 1) - bold = boldcols[attr] ? chr : chr + 256; - else - bold = boldcols[attr] ? chr + 256 : chr; - if (t1000->video_options & 2) - bold += 512; - - if (t1000->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); - } - } - else - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2+1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - -/* Draw a line in CGA 640x200 mode */ -static void t1000_cgaline6(t1000_t *t1000) -{ - int x, c; - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey; - uint32_t bg = grey; - - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - - addr = ((t1000->displine) & 1) * 0x2000 + - (t1000->displine >> 1) * 80 + - ((ma & ~1) << 1); - - for (x = 0; x < 80; x++) - { - dat = t1000->vram[addr & 0x3FFF]; - addr++; - - for (c = 0; c < 8; c++) - { - ink = (dat & 0x80) ? fg : bg; - if (!(t1000->cga.cgamode & 8)) - ink = grey; - ((uint32_t *)buffer32->line[t1000->displine])[x*8+c] = ink; - dat = dat << 1; - } - } -} - -/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to - * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ -static void t1000_cgaline4(t1000_t *t1000) -{ - int x, c; - uint8_t dat, pattern; - uint32_t ink0, ink1; - uint16_t addr; - - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - addr = ((t1000->displine) & 1) * 0x2000 + - (t1000->displine >> 1) * 80 + - ((ma & ~1) << 1); - - for (x = 0; x < 80; x++) - { - dat = t1000->vram[addr & 0x3FFF]; - addr++; - - for (c = 0; c < 4; c++) - { - pattern = (dat & 0xC0) >> 6; - if (!(t1000->cga.cgamode & 8)) pattern = 0; - - switch (pattern & 3) - { - default: - case 0: ink0 = ink1 = grey; break; - case 1: if (t1000->displine & 1) - { - ink0 = grey; ink1 = grey; - } - else - { - ink0 = blue; ink1 = grey; - } - break; - case 2: if (t1000->displine & 1) - { - ink0 = grey; ink1 = blue; - } - else - { - ink0 = blue; ink1 = grey; - } - break; - case 3: ink0 = ink1 = blue; break; - - } - ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c] = ink0; - ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c+1] = ink1; - dat = dat << 2; - } - } -} - -static void t1000_poll(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - if (t1000->video_options != st_video_options) - { - t1000->video_options = st_video_options; - - /* Set the font used for the external display */ - t1000->cga.fontbase = ((t1000->video_options & 3) * 256); - } - /* Switch between internal plasma and external CRT display. */ - if (st_display_internal != -1 && st_display_internal != t1000->internal) - { - t1000->internal = st_display_internal; - t1000_recalctimings(t1000); - } - if (!t1000->internal) - { - cga_poll(&t1000->cga); - return; - } - - if (!t1000->linepos) - { - t1000->cga.vidtime += t1000->dispofftime; - t1000->cga.cgastat |= 1; - t1000->linepos = 1; - if (t1000->dispon) - { - if (t1000->displine == 0) - { - video_wait_for_buffer(); - } - - /* Graphics */ - if (t1000->cga.cgamode & 0x02) - { - if (t1000->cga.cgamode & 0x10) - t1000_cgaline6(t1000); - else t1000_cgaline4(t1000); - } - else - if (t1000->cga.cgamode & 0x01) /* High-res text */ - { - t1000_text_row80(t1000); - } - else - { - t1000_text_row40(t1000); - } - } - t1000->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (t1000->displine == 200) /* Start of VSYNC */ - { - t1000->cga.cgastat |= 8; - t1000->dispon = 0; - } - if (t1000->displine == 216) /* End of VSYNC */ - { - t1000->displine = 0; - t1000->cga.cgastat &= ~8; - t1000->dispon = 1; - } - } - else - { - if (t1000->dispon) - { - t1000->cga.cgastat &= ~1; - } - t1000->cga.vidtime += t1000->dispontime; - t1000->linepos = 0; - - if (t1000->displine == 200) - { - /* Hardcode 640x200 window size */ - if (T1000_XSIZE != xsize || T1000_YSIZE != ysize) - { - xsize = T1000_XSIZE; - ysize = T1000_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 640x200 resolution */ - video_res_x = T1000_XSIZE; - video_res_y = T1000_YSIZE; - - if (t1000->cga.cgamode & 0x02) - { - if (t1000->cga.cgamode & 0x10) - video_bpp = 1; - else video_bpp = 2; - - } - else video_bpp = 0; - t1000->cga.cgablink++; - } - } -} - -static void t1000_recalcattrs(t1000_t *t1000) -{ - int n; - - /* val behaves as follows: - * Bit 0: Attributes 01-06, 08-0E are inverse video - * Bit 1: Attributes 01-06, 08-0E are bold - * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are inverse video - * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are bold */ - - /* Set up colours */ - blue = makecol(0x2D, 0x39, 0x5A); - grey = makecol(0x85, 0xa0, 0xD6); - - /* Initialise the attribute mapping. Start by defaulting everything - * to grey on blue, and with bold set by bit 3 */ - for (n = 0; n < 256; n++) - { - boldcols[n] = (n & 8) != 0; - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - } - - /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the - * passed value. Exclude x0 and x8, which are always grey on - * blue. */ - for (n = 0x11; n <= 0xFF; n++) - { - if ((n & 7) == 0) continue; - if (t1000->attrmap & 4) /* Inverse */ - { - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - } - else /* Normal */ - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - } - if (t1000->attrmap & 8) boldcols[n] = 1; /* Bold */ - } - /* Set up the 01-0E range, controlled by bits 0 and 1 of the - * passed value. When blinking is enabled this also affects 81-8E. */ - for (n = 0x01; n <= 0x0E; n++) - { - if (n == 7) continue; - if (t1000->attrmap & 1) - { - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - blinkcols[n+128][0] = blue; - blinkcols[n+128][1] = grey; - } - else - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - blinkcols[n+128][0] = grey; - blinkcols[n+128][1] = blue; - } - if (t1000->attrmap & 2) boldcols[n] = 1; - } - /* Colours 07 and 0F are always blue on grey. If blinking is - * enabled so are 87 and 8F. */ - for (n = 0x07; n <= 0x0F; n += 8) - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - blinkcols[n+128][0] = grey; - blinkcols[n+128][1] = blue; - } - /* When not blinking, colours 81-8F are always blue on grey. */ - for (n = 0x81; n <= 0x8F; n ++) - { - normcols[n][0] = grey; - normcols[n][1] = blue; - boldcols[n] = (n & 0x08) != 0; - } - - - /* Finally do the ones which are solid grey. These differ between - * the normal and blinking mappings */ - for (n = 0; n <= 0xFF; n += 0x11) - { - normcols[n][0] = normcols[n][1] = grey; - } - /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are grey */ - for (n = 0; n <= 0x77; n += 0x11) - { - blinkcols[n][0] = blinkcols[n][1] = grey; - blinkcols[n+128][0] = blinkcols[n+128][1] = grey; - } -} - - -static void *t1000_init(const device_t *info) -{ - t1000_t *t1000 = malloc(sizeof(t1000_t)); - memset(t1000, 0, sizeof(t1000_t)); - cga_init(&t1000->cga); - - t1000->internal = 1; - - /* 16k video RAM */ - t1000->vram = malloc(0x4000); - - timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000); - - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, t1000_in, NULL, NULL, t1000_out, NULL, NULL, t1000); - - /* Default attribute mapping is 4 */ - t1000->attrmap = 4; - t1000_recalcattrs(t1000); - - /* Start off in 80x25 text mode */ - t1000->cga.cgastat = 0xF4; - t1000->cga.vram = t1000->vram; - t1000->enabled = 1; - t1000->video_options = 0x01; - language = device_get_config_int("display_language") ? 2 : 0; - return t1000; -} - -static void t1000_close(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - free(t1000->vram); - free(t1000); -} - -static void t1000_speed_changed(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - t1000_recalctimings(t1000); -} - -static const device_config_t t1000_config[] = -{ - { - .name = "display_language", - .description = "Language", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "USA", - .value = 0 - }, - { - .description = "Danish", - .value = 1 - } - }, - .default_int = 0 - }, - { - .type = -1 - } -}; - - -const device_t t1000_video_device = { - "Toshiba T1000 Video", - 0, 0, - t1000_init, t1000_close, NULL, - NULL, - t1000_speed_changed, - NULL, - t1000_config -}; - - -const device_t t1200_video_device = { - "Toshiba T1200 Video", - 0, 0, - t1000_init, t1000_close, NULL, - NULL, - t1000_speed_changed, - NULL, - t1000_config -}; diff --git a/src - Cópia/machine/m_xt_xi8088.c b/src - Cópia/machine/m_xt_xi8088.c deleted file mode 100644 index 13d1c20b8..000000000 --- a/src - Cópia/machine/m_xt_xi8088.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include -#include -#include -#include "../86box.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 "../disk/hdc.h" -#include "machine.h" -#include "../cpu/cpu.h" - -#include "m_xt_xi8088.h" - -typedef struct xi8088_t -{ - uint8_t turbo; - - int turbo_setting; - int bios_128kb; -} xi8088_t; - -static xi8088_t xi8088; - -uint8_t xi8088_turbo_get() -{ - return xi8088.turbo; -} - -void xi8088_turbo_set(uint8_t value) -{ - if (!xi8088.turbo_setting) - return; - - xi8088.turbo = value; - if (!value) - { - pclog("Xi8088 turbo off\n"); - int c = cpu; - cpu = 0; /* 8088/4.77 */ - cpu_set(); - cpu = c; - } - else - { - pclog("Xi8088 turbo on\n"); - cpu_set(); - } -} - -void xi8088_bios_128kb_set(int val) -{ - xi8088.bios_128kb = val; -} - -int xi8088_bios_128kb() -{ - return xi8088.bios_128kb; -} - -static void *xi8088_init() -{ - /* even though the bios by default turns the turbo off when controlling by hotkeys, pcem always starts at full speed */ - xi8088.turbo = 1; - xi8088.turbo_setting = device_get_config_int("turbo_setting"); - - return &xi8088; -} - -static const device_config_t xi8088_config[] = -{ - { - .name = "turbo_setting", - .description = "Turbo", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Always at selected speed", - .value = 0 - }, - { - .description = "Hotkeys (starts off)", - .value = 1 - } - }, - .default_int = 0 - }, - { - .type = -1 - } -}; - - -const device_t xi8088_device = -{ - "Xi8088", - 0, - 0, - xi8088_init, - NULL, - NULL, - NULL, - NULL, - NULL, - xi8088_config -}; - -const device_t * -xi8088_get_device(void) -{ - return &xi8088_device; -} - -void machine_xt_xi8088_init(const machine_t *model) -{ - /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ - machine_common_init(model); - device_add(&fdc_xt_device); - device_add(&keyboard_ps2_device); - nmi_init(); - device_add(&at_nvr_device); - pic2_init(); - if (joystick_type != 7) - device_add(&gameport_device); -} diff --git a/src - Cópia/machine/m_xt_xi8088.h b/src - Cópia/machine/m_xt_xi8088.h deleted file mode 100644 index 0270ed16d..000000000 --- a/src - Cópia/machine/m_xt_xi8088.h +++ /dev/null @@ -1,8 +0,0 @@ -#include "../device.h" - -extern const device_t xi8088_device; - -uint8_t xi8088_turbo_get(); -void xi8088_turbo_set(uint8_t value); -void xi8088_bios_128kb_set(int val); -int xi8088_bios_128kb(); diff --git a/src - Cópia/machine/machine.c b/src - Cópia/machine/machine.c deleted file mode 100644 index ddfc5d119..000000000 --- a/src - Cópia/machine/machine.c +++ /dev/null @@ -1,109 +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. - * - * Version: @(#)machine.c 1.0.34 2018/04/29 - * - * 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. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.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 "machine.h" - - -int machine; -int AT, PCI; -int romset; - - -#ifdef ENABLE_MACHINE_LOG -int machine_do_log = ENABLE_MACHINE_LOG; -#endif - - -static void -machine_log(const char *fmt, ...) -{ -#ifdef ENABLE_TANDY_LOG - va_list ap; - - if (machine_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void -machine_init(void) -{ - machine_log("Initializing as \"%s\"\n", machine_getname()); - - /* Set up the architecture flags. */ - AT = IS_ARCH(machine, MACHINE_AT); - PCI = IS_ARCH(machine, MACHINE_PCI); - - /* Resize the memory. */ - mem_reset(); - - /* Load the machine's ROM BIOS. */ - rom_load_bios(romset); - mem_add_bios(); - - /* All good, boot the machine! */ - machines[machine].init(&machines[machine]); -} - - -void -machine_common_init(const machine_t *model) -{ - /* System devices first. */ - pic_init(); - dma_init(); - pit_init(); - - cpu_set(); - if (AT) - setrtcconst(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setrtcconst(14318184.0); - - if (lpt_enabled) - lpt_init(); - - if (serial_enabled[0]) - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - - if (serial_enabled[1]) - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); -} diff --git a/src - Cópia/machine/machine.h b/src - Cópia/machine/machine.h deleted file mode 100644 index 89228c5eb..000000000 --- a/src - Cópia/machine/machine.h +++ /dev/null @@ -1,217 +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. - * - * Version: @(#)machine.h 1.0.24 2018/05/10 - * - * 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. - */ -#ifndef EMU_MACHINE_H -# define EMU_MACHINE_H - - -/* Machine feature flags. */ -#define MACHINE_PC 0x000000 /* PC architecture */ -#define MACHINE_AT 0x000001 /* PC/AT architecture */ -#define MACHINE_PS2 0x000002 /* PS/2 architecture */ -#define MACHINE_ISA 0x000010 /* sys has ISA bus */ -#define MACHINE_CBUS 0x000020 /* sys has C-BUS bus */ -#define MACHINE_EISA 0x000040 /* sys has EISA bus */ -#define MACHINE_VLB 0x000080 /* sys has VL bus */ -#define MACHINE_MCA 0x000100 /* sys has MCA bus */ -#define MACHINE_PCI 0x000200 /* sys has PCI bus */ -#define MACHINE_AGP 0x000400 /* sys has AGP bus */ -#define MACHINE_HDC 0x001000 /* sys has int HDC */ -#define MACHINE_HDC_PS2 0x002000 /* sys has int PS/2 HDC */ -#define MACHINE_MOUSE 0x004000 /* sys has int mouse */ -#define MACHINE_VIDEO 0x008000 /* sys has int video */ - -#define IS_ARCH(m, a) (machines[(m)].flags & (a)) ? 1 : 0; - - -typedef struct _machine_ { - const char *name; - int id; - const char *internal_name; - struct { - const char *name; -#ifdef EMU_CPU_H - CPU *cpus; -#else - void *cpus; -#endif - } cpu[5]; - int fixed_gfxcard; - int flags; - uint32_t min_ram, max_ram; - int ram_granularity; - int nvrmask; - void (*init)(const struct _machine_ *); -#ifdef EMU_DEVICE_H - const device_t *(*get_device)(void); -#else - void *get_device; -#endif -} machine_t; - - -/* Global variables. */ -extern const machine_t machines[]; -extern int machine; -extern int romset; -extern int AT, PCI; - - -/* Core functions. */ -extern int machine_count(void); -extern int machine_getromset(void); -extern int machine_getmachine(int romset); -extern char *machine_getname(void); -extern char *machine_get_internal_name(void); -extern int machine_get_machine_from_internal_name(char *s); -extern void machine_init(void); -#ifdef EMU_DEVICE_H -extern const device_t *machine_getdevice(int machine); -#endif -extern int machine_getromset_ex(int m); -extern char *machine_get_internal_name_ex(int m); -extern int machine_get_nvrmask(int m); -extern void machine_close(void); - - -/* Initialization functions for boards and systems. */ -extern void machine_common_init(const machine_t *); - -extern void machine_at_common_init(const machine_t *); -extern void machine_at_init(const machine_t *); -extern void machine_at_ps2_init(const machine_t *); -extern void machine_at_common_ide_init(const machine_t *); -extern void machine_at_ide_init(const machine_t *); -extern void machine_at_ps2_ide_init(const machine_t *); -extern void machine_at_top_remap_init(const machine_t *); -extern void machine_at_ide_top_remap_init(const machine_t *); - -extern void machine_at_ibm_init(const machine_t *); - -extern void machine_at_t3100e_init(const machine_t *); - -extern void machine_at_p54tp4xe_init(const machine_t *); -extern void machine_at_endeavor_init(const machine_t *); -extern void machine_at_zappa_init(const machine_t *); -extern void machine_at_mb500n_init(const machine_t *); -extern void machine_at_president_init(const machine_t *); -extern void machine_at_thor_init(const machine_t *); -extern void machine_at_pb640_init(const machine_t *); - -extern void machine_at_acerm3a_init(const machine_t *); -extern void machine_at_acerv35n_init(const machine_t *); -extern void machine_at_ap53_init(const machine_t *); -extern void machine_at_p55t2p4_init(const machine_t *); -extern void machine_at_p55t2s_init(const machine_t *); - -extern void machine_at_batman_init(const machine_t *); -extern void machine_at_plato_init(const machine_t *); - -extern void machine_at_p55tvp4_init(const machine_t *); -extern void machine_at_i430vx_init(const machine_t *); -extern void machine_at_p55va_init(const machine_t *); - -#if defined(DEV_BRANCH) && defined(USE_I686) -extern void machine_at_i440fx_init(const machine_t *); -extern void machine_at_s1668_init(const machine_t *); -#endif -extern void machine_at_ali1429_init(const machine_t *); -extern void machine_at_cmdpc_init(const machine_t *); - -extern void machine_at_headland_init(const machine_t *); -extern void machine_at_neat_init(const machine_t *); -extern void machine_at_neat_ami_init(const machine_t *); -extern void machine_at_opti495_init(const machine_t *); -extern void machine_at_opti495_ami_init(const machine_t *); -extern void machine_at_scat_init(const machine_t *); -extern void machine_at_scatsx_init(const machine_t *); -extern void machine_at_compaq_init(const machine_t *); - -extern void machine_at_dtk486_init(const machine_t *); -extern void machine_at_r418_init(const machine_t *); - -extern void machine_at_wd76c10_init(const machine_t *); - -#if defined(DEV_BRANCH) && defined(USE_GREENB) -extern void machine_at_4gpv31_init(const machine_t *); -#endif - -extern void machine_pcjr_init(const machine_t *); - -extern void machine_ps1_m2011_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern void ps1_hdc_inform(void *, void *); -extern void ps1_set_feedback(void *); -extern const device_t ps1_hdc_device; -#endif - -extern void machine_ps1_m2121_init(const machine_t *); -extern void machine_ps1_m2133_init(const machine_t *); - -extern void machine_ps2_m30_286_init(const machine_t *); -extern void machine_ps2_model_50_init(const machine_t *); -extern void machine_ps2_model_55sx_init(const machine_t *); -extern void machine_ps2_model_70_type3_init(const machine_t *); -extern void machine_ps2_model_70_type4_init(const machine_t *); -extern void machine_ps2_model_80_init(const machine_t *); -#ifdef WALTJE -extern void machine_ps2_model_80_486_init(const machine_t *); -#endif - -extern void machine_amstrad_init(const machine_t *); - -extern void machine_europc_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t europc_device; -#endif - -extern void machine_olim24_init(const machine_t *); -extern void machine_olim24_video_init(void); - -extern void machine_tandy1k_init(const machine_t *); -extern int tandy1k_eeprom_read(void); - -extern void machine_xt_init(const machine_t *); -extern void machine_xt_compaq_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_LASERXT) -extern void machine_xt_laserxt_init(const machine_t *); -#endif - -extern void machine_xt_t1000_init(const machine_t *); -extern void machine_xt_t1200_init(const machine_t *); - -extern void machine_xt_xi8088_init(const machine_t *); - -#ifdef EMU_DEVICE_H -extern const device_t *xi8088_get_device(void); - -extern const device_t *pcjr_get_device(void); - -extern const device_t *tandy1k_get_device(void); -extern const device_t *tandy1k_hx_get_device(void); - -extern const device_t *t1000_get_device(void); -extern const device_t *t1200_get_device(void); - -extern const device_t *at_endeavor_get_device(void); -#endif - - -#endif /*EMU_MACHINE_H*/ diff --git a/src - Cópia/machine/machine_table.c b/src - Cópia/machine/machine_table.c deleted file mode 100644 index c1f89623b..000000000 --- a/src - Cópia/machine/machine_table.c +++ /dev/null @@ -1,266 +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.30 2018/05/26 - * - * 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. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "machine.h" - - -const machine_t machines[] = { - { "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, - { "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_xt_init, NULL }, - { "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, - { "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens",cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, - { "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device }, - { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device }, - { "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL }, -#endif - { "[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL }, - - { "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL }, - { "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, - { "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, - { "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, - { "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL }, - { "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, - { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL }, - { "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL }, -#endif - - { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL }, - { "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, - { "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[286 ISA] Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_compaq_init, NULL }, -#endif - { "[286 ISA] GW-286CT GEAR", ROM_GW286CT, "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL }, - { "[286 ISA] Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL }, - { "[286 ISA] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL }, - { "[286 ISA] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2 | MACHINE_HDC_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL }, - { "[286 ISA] IBM PS/2 model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL }, - { "[286 ISA] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibm_init, NULL }, - { "[286 ISA] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_scat_init, NULL }, - { "[286 ISA] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_scat_init, NULL }, -#ifdef WALTJE - { "[286 ISA] OpenAT 286", ROM_OPENAT, "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 4096, 128, 127, machine_at_init, NULL }, -#endif - { "[286 ISA] Toshiba T3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, - - { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, - - { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, - { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, - { "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL }, - { "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_scatsx_init, NULL }, - - { "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, - - { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, - { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL }, -#endif - - { "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, - { "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, - - { "[486 ISA] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL }, - { "[486 ISA] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL }, - { "[486 ISA] Award 486 clone", ROM_AWARD486_OPTI495, "award486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, - { "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_dtk486_init, NULL }, - { "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, - - { "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, - - { "[486 PCI] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, - - { "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - -#if defined(DEV_BRANCH) && defined(USE_AMD_K) - { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - - { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, - { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, 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", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, 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",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - - { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, 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 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, -#endif - { "[Socket 7 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, 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", ROM_PB640, "pb640", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, NULL }, - - { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, 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", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, 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", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, 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", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL }, - { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - - { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, -#else - { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - - { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, - { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 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", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 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",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - - { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, 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 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, -#endif - { "[Socket 7 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, 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", ROM_PB640, "pb640", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, NULL }, - - { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, 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", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, 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", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, 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", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL }, - { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - - { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, -#endif - -#if defined(DEV_BRANCH) && defined(USE_I686) - { "[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 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", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL }, -#endif - { "", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 } -}; - - -int -machine_count(void) -{ - return((sizeof(machines) / sizeof(machine)) - 1); -} - - -int -machine_getromset(void) -{ - return(machines[machine].id); -} - - -int -machine_getromset_ex(int m) -{ - return(machines[m].id); -} - - -int -machine_getmachine(int romset) -{ - int c = 0; - - while (machines[c].id != -1) { - if (machines[c].id == romset) - return(c); - c++; - } - - return(0); -} - - -char * -machine_getname(void) -{ - return((char *)machines[machine].name); -} - - -const device_t * -machine_getdevice(int machine) -{ - if (machines[machine].get_device) - return(machines[machine].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].id != -1) { - if (!strcmp(machines[c].internal_name, (const char *)s)) - return(c); - c++; - } - - return(0); -} diff --git a/src - Cópia/mca.c b/src - Cópia/mca.c deleted file mode 100644 index 3d0677b26..000000000 --- a/src - Cópia/mca.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include "io.h" -#include "mca.h" - - -void (*mca_card_write[8])(int addr, uint8_t val, void *priv); -uint8_t (*mca_card_read[8])(int addr, void *priv); -void *mca_priv[8]; - -static int mca_index; -static int mca_nr_cards; - - -void mca_init(int nr_cards) -{ - int c; - - for (c = 0; c < 8; c++) - { - mca_card_read[c] = NULL; - mca_card_write[c] = NULL; - mca_priv[c] = NULL; - } - - mca_index = 0; - mca_nr_cards = nr_cards; -} - -void mca_set_index(int index) -{ - mca_index = index; -} - -uint8_t mca_read(uint16_t port) -{ - if (mca_index >= mca_nr_cards) - return 0xff; - if (!mca_card_read[mca_index]) - return 0xff; - return mca_card_read[mca_index](port, mca_priv[mca_index]); -} - -void mca_write(uint16_t port, uint8_t val) -{ - if (mca_index >= mca_nr_cards) - return; - if (mca_card_write[mca_index]) - mca_card_write[mca_index](port, val, mca_priv[mca_index]); -} - -void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv) -{ - int c; - - for (c = 0; c < mca_nr_cards; c++) - { - if (!mca_card_read[c] && !mca_card_write[c]) - { - mca_card_read[c] = read; - mca_card_write[c] = write; - mca_priv[c] = priv; - return; - } - } -} diff --git a/src - Cópia/mca.h b/src - Cópia/mca.h deleted file mode 100644 index dd88c1f98..000000000 --- a/src - Cópia/mca.h +++ /dev/null @@ -1,7 +0,0 @@ -extern void mca_init(int nr_cards); -extern void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv); -extern void mca_set_index(int index); -extern uint8_t mca_read(uint16_t port); -extern void mca_write(uint16_t port, uint8_t val); - -extern void ps2_cache_clean(void); \ No newline at end of file diff --git a/src - Cópia/mcr.c b/src - Cópia/mcr.c deleted file mode 100644 index ddd2dd784..000000000 --- a/src - Cópia/mcr.c +++ /dev/null @@ -1,39 +0,0 @@ -/*INTEL 82355 MCR emulation - This chip was used as part of many 386 chipsets - It controls memory addressing and shadowing*/ -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "mem.h" - - -int nextreg6; -uint8_t mcr22; -int mcrlock,mcrfirst; - - -void resetmcr(void) -{ - mcrlock=0; - mcrfirst=1; - shadowbios=0; -} - -void writemcr(uint16_t addr, uint8_t val) -{ - switch (addr) - { - case 0x22: - if (val==6 && mcr22==6) nextreg6=1; - else nextreg6=0; - break; - case 0x23: - if (nextreg6) shadowbios=!val; - break; - } - mcr22=val; -} - diff --git a/src - Cópia/mem.c b/src - Cópia/mem.c deleted file mode 100644 index cad04677b..000000000 --- a/src - Cópia/mem.c +++ /dev/null @@ -1,1926 +0,0 @@ -/* - * 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. - * - * 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.10 2018/04/29 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#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 "config.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#ifdef USE_DYNAREC -# include "cpu/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 ram_low_mapping; -mem_mapping_t ram_high_mapping; -mem_mapping_t ram_mid_mapping; -mem_mapping_t bios_mapping[8]; -mem_mapping_t bios_high_mapping[8]; -mem_mapping_t romext_mapping; - -page_t *pages, /* RAM page table */ - **page_lookup; /* pagetable lookup */ -uint32_t pages_sz; /* #pages in table */ - -uint8_t isram[0x10000]; - -uint8_t *ram; /* the virtual RAM */ -uint32_t rammask; - -uint8_t *rom; /* the virtual ROM */ -uint8_t romext[32768]; -uint32_t biosmask; - -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 pctrans = 0; -int cachesize = 256; - -uint32_t ram_mapped_addr[64]; - -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; - - -/* FIXME: re-do this with a 'mem_ops' struct. */ -static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); -static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); -static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); -static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); -static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); -static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); -static uint8_t *_mem_exec[0x40000]; -static void *_mem_priv_r[0x40000]; -static void *_mem_priv_w[0x40000]; -static mem_mapping_t *_mem_mapping_r[0x40000]; -static mem_mapping_t *_mem_mapping_w[0x40000]; -static int _mem_state[0x40000]; - -static mem_mapping_t base_mapping; -static mem_mapping_t ram_remapped_mapping; - -#if FIXME -static uint8_t ff_array[0x1000]; -#else -static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; -#endif - -static int port_92_reg = 0; - - -#ifdef ENABLE_MEM_LOG -int mem_do_log = ENABLE_MEM_LOG; -#endif - - -static void -mem_log(const char *format, ...) -{ -#ifdef ENABLE_MEM_LOG - va_list ap; - - if (mem_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -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) >> 14]))[((x) >> 2) & 0xfff] - -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); - - 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; - } - -#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)]; - - writelookupp[writelnext] = mmu_perm; - writelookup[writelnext++] = virt >> 12; - writelnext &= (cachesize - 1); - - cycles -= 9; -} - - -uint8_t * -getpccache(uint32_t a) -{ - uint32_t a2; - - a2 = a; - - if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14]) { - a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF); - return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)]; - } - - a2 = a; - - if (cr0 >> 31) { - pctrans=1; - a = mmutranslate_read(a); - pctrans = 0; - - if (a == 0xffffffff) return ram; - } - a &= rammask; - - if (_mem_exec[a >> 14]) { - if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; - - return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (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_logical_addr = addr; - - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); - if(addr < (uint32_t) (mem_size * 1024)) return ram[addr]; - return 0xff; - } - - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xffffffff) return 0xff; - } - addr &= rammask; - - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - - -void -writemembl(uint32_t addr, uint8_t val) -{ - mem_logical_addr = addr; - - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); - if (addr < (uint32_t) (mem_size * 1024)) - ram[addr] = val; - return; - } - - 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; - - if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - - -uint8_t -readmemb386l(uint32_t seg, uint32_t addr) -{ - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - - return -1; - } - - mem_logical_addr = addr = addr + seg; - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); - if (addr < (uint32_t) (mem_size * 1024)) - return ram[addr]; - return 0xff; - } - - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xffffffff) - return 0xff; - } - - addr &= rammask; - - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - - -void -writememb386l(uint32_t seg, uint32_t addr, uint8_t val) -{ - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - - mem_logical_addr = addr = addr + seg; - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); - if (addr < (uint32_t) (mem_size * 1024)) - ram[addr] = val; - return; - } - - 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; - - if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - - -uint16_t -readmemwl(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - - if (addr2 & 1) { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) - 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 (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < (uint32_t) (mem_size * 1024)) - return *((uint16_t *)&ram[addr]); - return 0xffff; - } - - if (cr0 >> 31) { - addr2 = mmutranslate_read(addr2); - if (addr2 == 0xffffffff) - return 0xFFFF; - } - - addr2 &= rammask; - - if (_mem_read_w[addr2 >> 14]) - return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); - - if (_mem_read_b[addr2 >> 14]) { - if (AT) - return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint16_t) (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14])) << 8); - else - return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint16_t) (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14])) << 8); - } - - return 0xffff; -} - - -void -writememwl(uint32_t seg, uint32_t addr, uint16_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < mem_size * 1024) - *((uint16_t *)&ram[addr]) = val; - return; - } - - if (addr2 & 1) { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) - 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; - } - } - - if (page_lookup[addr2>>12]) { - page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); - return; - } - - if (cr0 >> 31) { - addr2 = mmutranslate_write(addr2); - if (addr2 == 0xffffffff) return; - } - - addr2 &= rammask; - -#if 0 - if (addr2 >= 0xa0000 && addr2 < 0xc0000) - mem_log("writememwl %08X %02X\n", addr2, val); -#endif - - if (_mem_write_w[addr2 >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - return; - } - - if (_mem_write_b[addr2 >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - return; - } -} - - -uint32_t -readmemll(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < mem_size * 1024) - return *((uint32_t *)&ram[addr]); - return 0xffffffff; - } - - if (addr2 & 3) { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) - 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); - } - - if (cr0 >> 31) { - addr2 = mmutranslate_read(addr2); - if (addr2 == 0xffffffff) - return 0xffffffff; - } - - addr2 &= rammask; - - if (_mem_read_l[addr2 >> 14]) - return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); - - if (_mem_read_w[addr2 >> 14]) - return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint32_t) (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14])) << 16); - - if (_mem_read_b[addr2 >> 14]) - return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14])) << 8) | - ((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14])) << 16) | - ((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14])) << 24); - - return 0xffffffff; -} - - -void -writememll(uint32_t seg, uint32_t addr, uint32_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < mem_size * 1024) - *((uint32_t *)&ram[addr]) = val; - return; - } - - if (addr2 & 3) { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) - 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; - } - } - - if (page_lookup[addr2>>12]) { - page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); - return; - } - - if (cr0 >> 31) { - addr2 = mmutranslate_write(addr2); - if (addr2 == 0xffffffff) return; - } - - addr2 &= rammask; - - if (_mem_write_l[addr2 >> 14]) { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_w[addr2 >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_b[addr2 >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); - return; - } -} - - -uint64_t -readmemql(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < mem_size * 1024) - return *((uint64_t *)&ram[addr]); - return -1; - } - - if (addr2 & 7) { - 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); - } - - if (cr0 >> 31) { - addr2 = mmutranslate_read(addr2); - if (addr2 == 0xffffffff) - return -1; - } - - addr2 &= rammask; - - if (_mem_read_l[addr2 >> 14]) - return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32); - - return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); -} - - -void -writememql(uint32_t seg, uint32_t addr, uint64_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); - if (addr < mem_size * 1024) - *((uint64_t *)&ram[addr]) = val; - return; - } - - if (addr2 & 7) { - 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; - } - } - - 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; - } - - if (cr0 >> 31) { - addr2 = mmutranslate_write(addr2); - if (addr2 == 0xffffffff) return; - } - - addr2 &= rammask; - - if (_mem_write_l[addr2 >> 14]) { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_w[addr2 >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_b[addr2 >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); - return; - } -} - - -uint8_t -mem_readb_phys(uint32_t addr) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - - -/* - * Version of mem_readby_phys that doesn't go through - * the CPU paging mechanism. - */ -uint8_t -mem_readb_phys_dma(uint32_t addr) -{ -#if 0 - mem_logical_addr = 0xffffffff; -#endif - - if (_mem_exec[addr >> 14]) - return _mem_exec[addr >> 14][addr & 0x3fff]; - else if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - else - return 0xff; -} - - -uint16_t -mem_readw_phys(uint32_t addr) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_read_w[addr >> 14]) - return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - - -void -mem_writeb_phys(uint32_t addr, uint8_t val) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - - -/* - * Version of mem_readby_phys that doesn't go through - * the CPU paging mechanism. - */ -void -mem_writeb_phys_dma(uint32_t addr, uint8_t val) -{ -#if 0 - mem_logical_addr = 0xffffffff; -#endif - - if (_mem_exec[addr >> 14]) - _mem_exec[addr >> 14][addr & 0x3fff] = val; - else if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - - -void -mem_writew_phys(uint32_t addr, uint16_t val) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_write_w[addr >> 14]) - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - - -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]; -} - - -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; - } -} - - -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; - } -} - - -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; - } -} - - -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]); -} - - -uint8_t -mem_read_bios(uint32_t addr, void *priv) -{ - return rom[addr & biosmask]; -} - - -uint16_t -mem_read_biosw(uint32_t addr, void *priv) -{ - return *(uint16_t *)&rom[addr & biosmask]; -} - - -uint32_t -mem_read_biosl(uint32_t addr, void *priv) -{ - return *(uint32_t *)&rom[addr & biosmask]; -} - - -uint8_t -mem_read_romext(uint32_t addr, void *priv) -{ - return romext[addr & 0x7fff]; -} - - -uint16_t -mem_read_romextw(uint32_t addr, void *priv) -{ - uint16_t *p = (uint16_t *)&romext[addr & 0x7fff]; - - return *p; -} - - -uint32_t -mem_read_romextl(uint32_t addr, void *priv) -{ - uint32_t *p = (uint32_t *)&romext[addr & 0x7fff]; - - return *p; -} - - -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) -{ - 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); - - pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - } -} - - -static __inline int -mem_mapping_read_allowed(uint32_t flags, int state) -{ - switch (state & MEM_READ_MASK) { - case MEM_READ_ANY: - return 1; - - case MEM_READ_EXTERNAL: - 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; - case MEM_WRITE_EXTERNAL: - 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 *mapping = base_mapping.next; - uint64_t c; - - if (! size) return; - - /* Clear out old mappings. */ - for (c = base; c < base + size; c += 0x4000) { - _mem_read_b[c >> 14] = NULL; - _mem_read_w[c >> 14] = NULL; - _mem_read_l[c >> 14] = NULL; - _mem_exec[c >> 14] = NULL; - _mem_priv_r[c >> 14] = NULL; - _mem_mapping_r[c >> 14] = NULL; - _mem_write_b[c >> 14] = NULL; - _mem_write_w[c >> 14] = NULL; - _mem_write_l[c >> 14] = NULL; - _mem_priv_w[c >> 14] = NULL; - _mem_mapping_w[c >> 14] = NULL; - } - - /* Walk mapping list. */ - while (mapping != NULL) { - /*In range?*/ - if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) { - uint64_t start = (mapping->base < base) ? mapping->base : base; - uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size); - if (start < mapping->base) - start = mapping->base; - - for (c = start; c < end; c += 0x4000) { - if ((mapping->read_b || mapping->read_w || mapping->read_l) && - mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) { - _mem_read_b[c >> 14] = mapping->read_b; - _mem_read_w[c >> 14] = mapping->read_w; - _mem_read_l[c >> 14] = mapping->read_l; - if (mapping->exec) - _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); - else - _mem_exec[c >> 14] = NULL; - _mem_priv_r[c >> 14] = mapping->p; - _mem_mapping_r[c >> 14] = mapping; - } - if ((mapping->write_b || mapping->write_w || mapping->write_l) && - mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { - _mem_write_b[c >> 14] = mapping->write_b; - _mem_write_w[c >> 14] = mapping->write_w; - _mem_write_l[c >> 14] = mapping->write_l; - _mem_priv_w[c >> 14] = mapping->p; - _mem_mapping_w[c >> 14] = mapping; - } - } - } - mapping = mapping->next; - } - - flushmmucache_cr3(); -} - - -void -mem_mapping_add(mem_mapping_t *mapping, - 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 flags, - void *p) -{ - mem_mapping_t *dest = &base_mapping; - - /* Add mapping to the end of the list.*/ - while (dest->next) - dest = dest->next; - dest->next = mapping; - mapping->prev = dest; - - if (size) - mapping->enable = 1; - else - mapping->enable = 0; - mapping->base = base; - mapping->size = size; - mapping->read_b = read_b; - mapping->read_w = read_w; - mapping->read_l = read_l; - mapping->write_b = write_b; - mapping->write_w = write_w; - mapping->write_l = write_l; - mapping->exec = exec; - mapping->flags = flags; - mapping->p = p; - mapping->next = NULL; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_mapping_set_handler(mem_mapping_t *mapping, - 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)) -{ - mapping->read_b = read_b; - mapping->read_w = read_w; - mapping->read_l = read_l; - mapping->write_b = write_b; - mapping->write_w = write_w; - mapping->write_l = write_l; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size) -{ - /* Remove old mapping. */ - mapping->enable = 0; - mem_mapping_recalc(mapping->base, mapping->size); - - /* Set new mapping. */ - mapping->enable = 1; - mapping->base = base; - mapping->size = size; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec) -{ - mapping->exec = exec; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_mapping_set_p(mem_mapping_t *mapping, void *p) -{ - mapping->p = p; -} - - -void -mem_mapping_disable(mem_mapping_t *mapping) -{ - mapping->enable = 0; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_mapping_enable(mem_mapping_t *mapping) -{ - mapping->enable = 1; - - mem_mapping_recalc(mapping->base, mapping->size); -} - - -void -mem_set_mem_state(uint32_t base, uint32_t size, int state) -{ - uint32_t c; - - for (c = 0; c < size; c += 0x4000) - _mem_state[(c + base) >> 14] = state; - - mem_mapping_recalc(base, size); -} - - -void -mem_add_bios(void) -{ - if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, - 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, 0); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x4000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x8000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0xc000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - } - - mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x10000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x14000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x18000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x1c000 & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - - mem_mapping_add(&bios_high_mapping[0], - (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[1], - (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[2], - (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[3], - (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[4], - (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[5], - (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[6], - (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[7], - (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0); -} - - -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; - - /* Free the ROM memory and reset size mask. */ - if (rom != NULL) { - free(rom); - rom = NULL; - } - biosmask = 0xffff; - - /* - * Always allocate the full 16 MB memory space if memory size - * is smaller, we'll need this for stupid things like the PS/2 - * split mapping. - */ - if (mem_size < 16384) - m = 1024UL * 16384; - else - m = 1024UL * (mem_size + 384); /* 386 extra kB for top remapping */ - 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)); - - for (c=0; c= 0xa && c <= 0xf) || - (cpu_16bitbus && c >= 0xfe && c <= 0xff)) - isram[c] = 0; - } - - memset(_mem_read_b, 0x00, sizeof(_mem_read_b)); - memset(_mem_read_w, 0x00, sizeof(_mem_read_w)); - memset(_mem_read_l, 0x00, sizeof(_mem_read_l)); - memset(_mem_write_b, 0x00, sizeof(_mem_write_b)); - memset(_mem_write_w, 0x00, sizeof(_mem_write_w)); - memset(_mem_write_l, 0x00, sizeof(_mem_write_l)); - 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); - - if (romset == ROM_IBMPS1_2011) - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, - mem_read_romext,mem_read_romextw,mem_read_romextl, - NULL,NULL, NULL, romext, 0, NULL); - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - mem_a20_init(); -} - - -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 - - memset(ram_mapped_addr, 0x00, 64 * sizeof(uint32_t)); - -#if FIXME - memset(ff_array, 0xff, sizeof(ff_array)); -#endif - - /* Reset the memory state. */ - mem_reset(); -} - - -static void -mem_remap_top(int max_size) -{ - uint32_t c; - - if (mem_size > 640) { - uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int size = mem_size - 640; - if (size > max_size) - size = max_size; - - for (c = (start / 64); c < ((start + size - 1) / 64); c++) - isram[c] = 1; - - 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_remap_top_256k(void) -{ - mem_remap_top(256); -} - - -void -mem_remap_top_384k(void) -{ - mem_remap_top(384); -} - - -void -mem_reset_page_blocks(void) -{ - uint32_t c; - - if (pages == NULL) return; - - for (c = 0; c < ((mem_size * 1024) >> 12); 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; - } - - 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; -} - - -uint8_t -port_92_read(uint16_t port, void *priv) -{ - return port_92_reg; -} - - -void -port_92_write(uint16_t port, uint8_t val, void *priv) -{ - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = (val & 2); - mem_a20_recalc(); - } - - if ((~port_92_reg & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - - port_92_reg = val; -} - - -void -port_92_clear_reset(void) -{ - port_92_reg &= 2; -} - - -void -port_92_add(void) -{ - io_sethandler(0x0092, 1, - port_92_read,NULL,NULL, port_92_write, NULL,NULL,NULL); -} - - -void -port_92_remove(void) -{ - io_removehandler(0x0092, 1, - port_92_read,NULL,NULL, port_92_write,NULL,NULL, NULL); -} - - -void -port_92_reset(void) -{ - port_92_reg = 0; - mem_a20_alt = 0; - mem_a20_recalc(); - - flushmmucache(); -} diff --git a/src - Cópia/mem.h b/src - Cópia/mem.h deleted file mode 100644 index 660bab616..000000000 --- a/src - Cópia/mem.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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 memory interface. - * - * Version: @(#)mem.h 1.0.4 2018/03/16 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_MEM_H -# define EMU_MEM_H - - -#define MEM_MAPPING_EXTERNAL 1 /* on external bus (ISA/PCI) */ -#define MEM_MAPPING_INTERNAL 2 /* on internal bus (RAM) */ -#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve - * additional wait states. */ - -#define MEM_MAP_TO_SHADOW_RAM_MASK 1 -#define MEM_MAP_TO_RAM_ADDR_MASK 2 - -#define MEM_READ_ANY 0x00 -#define MEM_READ_INTERNAL 0x10 -#define MEM_READ_EXTERNAL 0x20 -#define MEM_READ_MASK 0xf0 - -#define MEM_WRITE_ANY 0x00 -#define MEM_WRITE_INTERNAL 0x01 -#define MEM_WRITE_EXTERNAL 0x02 -#define MEM_WRITE_DISABLED 0x03 -#define MEM_WRITE_MASK 0x0f - - -typedef struct _mem_mapping_ { - struct _mem_mapping_ *prev, *next; - - int enable; - - uint32_t base; - uint32_t size; - - uint8_t (*read_b)(uint32_t addr, void *priv); - uint16_t (*read_w)(uint32_t addr, void *priv); - uint32_t (*read_l)(uint32_t addr, void *priv); - void (*write_b)(uint32_t addr, uint8_t val, void *priv); - void (*write_w)(uint32_t addr, uint16_t val, void *priv); - void (*write_l)(uint32_t addr, uint32_t val, void *priv); - - uint8_t *exec; - - uint32_t flags; - - void *p; -} mem_mapping_t; - -typedef struct _page_ { - void (*write_b)(uint32_t addr, uint8_t val, struct _page_ *p); - void (*write_w)(uint32_t addr, uint16_t val, struct _page_ *p); - void (*write_l)(uint32_t addr, uint32_t val, struct _page_ *p); - - uint8_t *mem; - - uint64_t code_present_mask[4], - dirty_mask[4]; - - struct codeblock_t *block[4], *block_2[4]; - - /*Head of codeblock tree associated with this page*/ - struct codeblock_t *head; -} page_t; - - -extern uint8_t *ram; -extern uint32_t rammask; - -extern uint8_t *rom; -extern uint8_t romext[32768]; -extern uint32_t biosmask; - -extern int readlookup[256], - readlookupp[256]; -extern uintptr_t * readlookup2; -extern int readlnext; -extern int writelookup[256], - writelookupp[256]; -extern uintptr_t *writelookup2; -extern int writelnext; -extern uint32_t ram_mapped_addr[64]; - -extern mem_mapping_t bios_mapping[8], - bios_high_mapping[8], - romext_mapping, - ram_low_mapping, - ram_mid_mapping, - ram_high_mapping; - -extern uint32_t mem_logical_addr; - -extern page_t *pages, - **page_lookup; - -extern uint32_t get_phys_virt,get_phys_phys; - -extern int shadowbios, - shadowbios_write; -extern int readlnum, - writelnum; - -extern int nopageerrors; -extern int memspeed[11]; -extern uint8_t isram[0x10000]; - -extern int mmu_perm; - -extern int mem_a20_state, - mem_a20_alt, - mem_a20_key; - - -#define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((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)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) - - -extern uint8_t readmembl(uint32_t addr); -extern void writemembl(uint32_t addr, uint8_t val); -extern uint8_t readmemb386l(uint32_t seg, uint32_t addr); -extern void writememb386l(uint32_t seg, uint32_t addr, uint8_t val); -extern uint16_t readmemwl(uint32_t seg, uint32_t addr); -extern void writememwl(uint32_t seg, uint32_t addr, uint16_t val); -extern uint32_t readmemll(uint32_t seg, uint32_t addr); -extern void writememll(uint32_t seg, uint32_t addr, uint32_t val); -extern uint64_t readmemql(uint32_t seg, uint32_t addr); -extern void writememql(uint32_t seg, uint32_t addr, uint64_t val); - -extern uint8_t *getpccache(uint32_t a); -extern uint32_t mmutranslatereal(uint32_t addr, int rw); -extern void addreadlookup(uint32_t virt, uint32_t phys); -extern void addwritelookup(uint32_t virt, uint32_t phys); - -extern void mem_mapping_add(mem_mapping_t *mapping, - 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 flags, - void *p); - -extern void mem_mapping_set_handler(mem_mapping_t *mapping, - 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)); - -extern void mem_mapping_set_p(mem_mapping_t *mapping, void *p); - -extern void mem_mapping_set_addr(mem_mapping_t *mapping, - uint32_t base, uint32_t size); -extern void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); -extern void mem_mapping_disable(mem_mapping_t *mapping); -extern void mem_mapping_enable(mem_mapping_t *mapping); - -extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); - -extern uint8_t mem_readb_phys(uint32_t addr); -extern uint8_t mem_readb_phys_dma(uint32_t addr); -extern uint16_t mem_readw_phys(uint32_t addr); -extern void mem_writeb_phys(uint32_t addr, uint8_t val); -extern void mem_writeb_phys_dma(uint32_t addr, uint8_t val); -extern void mem_writew_phys(uint32_t addr, uint16_t val); - -extern uint8_t mem_read_ram(uint32_t addr, void *priv); -extern uint16_t mem_read_ramw(uint32_t addr, void *priv); -extern uint32_t mem_read_raml(uint32_t addr, void *priv); -extern void mem_write_ram(uint32_t addr, uint8_t val, void *priv); -extern void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); -extern void mem_write_raml(uint32_t addr, uint32_t val, void *priv); - -extern uint8_t mem_read_bios(uint32_t addr, void *priv); -extern uint16_t mem_read_biosw(uint32_t addr, void *priv); -extern uint32_t mem_read_biosl(uint32_t addr, void *priv); - -extern void mem_write_null(uint32_t addr, uint8_t val, void *p); -extern void mem_write_nullw(uint32_t addr, uint16_t val, void *p); -extern void mem_write_nulll(uint32_t addr, uint32_t val, void *p); - -extern uint32_t mmutranslate_noabrt(uint32_t addr, int rw); - -extern void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr); - -extern void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p); -extern void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p); -extern void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); -extern void mem_flush_write_page(uint32_t addr, uint32_t virt); - -extern void mem_reset_page_blocks(void); - -extern void flushmmucache(void); -extern void flushmmucache_cr3(void); -extern void flushmmucache_nopc(void); -extern void mmu_invalidate(uint32_t addr); - -extern void mem_a20_recalc(void); - -extern void mem_add_bios(void); - -extern void mem_init(void); -extern void mem_reset(void); -extern void mem_remap_top_256k(void); -extern void mem_remap_top_384k(void); - -extern uint8_t port_92_read(uint16_t port, void *priv); -extern void port_92_write(uint16_t port, uint8_t val, void *priv); -extern void port_92_clear_reset(void); -extern void port_92_add(void); -extern void port_92_remove(void); -extern void port_92_reset(void); - - -#ifdef EMU_CPU_H -static __inline uint32_t get_phys(uint32_t addr) -{ - if (! ((addr ^ get_phys_virt) & ~0xfff)) - return get_phys_phys | (addr & 0xfff); - - get_phys_virt = addr; - - if (! (cr0 >> 31)) { - get_phys_phys = (addr & rammask) & ~0xfff; - - return addr & rammask; - } - - get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; - -#if 1 - return get_phys_phys | (addr & 0xfff); -#else - return mmutranslatereal(addr, 0) & rammask; -#endif -} - - -static __inline uint32_t get_phys_noabrt(uint32_t addr) -{ - if (! (cr0 >> 31)) - return addr & rammask; - - return mmutranslate_noabrt(addr, 0) & rammask; -} -#endif - - -#endif /*EMU_MEM_H*/ diff --git a/src - Cópia/memregs.c b/src - Cópia/memregs.c deleted file mode 100644 index f1aae4ac8..000000000 --- a/src - Cópia/memregs.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the memory I/O scratch registers on ports 0xE1 - * and 0xE2, used by just about any emulated machine. - * - * Version: @(#)memregs.c 1.0.6 2018/04/29 - * - * Author: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "io.h" -#include "memregs.h" - - -static uint8_t mem_regs[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - -static uint8_t mem_reg_ffff = 0; - - -void memregs_write(uint16_t port, uint8_t val, void *priv) -{ - if (port == 0xffff) - { - mem_reg_ffff = 0; - } - - mem_regs[port & 0xf] = val; -} - -uint8_t memregs_read(uint16_t port, void *priv) -{ - if (port == 0xffff) - { - return mem_reg_ffff; - } - - return mem_regs[port & 0xf]; -} - -void memregs_init(void) -{ - io_sethandler(0x00e1, 0x0002, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); -} - -void powermate_memregs_init(void) -{ - io_sethandler(0x00ed, 0x0002, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); - io_sethandler(0xffff, 0x0001, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); -} diff --git a/src - Cópia/memregs.h b/src - Cópia/memregs.h deleted file mode 100644 index c44cc21ed..000000000 --- a/src - Cópia/memregs.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. - * - * Emulation of the memory I/O scratch registers on ports 0xE1 - * and 0xE2, used by just about any emulated machine. - * - * Version: @(#)memregs.h 1.0.1 2017/08/23 - * - * Author: Miran Grca, - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_MEMREGS_H -# define EMU_MEMREGS_H - - -extern void powermate_memregs_init(void); -extern void memregs_init(void); - - -#endif /*EMU_MEMREGS_H*/ diff --git a/src - Cópia/mouse.c b/src - Cópia/mouse.c deleted file mode 100644 index 64364b81e..000000000 --- a/src - Cópia/mouse.c +++ /dev/null @@ -1,255 +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. - * - * Common driver module for MOUSE devices. - * - * TODO: Add the Genius bus- and serial mouse. - * Remove the '3-button' flag from mouse types. - * - * Version: @(#)mouse.c 1.0.27 2018/04/29 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "device.h" -#include "mouse.h" - - -typedef struct { - const char *internal_name; - const device_t *device; -} mouse_t; - - -int mouse_type = 0; -int mouse_x, - mouse_y, - mouse_z, - mouse_buttons; - - -static const device_t mouse_none_device = { - "None", - 0, MOUSE_TYPE_NONE, - NULL, NULL, NULL, - NULL, NULL, NULL, - NULL -}; -static const device_t mouse_internal_device = { - "Internal Mouse", - 0, MOUSE_TYPE_INTERNAL, - NULL, NULL, NULL, - NULL, NULL, NULL, - NULL -}; - - -static mouse_t mouse_devices[] = { - { "none", &mouse_none_device }, - { "internal", &mouse_internal_device }, - { "logibus", &mouse_logibus_device }, - { "msbus", &mouse_msinport_device }, -#if 0 - { "genibus", &mouse_genibus_device }, -#endif - { "mssystems", &mouse_mssystems_device }, - { "msserial", &mouse_msserial_device }, - { "ps2", &mouse_ps2_device }, - { NULL, NULL } -}; - - -static const device_t *mouse_curr; -static void *mouse_priv; -static int mouse_nbut; -static int (*mouse_dev_poll)(); - - -#ifdef ENABLE_MOUSE_LOG -int mouse_do_log = ENABLE_MOUSE_LOG; -#endif - - -static void -mouse_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_LOG - va_list ap; - - if (mouse_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Initialize the mouse module. */ -void -mouse_init(void) -{ - /* Initialize local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - - mouse_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; -} - - -void -mouse_close(void) -{ - if (mouse_curr == NULL) return; - - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; -} - - -void -mouse_reset(void) -{ - if ((mouse_curr != NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) - return; /* Mouse already initialized. */ - - mouse_log("MOUSE: reset(type=%d, '%s')\n", - mouse_type, mouse_devices[mouse_type].device->name); - - /* Clear local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - - /* If no mouse configured, we're done. */ - if (mouse_type == 0) return; - - mouse_curr = mouse_devices[mouse_type].device; - - if (mouse_curr != NULL) - mouse_priv = device_add(mouse_curr); -} - - -/* Callback from the hardware driver. */ -void -mouse_set_buttons(int buttons) -{ - mouse_nbut = buttons; -} - - -void -mouse_process(void) -{ - static int poll_delay = 2; - - if ((mouse_curr == NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) - return; - - if (--poll_delay) return; - - mouse_poll(); - - if ((mouse_dev_poll != NULL) || (mouse_curr->available != NULL)) { - if (mouse_curr->available != NULL) - mouse_curr->available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); - else - mouse_dev_poll(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); - - /* Reset mouse deltas. */ - mouse_x = mouse_y = mouse_z = 0; - } - - poll_delay = 2; -} - - -void -mouse_set_poll(int (*func)(int,int,int,int,void *), void *arg) -{ - if (mouse_type != MOUSE_TYPE_INTERNAL) return; - - mouse_dev_poll = func; - mouse_priv = arg; -} - - -char * -mouse_get_name(int mouse) -{ - return((char *)mouse_devices[mouse].device->name); -} - - -char * -mouse_get_internal_name(int mouse) -{ - return((char *)mouse_devices[mouse].internal_name); -} - - -int -mouse_get_from_internal_name(char *s) -{ - int c = 0; - - while (mouse_devices[c].internal_name != NULL) { - if (! strcmp((char *)mouse_devices[c].internal_name, s)) - return(c); - c++; - } - - return(0); -} - - -int -mouse_has_config(int mouse) -{ - if (mouse_devices[mouse].device == NULL) return(0); - - return(mouse_devices[mouse].device->config ? 1 : 0); -} - - -const device_t * -mouse_get_device(int mouse) -{ - return(mouse_devices[mouse].device); -} - - -int -mouse_get_buttons(void) -{ - return(mouse_nbut); -} - - -/* Return number of MOUSE types we know about. */ -int -mouse_get_ndev(void) -{ - return((sizeof(mouse_devices)/sizeof(mouse_t)) - 1); -} diff --git a/src - Cópia/mouse.h b/src - Cópia/mouse.h deleted file mode 100644 index 4d402fa0a..000000000 --- a/src - Cópia/mouse.h +++ /dev/null @@ -1,81 +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. - * - * Definitions for the mouse driver. - * - * Version: @(#)mouse.h 1.0.15 2018/03/18 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_MOUSE_H -# define EMU_MOUSE_H - - -#define MOUSE_TYPE_NONE 0 /* no mouse configured */ -#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */ -#define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */ -#define MOUSE_TYPE_INPORT 3 /* Microsoft InPort Mouse */ -#if 0 -# define MOUSE_TYPE_GENIBUS 4 /* Genius Bus Mouse */ -#endif -#define MOUSE_TYPE_MSYSTEMS 5 /* Mouse Systems mouse */ -#define MOUSE_TYPE_MICROSOFT 6 /* Microsoft Serial Mouse */ -#define MOUSE_TYPE_LOGITECH 7 /* Logitech Serial Mouse */ -#define MOUSE_TYPE_MSWHEEL 8 /* Serial Wheel Mouse */ -#define MOUSE_TYPE_PS2 9 /* PS/2 series Bus Mouse */ - - -#ifdef __cplusplus -extern "C" { -#endif - -extern int mouse_type; -extern int mouse_x, mouse_y, mouse_z; -extern int mouse_buttons; - - -#ifdef EMU_DEVICE_H -extern const device_t *mouse_get_device(int mouse); -extern void *mouse_ps2_init(const device_t *); - -extern const device_t mouse_logibus_device; -extern const device_t mouse_msinport_device; -#if 0 -extern const device_t mouse_genibus_device; -#endif -extern const device_t mouse_mssystems_device; -extern const device_t mouse_msserial_device; -extern const device_t mouse_ps2_device; -#endif - -extern void mouse_init(void); -extern void mouse_close(void); -extern void mouse_reset(void); -extern void mouse_set_buttons(int buttons); -extern void mouse_process(void); -extern void mouse_set_poll(int (*f)(int,int,int,int,void *), void *); -extern void mouse_poll(void); - -extern char *mouse_get_name(int mouse); -extern char *mouse_get_internal_name(int mouse); -extern int mouse_get_from_internal_name(char *s); -extern int mouse_has_config(int mouse); -extern int mouse_get_type(int mouse); -extern int mouse_get_ndev(void); -extern int mouse_get_buttons(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_MOUSE_H*/ diff --git a/src - Cópia/mouse_bus - Cópia (2).c b/src - Cópia/mouse_bus - Cópia (2).c deleted file mode 100644 index bd626e258..000000000 --- a/src - Cópia/mouse_bus - Cópia (2).c +++ /dev/null @@ -1,876 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.39 2018/05/24 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_ctrl = (LTCTRL_IDIS) | 0x0f; - dev->r_conf = 0x0e; - dev->r_magic = 0x00; - - dev->seq = 0; - dev->flags &= 0xf0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - -0x20 >> 5 = 0x01 -0x20 >> 4 = 0x02 -0x20 >> 3 = 0x04 -0x20 >> 2 = 0x08 - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - dev->r_ctrl &= ~((1 << 5) >> dev->irq); -#if 0 - switch(dev->irq) { - case 2: - dev->r_ctrl &= ~0x08; - break; - - case 3: - dev->r_ctrl &= ~0x04; - break; - - case 4: - dev->r_ctrl &= ~0x02; - break; - - case 5: - dev->r_ctrl &= ~0x01; - break; - } -#endif - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_bus - Cópia (3).c b/src - Cópia/mouse_bus - Cópia (3).c deleted file mode 100644 index 424d75b53..000000000 --- a/src - Cópia/mouse_bus - Cópia (3).c +++ /dev/null @@ -1,632 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. - * - * Logitech Bus Mouse verified with: - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 - * - * InPort verified with: - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE - * - * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 - * - * Authors: Miran Grca, - * - * Copyright 200?-2018 Bochs. - * Copyright 2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - -#define IRQ_MASK ((1<<5) >> dev->irq) - -/* MS Inport Bus Mouse Adapter */ -#define INP_PORT_CONTROL 0x0000 -#define INP_PORT_DATA 0x0001 -#define INP_PORT_SIGNATURE 0x0002 -#define INP_PORT_CONFIG 0x0003 - -#define INP_CTRL_READ_BUTTONS 0x00 -#define INP_CTRL_READ_X 0x01 -#define INP_CTRL_READ_Y 0x02 -#define INP_CTRL_COMMAND 0x07 -#define INP_CTRL_RAISE_IRQ 0x16 -#define INP_CTRL_RESET 0x80 - -#define INP_HOLD_COUNTER (1 << 5) -#define INP_ENABLE_TIMER_IRQ (1 << 4) -#define INP_ENABLE_DATA_IRQ (1 << 3) -#define INP_PERIOD_MASK 0x07 - -#define INP_PERIOD (33334LL * TIMER_USEC) - -/* MS/Logictech Standard Bus Mouse Adapter */ -#define BUSM_PORT_DATA 0x0000 -#define BUSM_PORT_SIGNATURE 0x0001 -#define BUSM_PORT_CONTROL 0x0002 -#define BUSM_PORT_CONFIG 0x0003 - -/* The MS/Logitech Standard Bus Mouse sends data about 45 times a second */ -#define BUSM_PERIOD (22223LL * TIMER_USEC) - -#define HOLD_COUNTER (1 << 7) -#define READ_X (0 << 6) -#define READ_Y (1 << 6) -#define READ_LOW (0 << 5) -#define READ_HIGH (1 << 5) -#define DISABLE_IRQ (1 << 4) - -#define READ_X_LOW (READ_X | READ_LOW) -#define READ_X_HIGH (READ_X | READ_HIGH) -#define READ_Y_LOW (READ_Y | READ_LOW) -#define READ_Y_HIGH (READ_Y | READ_HIGH) - - -/* Our mouse device. */ -typedef struct mouse { - int type, model, base, irq, bn, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, - current_x, current_y, - current_b, - control_val, mouse_buttons_last, - config_val, sig_val, - command_val, toggle_counter, - data_int, hold, - interrupts; - - double period; - - int64_t timer_enabled, timer; /* mouse event timer */ -} mouse_t; - - -#ifdef ENABLE_MOUSE_BUS_LOG -int bm_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -bm_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (bm_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - if (dev->type == MOUSE_TYPE_INPORT) { - switch (port & 0x03) { - case INP_PORT_CONTROL: - value = dev->control_val; - break; - case INP_PORT_DATA: - switch (dev->command_val) { - case INP_CTRL_READ_BUTTONS: - value = dev->current_b | 0x80; - if (dev->model) - value |= 0x40; /* Newer Logitech mouse drivers look for bit 6 set */ - break; - case INP_CTRL_READ_X: - value = dev->current_x; - break; - case INP_CTRL_READ_Y: - value = dev->current_y; - break; - case INP_CTRL_COMMAND: - value = dev->control_val; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - break; - case INP_PORT_SIGNATURE: - if (dev->toggle_counter) - value = 0x12; - else - value = 0xDE; - dev->toggle_counter ^= 1; - break; - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported read from port 0x%04x\n", port); - break; - } - } else { - switch (port & 0x03) { - case BUSM_PORT_CONTROL: - value = dev->control_val; - dev->control_val |= 0x0F; - - if ((dev->toggle_counter > 0x3FF) && (!dev->model || dev->interrupts)) - dev->control_val &= ~IRQ_MASK; - dev->toggle_counter = (dev->toggle_counter + 1) & 0x7FF; - break; - case BUSM_PORT_DATA: - /* Testing and another source confirm that the buttons are - *ALWAYS* present, so I'm going to change this a bit. */ - switch (dev->control_val & 0x60) { - case READ_X_LOW: - value = dev->current_x & 0x0F; - break; - case READ_X_HIGH: - value = (dev->current_x >> 4) & 0x0F; - break; - case READ_Y_LOW: - value = dev->current_y & 0x0F; - break; - case READ_Y_HIGH: - value = (dev->current_y >> 4) & 0x0F; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - value |= ((dev->current_b ^ 7) << 5); - break; - case BUSM_PORT_CONFIG: - value = dev->config_val; - break; - case BUSM_PORT_SIGNATURE: - value = dev->sig_val; - break; - } - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - if (dev->type == MOUSE_TYPE_INPORT) { - switch (port & 0x03) { - case INP_PORT_CONTROL: - /* Bit 7 is reset. */ - if (val & INP_CTRL_RESET) - dev->control_val = 0; - - /* Bits 0-2 are the internal register index. */ - switch(val & 0x07) { - case INP_CTRL_COMMAND: - case INP_CTRL_READ_BUTTONS: - case INP_CTRL_READ_X: - case INP_CTRL_READ_Y: - dev->command_val = val & 0x07; - break; - default: - bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_DATA: - picintc(1 << dev->irq); - switch(dev->command_val) { - case INP_CTRL_COMMAND: - dev->hold = (val & INP_HOLD_COUNTER) > 0; - - dev->interrupts = (val & INP_ENABLE_TIMER_IRQ) > 0; - dev->data_int = (val & INP_ENABLE_DATA_IRQ) > 0; - - switch(val & INP_PERIOD_MASK) { - case 0: - dev->period = 0.0; - dev->timer_enabled = 0; - break; - case 1: - dev->period = 1000000.0 / 30.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 2: - dev->period = 1000000.0 / 50.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 3: - dev->period = 1000000.0 / 100.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 4: - dev->period = 1000000.0 / 200.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 6: - if (val & INP_ENABLE_TIMER_IRQ) - picint(1 << dev->irq); - dev->control_val &= INP_PERIOD_MASK; - dev->control_val |= (val & ~INP_PERIOD_MASK); - return; - default: - bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); - } - - dev->control_val = val; - - break; - default: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_SIGNATURE: - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } - } else { - switch (port & 0x03) { - case BUSM_PORT_CONTROL: - dev->control_val = val | 0x0F; - - dev->interrupts = (val & DISABLE_IRQ) == 0; - dev->hold = (val & HOLD_COUNTER) > 0; - - picintc(1 << dev->irq); - - break; - case BUSM_PORT_CONFIG: - dev->config_val = val; - break; - case BUSM_PORT_SIGNATURE: - dev->sig_val = val; - break; - case BUSM_PORT_DATA: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } - } -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t shift = 0xff; - - if (dev->type == MOUSE_TYPE_INPORT) - shift = 0x07; - - if (!x && !y && !((b ^ dev->mouse_buttons_last) & shift)/* && (dev->type == MOUSE_TYPE_INPORT)*/) - return(1); /* State has not changed, do nothing. */ - - /* change button staste MRL to LMR */ - dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->bn == 3) - dev->mouse_buttons |= ((b & 4) >> 1); - - if (dev->type == MOUSE_TYPE_INPORT) { - /* InPort mouse. */ - - /* If the mouse has moved, set bit 6. */ - if (x || y) - dev->mouse_buttons |= 0x40; - - /* Set bits 3-5 according to button state changes. */ - if ((b ^ dev->mouse_buttons_last) & (1 << 0)) - dev->mouse_buttons |= (1 << 5); - if ((b ^ dev->mouse_buttons_last) & (1 << 4) && (dev->bn == 3)) - dev->mouse_buttons |= (1 << 4); - if ((b ^ dev->mouse_buttons_last) & (1 << 2)) - dev->mouse_buttons |= (1 << 3); - } - - dev->mouse_buttons_last = b; - - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) x = 127; - if (x < -128) x = -128; - - if (y > 127) y = 127; - if (y < -128) y = -128; - - if (dev->timer_enabled) { /* Timer interrupt mode. */ - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { /* Data interrupt mode. */ - /* If the counters are not frozen, update them. */ - if (!dev->hold) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; - - dev->current_b = dev->mouse_buttons; - } - - /* Send interrupt. */ - if (dev->data_int) { - picintc(1 << dev->irq); - picint(1 << dev->irq); - bm_log("DEBUG: Data Interrupt Fired...\n"); - } - } - return(0); -} - - -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } - - if (!dev->hold) { - dev->current_x = (uint8_t) delta_x; - dev->current_y = (uint8_t) delta_y; - dev->current_b = dev->mouse_buttons; - } -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->type == MOUSE_TYPE_INPORT) - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - else - dev->timer = BUSM_PERIOD; - - if (dev->interrupts) { - picintc(1 << dev->irq); - picint(1 << dev->irq); - bm_log("DEBUG: Timer Interrupt Fired...\n"); - } - - bm_update_data(dev); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev) - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - - dev->type = info->local; - dev->model = device_get_config_int("model"); - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bn = device_get_config_int("buttons"); - mouse_set_buttons(dev->bn); - - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; - dev->mouse_buttons = 0; - dev->current_x = - dev->current_y = - dev->current_b = 0; - - if (dev->type == MOUSE_TYPE_INPORT) { - dev->control_val = 0; /* the control port value */ - dev->mouse_buttons_last = 0; - dev->period = 0.0; /* 30 Hz default */ - dev->timer = 0LL; - dev->timer_enabled = 0; - } else { - dev->control_val = 0x0f; /* the control port value */ - dev->config_val = 0x0e; /* the config port value */ - dev->sig_val = 0; /* the signature port value */ - dev->timer = BUSM_PERIOD; - dev->timer_enabled = *TIMER_ALWAYS_ENABLED; - dev->interrupts = 1; - } - dev->data_int = 0; - dev->interrupts = 0; /* timer interrupts off */ - dev->command_val = 0; /* command byte */ - dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - dev->hold = 0; /* counter freeze */ - - timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - - if (dev->type == MOUSE_TYPE_INPORT) - bm_log("MS Inport BusMouse initialized\n"); - else - bm_log("Standard MS/Logitech BusMouse initialized\n"); - - return dev; -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_bus - Cópia (4).c b/src - Cópia/mouse_bus - Cópia (4).c deleted file mode 100644 index ad2f53bed..000000000 --- a/src - Cópia/mouse_bus - Cópia (4).c +++ /dev/null @@ -1,805 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. - * - * Logitech Bus Mouse verified with: - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 - * - * InPort verified with: - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE - * - * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 200?-2018 Bochs. - * Copyright 2017,2018 Miran Grca. - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" -#if 1 -#include "random.h" -#endif - -#define IRQ_MASK ((1 << 5) >> dev->irq) - -/* MS Inport Bus Mouse Adapter */ -#define INP_PORT_CONTROL 0x0000 -#define INP_PORT_DATA 0x0001 -#define INP_PORT_SIGNATURE 0x0002 -#define INP_PORT_CONFIG 0x0003 - -#define INP_CTRL_READ_BUTTONS 0x00 -#define INP_CTRL_READ_X 0x01 -#define INP_CTRL_READ_Y 0x02 -#define INP_CTRL_COMMAND 0x07 -#define INP_CTRL_RAISE_IRQ 0x16 -#define INP_CTRL_RESET 0x80 - -#define INP_HOLD_COUNTER (1 << 5) -#define INP_ENABLE_TIMER_IRQ (1 << 4) -#define INP_ENABLE_DATA_IRQ (1 << 3) -#define INP_PERIOD_MASK 0x07 - -/* MS/Logictech Standard Bus Mouse Adapter */ -#define BUSM_PORT_DATA 0x0000 -#define BUSM_PORT_SIGNATURE 0x0001 -#define BUSM_PORT_CONTROL 0x0002 -#define BUSM_PORT_CONFIG 0x0003 - -#define HOLD_COUNTER (1 << 7) -#define READ_X (0 << 6) -#define READ_Y (1 << 6) -#define READ_LOW (0 << 5) -#define READ_HIGH (1 << 5) -#define DISABLE_IRQ (1 << 4) - -#define DEVICE_ACTIVE (1 << 7) - -#define READ_X_LOW (READ_X | READ_LOW) -#define READ_X_HIGH (READ_X | READ_HIGH) -#define READ_Y_LOW (READ_Y | READ_LOW) -#define READ_Y_HIGH (READ_Y | READ_HIGH) - -#define FLAG_INPORT (1 << 0) -#define FLAG_NEW (1 << 1) -#define FLAG_ENABLED (1 << 2) -#define FLAG_HOLD (1 << 3) -#define FLAG_TIMER_INT (1 << 4) -#define FLAG_DATA_INT (1 << 5) - -static const double periods[4] = { 30.0, 50.0, 100.0, 200.0 }; - - -/* Our mouse device. */ -typedef struct mouse { - int base, irq, bn, flags, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, - current_x, current_y, - current_b, - control_val, mouse_buttons_last, - config_val, sig_val, - command_val, toggle_counter; - - double period; - - int64_t timer_enabled, timer; /* mouse event timer */ -} mouse_t; - - -#ifdef ENABLE_MOUSE_BUS_LOG -int bm_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -bm_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (bm_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -lt_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case BUSM_PORT_DATA: - /* Testing and another source confirm that the buttons are - *ALWAYS* present, so I'm going to change this a bit. */ - switch (dev->control_val & 0x60) { - case READ_X_LOW: - value = dev->current_x & 0x0F; - break; - case READ_X_HIGH: - value = (dev->current_x >> 4) & 0x0F; - break; - case READ_Y_LOW: - value = dev->current_y & 0x0F; - break; - case READ_Y_HIGH: - value = (dev->current_y >> 4) & 0x0F; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - value |= ((dev->current_b ^ 7) << 5); - break; - case BUSM_PORT_SIGNATURE: - value = dev->sig_val; - break; - case BUSM_PORT_CONTROL: - value = dev->control_val; - dev->control_val |= 0x0F; - - /* If the conditions are right, simulate the flakiness of the correct IRQ bit. */ - if (!(dev->flags & FLAG_NEW) || (dev->flags & FLAG_TIMER_INT)) - dev->control_val = (dev->control_val & ~IRQ_MASK) | (random_generate() & IRQ_MASK); - break; - case BUSM_PORT_CONFIG: - /* Read from config port returns control_val in the upper 4 bits when enabled, - possibly solid interrupt readout in the lower 4 bits, 0xff when not (at power-up). */ - if (dev->flags & FLAG_ENABLED) - return (dev->control_val | 0x0F) & ~IRQ_MASK; - else - return 0xff; - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -static uint8_t -ms_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case INP_PORT_CONTROL: - value = dev->control_val; - break; - case INP_PORT_DATA: - switch (dev->command_val) { - case INP_CTRL_READ_BUTTONS: - value = dev->current_b | 0x80; - break; - case INP_CTRL_READ_X: - value = dev->current_x; - break; - case INP_CTRL_READ_Y: - value = dev->current_y; - break; - case INP_CTRL_COMMAND: - value = dev->control_val; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - break; - case INP_PORT_SIGNATURE: - if (dev->toggle_counter) - value = 0x12; - else - value = 0xDE; - dev->toggle_counter ^= 1; - break; - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported read from port 0x%04x\n", port); - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -lt_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case BUSM_PORT_DATA: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - case BUSM_PORT_SIGNATURE: - dev->sig_val = val; - break; - case BUSM_PORT_CONTROL: - dev->control_val = val | 0x0F; - - if (!(val & DISABLE_IRQ)) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - picintc(1 << dev->irq); - - break; - case BUSM_PORT_CONFIG: - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->config_val = val; - if (val & DEVICE_ACTIVE) { - dev->flags |= FLAG_ENABLED; - dev->control_val = 0x0F & ~IRQ_MASK; - } else - dev->flags &= ~FLAG_ENABLED; - break; - } -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -ms_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case INP_PORT_CONTROL: - /* Bit 7 is reset. */ - if (val & INP_CTRL_RESET) - dev->control_val = 0; - - /* Bits 0-2 are the internal register index. */ - switch(val & 0x07) { - case INP_CTRL_COMMAND: - case INP_CTRL_READ_BUTTONS: - case INP_CTRL_READ_X: - case INP_CTRL_READ_Y: - dev->command_val = val & 0x07; - break; - default: - bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_DATA: - picintc(1 << dev->irq); - switch(dev->command_val) { - case INP_CTRL_COMMAND: - if (val & INP_HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - if (val & INP_ENABLE_TIMER_IRQ) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & INP_ENABLE_DATA_IRQ) - dev->flags |= FLAG_DATA_INT; - else - dev->flags &= ~FLAG_DATA_INT; - - switch(val & INP_PERIOD_MASK) { - case 0: - dev->period = 0.0; - dev->timer = 0LL; - dev->timer_enabled = 0LL; - break; - - case 1: - case 2: - case 3: - case 4: - dev->period = 1000000.0 / periods[(val & INP_PERIOD_MASK) - 1]; - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? 1LL : 0LL; - bm_log("DEBUG: Timer is now %sabled at period %i\n", (val & INP_ENABLE_TIMER_IRQ) ? "en" : "dis", (int32_t) dev->period); - break; - - case 6: - if (val & INP_ENABLE_TIMER_IRQ) - picint(1 << dev->irq); - dev->control_val &= INP_PERIOD_MASK; - dev->control_val |= (val & ~INP_PERIOD_MASK); - return; - default: - bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); - } - - dev->control_val = val; - - break; - default: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_SIGNATURE: - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - int xor; - - if (!(dev->flags & FLAG_ENABLED)) - return(1); /* Mouse is disabled, do nothing. */ - - if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) { - dev->mouse_buttons_last = b; - return(1); /* State has not changed, do nothing. */ - } - - /* Converts button states from MRL to LMR. */ - dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->bn == 3) - dev->mouse_buttons |= ((b & 4) >> 1); - - if ((dev->flags & FLAG_INPORT) && !dev->timer_enabled) { - /* This is an InPort mouse in data interrupt mode, - so update bits 6-3 here. */ - - /* If the mouse has moved, set bit 6. */ - if (x || y) - dev->mouse_buttons |= 0x40; - - /* Set bits 3-5 according to button state changes. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->mouse_buttons |= xor; - } - - dev->mouse_buttons_last = b; - - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) x = 127; - if (x < -128) x = -128; - - if (y > 127) y = 127; - if (y < -128) y = -128; - - if (dev->timer_enabled) { - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; - - dev->current_b = dev->mouse_buttons; - } - - /* Send interrupt. */ - if (dev->flags & FLAG_DATA_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Data Interrupt Fired...\n"); - } - } - return(0); -} - - -/* The timer calls us on every tick if the mouse is in timer mode - (InPort mouse is so configured, MS/Logitech Bus mouse always). */ -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - int xor; - - /* Update the deltas and the delays. */ - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } - - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (uint8_t) delta_x; - dev->current_y = (uint8_t) delta_y; - } - - if (dev->flags & FLAG_INPORT) { - /* This is an InPort mouse in timer mode, so update current_b always, - and update bits 6-3 (mouse moved and button state changed) here. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->current_b = (dev->mouse_buttons & 0x87) | xor; - if (delta_x || delta_y) - dev->current_b |= 0x40; - } else if (!(dev->flags & FLAG_HOLD)) { - /* This is a MS/Logitech Bus Mouse, so only update current_b if the - counters are frozen. */ - dev->current_b = dev->mouse_buttons; - } -} - - -/* Called at the configured period (InPort mouse) or 45 times per second (MS/Logitech Bus mouse). */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: Timer Tick (flags=%08X)...\n", dev->flags); - - /* The period is configured either via emulator settings (for MS/Logitech Bus mouse) - or via software (for InPort mouse). */ - dev->timer += ((int64_t) dev->period) * TIMER_USEC; - - if (dev->flags & FLAG_TIMER_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Timer Interrupt Fired...\n"); - } - - bm_update_data(dev); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev) - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - - if (info->local == MOUSE_TYPE_INPORT) - dev->flags = FLAG_INPORT; - else - dev->flags = 0; - - if (device_get_config_int("model")) - dev->flags |= FLAG_NEW; - - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bn = device_get_config_int("buttons"); - mouse_set_buttons(dev->bn); - - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; - dev->mouse_buttons = 0; - dev->mouse_buttons_last = 0; - dev->sig_val = 0; /* the signature port value */ - dev->current_x = - dev->current_y = - dev->current_b = 0; - dev->command_val = 0; /* command byte */ - dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - - if (dev->flags & FLAG_INPORT) { - dev->control_val = 0; /* the control port value */ - dev->timer = 0LL; - dev->timer_enabled = 0; - dev->flags |= FLAG_ENABLED; - dev->period = 0.0; - - io_sethandler(dev->base, 4, - ms_read, NULL, NULL, ms_write, NULL, NULL, dev); - } else { - dev->control_val = 0x0f; /* the control port value */ - dev->config_val = 0x0e; /* the config port value */ - dev->period = 1000000.0 / ((double) device_get_config_int("hz")); - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = 1LL; - dev->flags |= FLAG_TIMER_INT; - - io_sethandler(dev->base, 4, - lt_read, NULL, NULL, lt_write, NULL, NULL, dev); - } - - timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - - if (dev->flags & FLAG_INPORT) - bm_log("MS Inport BusMouse initialized\n"); - else - bm_log("Standard MS/Logitech BusMouse initialized\n"); - - return dev; -} - - -static const device_config_t lt_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "hz", "Hz", CONFIG_SELECTION, "", 30, { - { - "30 Hz (JMP2 = 1)", 30 - }, - { - "45 Hz (JMP2 not populated)", 45 - }, - { - "60 Hz (JMP 2 = 2)", 60 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_config_t ms_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - lt_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - ms_config -}; diff --git a/src - Cópia/mouse_bus - Cópia 2.c b/src - Cópia/mouse_bus - Cópia 2.c deleted file mode 100644 index f2fd8ab99..000000000 --- a/src - Cópia/mouse_bus - Cópia 2.c +++ /dev/null @@ -1,877 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.37 2018/05/22 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint8_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - /* Bits 0-2 are the internal register index. */ - switch (val) { - case MSCTRL_RESET: - // ms_reset(dev); - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - break; - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val; - break; - case 0x87: - // ms_reset(dev); - dev->r_ctrl = 0x00; - dev->r_cmd = 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - /* dev->x = dev->y = 0; - dev->but = 0; */ - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = 0x0f; - if (!(dev->r_ctrl & LTCTRL_IDIS) && (dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - ret &= ~0x08; - break; - - case 3: - ret &= ~0x04; - break; - - case 4: - ret &= ~0x02; - break; - - case 5: - ret &= ~0x01; - break; - } - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->irq = device_get_config_int("irq"); - dev->base = device_get_config_hex16("base"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_bus - Cópia.c b/src - Cópia/mouse_bus - Cópia.c deleted file mode 100644 index f13bcfd37..000000000 --- a/src - Cópia/mouse_bus - Cópia.c +++ /dev/null @@ -1,794 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.34 2018/04/29 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - int8_t irq; /* IRQ channel to use */ - uint8_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint8_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t need_upd; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -// # define MAGIC_MSBYTE2 0x12 -# define MAGIC_MSBYTE2 0x22 /* According to the Bochs code, this sould be 0x22, not 0x12. */ -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - dev->need_upd = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if ((dev->x_delay == 0) && (dev->y_delay == 0)) - dev->need_upd = 0; - - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - switch (port) { - case MSMOUSE_CTRL: - switch (val) { - case MSCTRL_RESET: - ms_reset(dev); - break; - - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_ctrl = val & 0x07; - break; - - case 0x87: - ms_reset(dev); - dev->r_ctrl = MSCTRL_COMMAND; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - if (val == MSDATA_IRQ) { - picint(1<irq); - } else switch (dev->r_ctrl) { - case MSCTRL_COMMAND: - if (val & MSCTRL_FREEZE) { - /* Hold the sampling. */ - ms_update_data(dev); - } else { - /* Reset current state. */ - picintc(1 << dev->irq); - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_cmd = val; - break; - - default: - break; - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_ctrl) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_cmd; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - if ((dev->flags & FLAG_INTR) && dev->need_upd) { - picint(1 << dev->irq); - mouse_bus_log("IRQ %i raised\n", dev->irq); - } - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = 0x0f; - if (!(dev->r_ctrl & LTCTRL_IDIS) && (dev->seq++ == 0)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - ret &= ~0x08; - break; - - case 3: - ret &= ~0x04; - break; - - case 4: - ret &= ~0x02; - break; - - case 5: - ret &= ~0x01; - break; - } - } - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port-MOUSE_PORT, val); - - dev->write(dev, port-MOUSE_PORT, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port-MOUSE_PORT); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port-MOUSE_PORT, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but = (uint8_t)(0x40 | ((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - dev->need_upd = 1; - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(MOUSE_PORT, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d\n", - dev->name, MOUSE_PORT, dev->irq, i); - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(MOUSE_PORT, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_bus.c b/src - Cópia/mouse_bus.c deleted file mode 100644 index 7f14b3aeb..000000000 --- a/src - Cópia/mouse_bus.c +++ /dev/null @@ -1,789 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. - * - * Logitech Bus Mouse verified with: - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 - * - * InPort verified with: - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE - * - * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 200?-2018 Bochs. - * Copyright 2017,2018 Miran Grca. - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" -#include "random.h" - -#define IRQ_MASK ((1 << 5) >> dev->irq) - -/* MS Inport Bus Mouse Adapter */ -#define INP_PORT_CONTROL 0x0000 -#define INP_PORT_DATA 0x0001 -#define INP_PORT_SIGNATURE 0x0002 -#define INP_PORT_CONFIG 0x0003 - -#define INP_CTRL_READ_BUTTONS 0x00 -#define INP_CTRL_READ_X 0x01 -#define INP_CTRL_READ_Y 0x02 -#define INP_CTRL_COMMAND 0x07 -#define INP_CTRL_RAISE_IRQ 0x16 -#define INP_CTRL_RESET 0x80 - -#define INP_HOLD_COUNTER (1 << 5) -#define INP_ENABLE_TIMER_IRQ (1 << 4) -#define INP_ENABLE_DATA_IRQ (1 << 3) -#define INP_PERIOD_MASK 0x07 - -/* MS/Logictech Standard Bus Mouse Adapter */ -#define BUSM_PORT_DATA 0x0000 -#define BUSM_PORT_SIGNATURE 0x0001 -#define BUSM_PORT_CONTROL 0x0002 -#define BUSM_PORT_CONFIG 0x0003 - -#define HOLD_COUNTER (1 << 7) -#define READ_X (0 << 6) -#define READ_Y (1 << 6) -#define READ_LOW (0 << 5) -#define READ_HIGH (1 << 5) -#define DISABLE_IRQ (1 << 4) - -#define DEVICE_ACTIVE (1 << 7) - -#define READ_X_LOW (READ_X | READ_LOW) -#define READ_X_HIGH (READ_X | READ_HIGH) -#define READ_Y_LOW (READ_Y | READ_LOW) -#define READ_Y_HIGH (READ_Y | READ_HIGH) - -#define FLAG_INPORT (1 << 0) -#define FLAG_ENABLED (1 << 1) -#define FLAG_HOLD (1 << 2) -#define FLAG_TIMER_INT (1 << 3) -#define FLAG_DATA_INT (1 << 4) - -static const double periods[4] = { 30.0, 50.0, 100.0, 200.0 }; - - -/* Our mouse device. */ -typedef struct mouse { - int base, irq, bn, flags, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, - current_x, current_y, - current_b, - control_val, mouse_buttons_last, - config_val, sig_val, - command_val, toggle_counter; - - double period; - - int64_t timer_enabled, timer; /* mouse event timer */ -} mouse_t; - - -#ifdef ENABLE_MOUSE_BUS_LOG -int bm_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -bm_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (bm_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -lt_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case BUSM_PORT_DATA: - /* Testing and another source confirm that the buttons are - *ALWAYS* present, so I'm going to change this a bit. */ - switch (dev->control_val & 0x60) { - case READ_X_LOW: - value = dev->current_x & 0x0F; - break; - case READ_X_HIGH: - value = (dev->current_x >> 4) & 0x0F; - break; - case READ_Y_LOW: - value = dev->current_y & 0x0F; - break; - case READ_Y_HIGH: - value = (dev->current_y >> 4) & 0x0F; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - value |= ((dev->current_b ^ 7) << 5); - break; - case BUSM_PORT_SIGNATURE: - value = dev->sig_val; - break; - case BUSM_PORT_CONTROL: - value = dev->control_val; - dev->control_val |= 0x0F; - - /* If the conditions are right, simulate the flakiness of the correct IRQ bit. */ - if (dev->flags & FLAG_TIMER_INT) - dev->control_val = (dev->control_val & ~IRQ_MASK) | (random_generate() & IRQ_MASK); - break; - case BUSM_PORT_CONFIG: - /* Read from config port returns control_val in the upper 4 bits when enabled, - possibly solid interrupt readout in the lower 4 bits, 0xff when not (at power-up). */ - if (dev->flags & FLAG_ENABLED) - return (dev->control_val | 0x0F) & ~IRQ_MASK; - else - return 0xff; - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -static uint8_t -ms_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case INP_PORT_CONTROL: - value = dev->control_val; - break; - case INP_PORT_DATA: - switch (dev->command_val) { - case INP_CTRL_READ_BUTTONS: - value = dev->current_b | 0x80; - break; - case INP_CTRL_READ_X: - value = dev->current_x; - break; - case INP_CTRL_READ_Y: - value = dev->current_y; - break; - case INP_CTRL_COMMAND: - value = dev->control_val; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - break; - case INP_PORT_SIGNATURE: - if (dev->toggle_counter) - value = 0x12; - else - value = 0xDE; - dev->toggle_counter ^= 1; - break; - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported read from port 0x%04x\n", port); - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -lt_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case BUSM_PORT_DATA: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - case BUSM_PORT_SIGNATURE: - dev->sig_val = val; - break; - case BUSM_PORT_CONTROL: - dev->control_val = val | 0x0F; - - if (!(val & DISABLE_IRQ)) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - picintc(1 << dev->irq); - - break; - case BUSM_PORT_CONFIG: - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->config_val = val; - if (val & DEVICE_ACTIVE) { - dev->flags |= (FLAG_ENABLED | FLAG_TIMER_INT); - dev->control_val = 0x0F & ~IRQ_MASK; - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = 1LL; - } else { - dev->flags &= ~(FLAG_ENABLED | FLAG_TIMER_INT); - dev->timer = 0LL; - dev->timer_enabled = 0LL; - } - break; - } -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -ms_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case INP_PORT_CONTROL: - /* Bit 7 is reset. */ - if (val & INP_CTRL_RESET) - dev->control_val = 0; - - /* Bits 0-2 are the internal register index. */ - switch(val & 0x07) { - case INP_CTRL_COMMAND: - case INP_CTRL_READ_BUTTONS: - case INP_CTRL_READ_X: - case INP_CTRL_READ_Y: - dev->command_val = val & 0x07; - break; - default: - bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_DATA: - picintc(1 << dev->irq); - switch(dev->command_val) { - case INP_CTRL_COMMAND: - if (val & INP_HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - if (val & INP_ENABLE_TIMER_IRQ) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & INP_ENABLE_DATA_IRQ) - dev->flags |= FLAG_DATA_INT; - else - dev->flags &= ~FLAG_DATA_INT; - - switch(val & INP_PERIOD_MASK) { - case 0: - dev->period = 0.0; - dev->timer = 0LL; - dev->timer_enabled = 0LL; - break; - - case 1: - case 2: - case 3: - case 4: - dev->period = 1000000.0 / periods[(val & INP_PERIOD_MASK) - 1]; - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? 1LL : 0LL; - bm_log("DEBUG: Timer is now %sabled at period %i\n", (val & INP_ENABLE_TIMER_IRQ) ? "en" : "dis", (int32_t) dev->period); - break; - - case 6: - if (val & INP_ENABLE_TIMER_IRQ) - picint(1 << dev->irq); - dev->control_val &= INP_PERIOD_MASK; - dev->control_val |= (val & ~INP_PERIOD_MASK); - return; - default: - bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); - } - - dev->control_val = val; - - break; - default: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_SIGNATURE: - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - int xor; - - if (!(dev->flags & FLAG_ENABLED)) - return(1); /* Mouse is disabled, do nothing. */ - - if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) { - dev->mouse_buttons_last = b; - return(1); /* State has not changed, do nothing. */ - } - - /* Converts button states from MRL to LMR. */ - dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->bn == 3) - dev->mouse_buttons |= ((b & 4) >> 1); - - if ((dev->flags & FLAG_INPORT) && !dev->timer_enabled) { - /* This is an InPort mouse in data interrupt mode, - so update bits 6-3 here. */ - - /* If the mouse has moved, set bit 6. */ - if (x || y) - dev->mouse_buttons |= 0x40; - - /* Set bits 3-5 according to button state changes. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->mouse_buttons |= xor; - } - - dev->mouse_buttons_last = b; - - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) x = 127; - if (x < -128) x = -128; - - if (y > 127) y = 127; - if (y < -128) y = -128; - - if (dev->timer_enabled) { - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; - - dev->current_b = dev->mouse_buttons; - } - - /* Send interrupt. */ - if (dev->flags & FLAG_DATA_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Data Interrupt Fired...\n"); - } - } - return(0); -} - - -/* The timer calls us on every tick if the mouse is in timer mode - (InPort mouse is so configured, MS/Logitech Bus mouse always). */ -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - int xor; - - /* Update the deltas and the delays. */ - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } - - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (uint8_t) delta_x; - dev->current_y = (uint8_t) delta_y; - } - - if (dev->flags & FLAG_INPORT) { - /* This is an InPort mouse in timer mode, so update current_b always, - and update bits 6-3 (mouse moved and button state changed) here. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->current_b = (dev->mouse_buttons & 0x87) | xor; - if (delta_x || delta_y) - dev->current_b |= 0x40; - } else if (!(dev->flags & FLAG_HOLD)) { - /* This is a MS/Logitech Bus Mouse, so only update current_b if the - counters are frozen. */ - dev->current_b = dev->mouse_buttons; - } -} - - -/* Called at the configured period (InPort mouse) or 45 times per second (MS/Logitech Bus mouse). */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: Timer Tick (flags=%08X)...\n", dev->flags); - - /* The period is configured either via emulator settings (for MS/Logitech Bus mouse) - or via software (for InPort mouse). */ - dev->timer += ((int64_t) dev->period) * TIMER_USEC; - - if (dev->flags & FLAG_TIMER_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Timer Interrupt Fired...\n"); - } - - bm_update_data(dev); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev) - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - - if (info->local == MOUSE_TYPE_INPORT) - dev->flags = FLAG_INPORT; - else - dev->flags = 0; - - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bn = device_get_config_int("buttons"); - mouse_set_buttons(dev->bn); - - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; - dev->mouse_buttons = 0; - dev->mouse_buttons_last = 0; - dev->sig_val = 0; /* the signature port value */ - dev->current_x = - dev->current_y = - dev->current_b = 0; - dev->command_val = 0; /* command byte */ - dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - - if (dev->flags & FLAG_INPORT) { - dev->control_val = 0; /* the control port value */ - dev->flags |= FLAG_ENABLED; - dev->period = 0.0; - - io_sethandler(dev->base, 4, - ms_read, NULL, NULL, ms_write, NULL, NULL, dev); - } else { - dev->control_val = 0x0f; /* the control port value */ - dev->config_val = 0x0e; /* the config port value */ - dev->period = 1000000.0 / ((double) device_get_config_int("hz")); - - io_sethandler(dev->base, 4, - lt_read, NULL, NULL, lt_write, NULL, NULL, dev); - } - - dev->timer = 0LL; - dev->timer_enabled = 0LL; - - timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - - if (dev->flags & FLAG_INPORT) - bm_log("MS Inport BusMouse initialized\n"); - else - bm_log("Standard MS/Logitech BusMouse initialized\n"); - - return dev; -} - - -static const device_config_t lt_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "hz", "Hz", CONFIG_SELECTION, "", 45, { - { - "30 Hz (JMP2 = 1)", 30 - }, - { - "45 Hz (JMP2 not populated)", 45 - }, - { - "60 Hz (JMP 2 = 2)", 60 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_config_t ms_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - lt_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - ms_config -}; diff --git a/src - Cópia/mouse_bus_good.c b/src - Cópia/mouse_bus_good.c deleted file mode 100644 index 1f592646e..000000000 --- a/src - Cópia/mouse_bus_good.c +++ /dev/null @@ -1,879 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.38 2018/05/23 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - // dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ -#if 0 - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } -#endif - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - if (val & LTCTRL_FREEZE) { - mouse_bus_log("Freeze: Raise IRQ %i\n", dev->irq); - picint(1 << dev->irq); /* Microsoft MOUSE.SYS v3.0 seems to expect every freeze to send an IRQ? */ - } else { - mouse_bus_log("No freeze: Lower IRQ %i\n", dev->irq); - picintc(1 << dev->irq); - } - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - dev->r_ctrl &= ~0x08; - break; - - case 3: - dev->r_ctrl &= ~0x04; - break; - - case 4: - dev->r_ctrl &= ~0x02; - break; - - case 5: - dev->r_ctrl &= ~0x01; - break; - } - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - // dev->timer = 0; - // timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_bus_x.c b/src - Cópia/mouse_bus_x.c deleted file mode 100644 index 62fae5e53..000000000 --- a/src - Cópia/mouse_bus_x.c +++ /dev/null @@ -1,795 +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. - * - * Implementation of Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.39 2018/05/24 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_ctrl = (LTCTRL_IENB) | 0x0f; - dev->r_conf = 0x0e; - dev->r_magic = 0x00; - - dev->seq = 0; - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - else - dev->timer = ((1000000LL * TIMER_USEC) / 200LL); - - bm_update_data(dev); - - if (dev->flags & FLAG_INTR) { - picint(1 << dev->irq); - mouse_bus_log("Mouse IRQ %i\n", dev->irq); - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - dev->r_magic = val; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->cur_but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->cur_but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->cur_but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) - dev->r_ctrl &= ~((1 << 5) >> dev->irq); - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - } else - dev->but = 0x00; - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - - /* Change button state MRL to LMR */ - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if (dev->flags & FLAG_INPORT) { - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = ((1000000LL * TIMER_USEC) / 200LL); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/src - Cópia/mouse_ps2.c b/src - Cópia/mouse_ps2.c deleted file mode 100644 index a20e49d3e..000000000 --- a/src - Cópia/mouse_ps2.c +++ /dev/null @@ -1,319 +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. - * - * Implementation of PS/2 series Mouse devices. - * - * Version: @(#)mouse_ps2.c 1.0.9 2018/05/12 - * - * Authors: Fred N. van Kempen, - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "device.h" -#include "keyboard.h" -#include "mouse.h" - - -enum { - MODE_STREAM, - MODE_REMOTE, - MODE_ECHO -}; - - -typedef struct { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - - int mode; - - uint8_t flags; - uint8_t resolution; - uint8_t sample_rate; - - uint8_t command; - - int x, y, z, b; - - uint8_t last_data[6]; -} mouse_t; -#define FLAG_INTELLI 0x80 /* device is IntelliMouse */ -#define FLAG_INTMODE 0x40 /* using Intellimouse mode */ -#define FLAG_SCALED 0x20 /* enable delta scaling */ -#define FLAG_ENABLED 0x10 /* dev is enabled for use */ -#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ - - -int mouse_scan = 0; - - -#ifdef ENABLE_MOUSE_PS2_LOG -int mouse_ps2_do_log = ENABLE_MOUSE_PS2_LOG; -#endif - - -static void -mouse_ps2_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_PS2_LOG - va_list ap; - - if (mouse_ps2_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static void -ps2_write(uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t temp; - - if (dev->flags & FLAG_CTRLDAT) { - dev->flags &= ~FLAG_CTRLDAT; - - switch (dev->command) { - case 0xe8: /* set mouse resolution */ - dev->resolution = val; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xf3: /* set sample rate */ - dev->sample_rate = val; - keyboard_at_adddata_mouse(0xfa); /* Command response */ - break; - - default: - keyboard_at_adddata_mouse(0xfc); - } - } else { - dev->command = val; - - switch (dev->command) { - case 0xe6: /* set scaling to 1:1 */ - dev->flags &= ~FLAG_SCALED; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xe7: /* set scaling to 2:1 */ - dev->flags |= FLAG_SCALED; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xe8: /* set mouse resolution */ - dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xe9: /* status request */ - keyboard_at_adddata_mouse(0xfa); - temp = (dev->flags & 0x3f); - if (mouse_buttons & 0x01) - temp |= 0x01; - if (mouse_buttons & 0x02) - temp |= 0x02; - if (mouse_buttons & 0x04) - temp |= 0x03; - keyboard_at_adddata_mouse(temp); - keyboard_at_adddata_mouse(dev->resolution); - keyboard_at_adddata_mouse(dev->sample_rate); - break; - - case 0xf2: /* read ID */ - keyboard_at_adddata_mouse(0xfa); - if (dev->flags & FLAG_INTMODE) - keyboard_at_adddata_mouse(0x03); - else - keyboard_at_adddata_mouse(0x00); - break; - - case 0xf3: /* set command mode */ - dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse(0xfa); /* ACK for command byte */ - break; - - case 0xf4: /* enable */ - dev->flags |= FLAG_ENABLED; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xf5: /* disable */ - dev->flags &= ~FLAG_ENABLED; - keyboard_at_adddata_mouse(0xfa); - break; - - case 0xff: /* reset */ - dev->mode = MODE_STREAM; - dev->flags &= 0x80; - keyboard_at_adddata_mouse(0xfa); - keyboard_at_adddata_mouse(0xaa); - keyboard_at_adddata_mouse(0x00); - break; - - default: - keyboard_at_adddata_mouse(0xfe); - } - } - - if (dev->flags & FLAG_INTELLI) { - for (temp=0; temp<5; temp++) - dev->last_data[temp] = dev->last_data[temp+1]; - dev->last_data[5] = val; - - if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 && - dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 && - dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) - dev->flags |= FLAG_INTMODE; - } -} - - -static int -ps2_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t buff[3]; - - if (!x && !y && !z && b == dev->b) return(0xff); - - if (! (dev->flags & FLAG_ENABLED)) return(0xff); - - if (! mouse_scan) return(0xff); - - dev->x += x; - dev->y -= y; - dev->z -= z; - if ((dev->mode == MODE_STREAM) && - ((mouse_queue_end-mouse_queue_start) & 0x0f) < 13) { - dev->b = b; - - if (dev->x > 255) dev->x = 255; - if (dev->x < -256) dev->x = -256; - if (dev->y > 255) dev->y = 255; - if (dev->y < -256) dev->y = -256; - if (dev->z < -8) dev->z = -8; - if (dev->z > 7) dev->z = 7; - - memset(buff, 0x00, sizeof(buff)); - buff[0] = 0x08; - if (dev->x < 0) - buff[0] |= 0x10; - if (dev->y < 0) - buff[0] |= 0x20; - if (mouse_buttons & 0x01) - buff[0] |= 0x01; - if (mouse_buttons & 0x02) - buff[0] |= 0x02; - if (dev->flags & FLAG_INTELLI) { - if (mouse_buttons & 0x04) - buff[0] |= 0x04; - } - buff[1] = (dev->x & 0xff); - buff[2] = (dev->y & 0xff); - - keyboard_at_adddata_mouse(buff[0]); - keyboard_at_adddata_mouse(buff[1]); - keyboard_at_adddata_mouse(buff[2]); - if (dev->flags & FLAG_INTELLI) - keyboard_at_adddata_mouse(dev->z); - - dev->x = dev->y = dev->z = 0; - } - - return(0); -} - - -/* - * Initialize the device for use by the user. - * - * We also get called from the various machines. - */ -void * -mouse_ps2_init(const device_t *info) -{ - mouse_t *dev; - int i; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - - dev->mode = MODE_STREAM; - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_INTELLI; - - /* Hook into the general AT Keyboard driver. */ - keyboard_at_set_mouse(ps2_write, dev); - - mouse_ps2_log("%s: buttons=%d\n", dev->name, (dev->flags & FLAG_INTELLI)? 3 : 2); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_INTELLI) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static void -ps2_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Unhook from the general AT Keyboard driver. */ - keyboard_at_set_mouse(NULL, NULL); - - free(dev); -} - - -static const device_config_t ps2_config[] = { - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "Wheel", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_ps2_device = { - "Standard PS/2 Mouse", - 0, - MOUSE_TYPE_PS2, - mouse_ps2_init, ps2_close, NULL, - ps2_poll, NULL, NULL, - ps2_config -}; diff --git a/src - Cópia/mouse_serial.c b/src - Cópia/mouse_serial.c deleted file mode 100644 index cb338a0c5..000000000 --- a/src - Cópia/mouse_serial.c +++ /dev/null @@ -1,324 +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. - * - * Implementation of Serial Mouse devices. - * - * TODO: Add the Genius Serial Mouse. - * - * Version: @(#)mouse_serial.c 1.0.23 2018/04/29 - * - * Author: Fred N. van Kempen, - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "device.h" -#include "timer.h" -#include "serial.h" -#include "mouse.h" - - -#define SERMOUSE_PORT 0 /* attach to Serial0 */ - - -typedef struct { - const char *name; /* name of this device */ - int8_t type, /* type of this device */ - port; - uint8_t flags; /* device flags */ - - int pos; - int64_t delay; - int oldb; - - SERIAL *serial; -} mouse_t; -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -#ifdef ENABLE_MOUSE_SERIAL_LOG -int mouse_serial_do_log = ENABLE_MOUSE_SERIAL_LOG; -#endif - - -static void -mouse_serial_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_SERIAL_LOG - va_list ap; - - if (mouse_serial_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Callback from serial driver: RTS was toggled. */ -static void -sermouse_callback(struct SERIAL *serial, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Start a timer to wake us up in a little while. */ - dev->pos = -1; - serial_clear_fifo((SERIAL *) serial); - dev->delay = 5000LL * (1LL << TIMER_SHIFT); -} - - -/* Callback timer expired, now send our "mouse ID" to the serial port. */ -static void -sermouse_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - dev->delay = 0LL; - - if (dev->pos != -1) return; - - dev->pos = 0; - switch(dev->type) { - case MOUSE_TYPE_MSYSTEMS: - /* Identifies Mouse Systems serial mouse. */ - serial_write_fifo(dev->serial, 'H'); - break; - - case MOUSE_TYPE_MICROSOFT: - /* Identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(dev->serial, 'M'); - break; - - case MOUSE_TYPE_LOGITECH: - /* Identifies a two-button Logitech Serial mouse. */ - serial_write_fifo(dev->serial, 'M'); - serial_write_fifo(dev->serial, '3'); - break; - - case MOUSE_TYPE_MSWHEEL: - /* Identifies multi-button Microsoft Wheel Mouse. */ - serial_write_fifo(dev->serial, 'M'); - serial_write_fifo(dev->serial, 'Z'); - break; - - default: - mouse_serial_log("%s: unsupported mouse type %d?\n", dev->type); - } -} - - -static int -sermouse_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t buff[16]; - int len; - - if (!x && !y && b == dev->oldb) return(1); - -#if 0 - mouse_serial_log("%s: poll(%d,%d,%d,%02x)\n", dev->name, x, y, z, b); -#endif - - dev->oldb = b; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x <- 128) x = -128; - if (y <- 128) y = -128; - - len = 0; - switch(dev->type) { - case MOUSE_TYPE_MSYSTEMS: - buff[0] = 0x80; - buff[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */ - buff[0] |= (b & 0x02) ? 0x00 : 0x01; /* middle button */ - buff[0] |= (b & 0x04) ? 0x00 : 0x02; /* right button */ - buff[1] = x; - buff[2] = -y; - buff[3] = x; /* same as byte 1 */ - buff[4] = -y; /* same as byte 2 */ - len = 5; - break; - - case MOUSE_TYPE_MICROSOFT: - case MOUSE_TYPE_LOGITECH: - case MOUSE_TYPE_MSWHEEL: - buff[0] = 0x40; - buff[0] |= (((y >> 6) & 0x03) << 2); - buff[0] |= ((x >> 6) & 0x03); - if (b & 0x01) buff[0] |= 0x20; - if (b & 0x02) buff[0] |= 0x10; - buff[1] = x & 0x3F; - buff[2] = y & 0x3F; - if (dev->type == MOUSE_TYPE_LOGITECH) { - len = 3; - if (b & 0x04) { - buff[3] = 0x20; - len++; - } - } else if (dev->type == MOUSE_TYPE_MSWHEEL) { - len = 4; - buff[3] = z & 0x0F; - if (b & 0x04) - buff[3] |= 0x10; - } else - len = 3; - break; - } - -#if 0 - mouse_serial_log("%s: [", dev->name); - for (b=0; bserial != NULL) { - for (b=0; bserial, buff[b]); - } - - return(0); -} - - -static void -sermouse_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Detach serial port from the mouse. */ - if ((dev != NULL) && (dev->serial != NULL)) { - dev->serial->rcr_callback = NULL; - dev->serial->rcr_callback_p = NULL; - } - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -sermouse_init(const device_t *info) -{ - mouse_t *dev; - int i; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - - if (info->local == MOUSE_TYPE_MSYSTEMS) - dev->type = info->local; - else { - switch(i) { - case 2: - default: - dev->type = MOUSE_TYPE_MICROSOFT; - break; - case 3: - dev->type = MOUSE_TYPE_LOGITECH; - break; - case 4: - dev->type = MOUSE_TYPE_MSWHEEL; - break; - } - } - - dev->port = device_get_config_int("port"); - - /* Attach a serial port to the mouse. */ - if (dev->port == 0) - dev->serial = &serial1; - else - dev->serial = &serial2; - dev->serial->rcr_callback = sermouse_callback; - dev->serial->rcr_callback_p = dev; - - mouse_serial_log("%s: port=COM%d\n", dev->name, dev->port+1); - - timer_add(sermouse_timer, &dev->delay, &dev->delay, dev); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t sermouse_config[] = { - { - "port", "Serial Port", CONFIG_SELECTION, "", 0, { - { - "COM1", 0 - }, - { - "COM2", 1 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "Wheel", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_mssystems_device = { - "Mouse Systems Serial Mouse", - 0, - MOUSE_TYPE_MSYSTEMS, - sermouse_init, sermouse_close, NULL, - sermouse_poll, NULL, NULL, - sermouse_config -}; - -const device_t mouse_msserial_device = { - "Microsoft/Logitech Serial Mouse", - 0, - 0, - sermouse_init, sermouse_close, NULL, - sermouse_poll, NULL, NULL, - sermouse_config -}; diff --git a/src - Cópia/network/bswap.h b/src - Cópia/network/bswap.h deleted file mode 100644 index 75311d39b..000000000 --- a/src - Cópia/network/bswap.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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. - * - * Various definitions for portable byte-swapping. - * - * Version: @(#)bswap.h 1.0.2 2018/03/12 - * - * Authors: Fred N. van Kempen, - * neozeed, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 neozeed. - * - * 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 BSWAP_H -#define BSWAP_H - -#include - -#ifdef HAVE_BYTESWAP_H -#include -#else -# define bswap_16(x) \ - ( \ - ((uint16_t)( \ - (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \ - ) - -# define bswap_32(x) \ - ( \ - ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \ - ) - -# define bswap_64(x) \ - ( \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \ - ) -#endif /*HAVE_BYTESWAP_H*/ - -static __inline uint16_t bswap16(uint16_t x) -{ - return bswap_16(x); -} - -static __inline uint32_t bswap32(uint32_t x) -{ - return bswap_32(x); -} - -static __inline uint64_t bswap64(uint64_t x) -{ - return bswap_64(x); -} - -static __inline void bswap16s(uint16_t *s) -{ - *s = bswap16(*s); -} - -static __inline void bswap32s(uint32_t *s) -{ - *s = bswap32(*s); -} - -static __inline void bswap64s(uint64_t *s) -{ - *s = bswap64(*s); -} - -#if defined(WORDS_BIGENDIAN) -# define be_bswap(v, size) (v) -# define le_bswap(v, size) bswap ## size(v) -# define be_bswaps(v, size) -# define le_bswaps(p, size) *p = bswap ## size(*p); -#else -# define le_bswap(v, size) (v) -# define be_bswap(v, size) bswap ## size(v) -# define le_bswaps(v, size) -# define be_bswaps(p, size) *p = bswap ## size(*p); -#endif - -#define CPU_CONVERT(endian, size, type)\ -static __inline type endian ## size ## _to_cpu(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline type cpu_to_ ## endian ## size(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline void endian ## size ## _to_cpus(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## s(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline type endian ## size ## _to_cpup(const type *p)\ -{\ - return endian ## size ## _to_cpu(*p);\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ -{\ - *p = cpu_to_ ## endian ## size(v);\ -} - -CPU_CONVERT(be, 16, uint16_t) -CPU_CONVERT(be, 32, uint32_t) -CPU_CONVERT(be, 64, uint64_t) - -CPU_CONVERT(le, 16, uint16_t) -CPU_CONVERT(le, 32, uint32_t) -CPU_CONVERT(le, 64, uint64_t) - -/* unaligned versions (optimized for frequent unaligned accesses)*/ - -#if defined(__i386__) || defined(__powerpc__) - -#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) -#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) -#define le16_to_cpupu(p) le16_to_cpup(p) -#define le32_to_cpupu(p) le32_to_cpup(p) - -#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) -#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) - -#else - -static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v) -{ - uint8_t *p1 = (uint8_t *)p; - - p1[0] = v & 0xff; - p1[1] = v >> 8; -} - -static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) -{ - uint8_t *p1 = (uint8_t *)p; - - p1[0] = v; - p1[1] = v >> 8; - p1[2] = v >> 16; - p1[3] = v >> 24; -} - -static __inline uint16_t le16_to_cpupu(const uint16_t *p) -{ - const uint8_t *p1 = (const uint8_t *)p; - return p1[0] | (p1[1] << 8); -} - -static __inline uint32_t le32_to_cpupu(const uint32_t *p) -{ - const uint8_t *p1 = (const uint8_t *)p; - return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24); -} - -static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v) -{ - uint8_t *p1 = (uint8_t *)p; - - p1[0] = v >> 8; - p1[1] = v & 0xff; -} - -static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) -{ - uint8_t *p1 = (uint8_t *)p; - - p1[0] = v >> 24; - p1[1] = v >> 16; - p1[2] = v >> 8; - p1[3] = v; -} - -#endif - -#ifdef WORDS_BIGENDIAN -#define cpu_to_32wu cpu_to_be32wu -#else -#define cpu_to_32wu cpu_to_le32wu -#endif - -#undef le_bswap -#undef be_bswap -#undef le_bswaps -#undef be_bswaps - -#endif /* BSWAP_H */ diff --git a/src - Cópia/network/net_ne2000.c b/src - Cópia/network/net_ne2000.c deleted file mode 100644 index ea446743b..000000000 --- a/src - Cópia/network/net_ne2000.c +++ /dev/null @@ -1,2846 +0,0 @@ -/* - * 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. - * - * Implementation of the following network controllers: - * - Novell NE1000 (ISA 8-bit); - * - Novell NE2000 (ISA 16-bit); - * - Realtek RTL8019AS (ISA 16-bit, PnP); - * - Realtek RTL8029AS (PCI). - * - * Version: @(#)net_ne2000.c 1.0.4 2018/04/26 - * - * Based on @(#)ne2k.cc v1.56.2.1 2004/02/02 22:37:22 cbothamy - * - * Authors: Fred N. van Kempen, - * TheCollector1995, - * Miran Grca, - * Peter Grehan, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Portions Copyright (C) 2002 MandrakeSoft S.A. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" -#include "../ui.h" -#include "network.h" -#include "net_ne2000.h" -#include "bswap.h" - - -enum { - PNP_PHASE_WAIT_FOR_KEY = 0, - PNP_PHASE_CONFIG, - PNP_PHASE_ISOLATION, - PNP_PHASE_SLEEP -}; - - -/* ROM BIOS file paths. */ -#define ROM_PATH_NE1000 L"roms/network/ne1000/ne1000.rom" -#define ROM_PATH_NE2000 L"roms/network/ne2000/ne2000.rom" -#define ROM_PATH_RTL8019 L"roms/network/rtl8019as/rtl8019as.rom" -#define ROM_PATH_RTL8029 L"roms/network/rtl8029as/rtl8029as.rom" - -/* PCI info. */ -#define PNP_VENDID 0x4a8c /* Realtek, Inc */ -#define PCI_VENDID 0x10ec /* Realtek, Inc */ -#define PNP_DEVID 0x8019 /* RTL8029AS */ -#define PCI_DEVID 0x8029 /* RTL8029AS */ -#define PCI_REGSIZE 256 /* size of PCI space */ - - -/* Never completely fill the ne2k ring so that we never - hit the unclear completely full buffer condition. */ -#define NE2K_NEVER_FULL_RING (1) - -#define NE2K_MEMSIZ (32*1024) -#define NE2K_MEMSTART (16*1024) -#define NE2K_MEMEND (NE2K_MEMSTART+NE2K_MEMSIZ) - -#define NE1K_MEMSIZ (16*1024) -#define NE1K_MEMSTART (8*1024) -#define NE1K_MEMEND (NE1K_MEMSTART+NE1K_MEMSIZ) - -uint8_t pnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, - 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61, - 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, - 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39 }; - - -typedef struct { - /* Page 0 */ - - /* Command Register - 00h read/write */ - struct CR_t { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ - uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ - uint8_t pgsel; /* PS0,PS1 - Page select */ - } CR; - - /* Interrupt Status Register - 07h read/write */ - struct ISR_t { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet txed with no errors */ - int rx_err; /* RXE - packet rxed with 1 or more errors */ - int tx_err; /* TXE - packet txed " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ - } ISR; - - /* Interrupt Mask Register - 0fh write */ - struct IMR_t { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ - } IMR; - - /* Data Configuration Register - 0eh write */ - struct DCR_t { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ - uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ - } DCR; - - /* Transmit Configuration Register - 0dh write */ - struct TCR_t { - int crc_disable; /* CRC - inhibit tx CRC */ - uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ - uint8_t reserved; /* D5,D6,D7 - reserved */ - } TCR; - - /* Transmit Status Register - 04h read */ - struct TSR_t { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ - } TSR; - - /* Receive Configuration Register - 0ch write */ - struct RCR_t { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ - uint8_t reserved; /* D6,D7 - reserved */ - } RCR; - - /* Receive Status Register - 0ch read */ - struct RSR_t { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ - } RSR; - - uint16_t local_dma; /* 01,02h read ; current local DMA addr */ - uint8_t page_start; /* 01h write ; page start regr */ - uint8_t page_stop; /* 02h write ; page stop regr */ - uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ - uint8_t tx_page_start; /* 04h write ; transmit page start reg */ - uint8_t num_coll; /* 05h read ; number-of-collisions reg */ - uint16_t tx_bytes; /* 05,06h write ; transmit byte-count reg */ - uint8_t fifo; /* 06h read ; FIFO */ - uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ - uint16_t remote_start; /* 08,09h write ; remote start address reg */ - uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count reg */ - uint8_t tallycnt_0; /* 0dh read ; tally ctr 0 (frame align errs) */ - uint8_t tallycnt_1; /* 0eh read ; tally ctr 1 (CRC errors) */ - uint8_t tallycnt_2; /* 0fh read ; tally ctr 2 (missed pkt errs) */ - - /* Page 1 */ - - /* Command Register 00h (repeated) */ - - uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ - uint8_t curr_page; /* 07h read/write ; current page register */ - uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ - - /* Page 2 - diagnostic use only */ - - /* Command Register 00h (repeated) */ - - /* Page Start Register 01h read (repeated) - * Page Stop Register 02h read (repeated) - * Current Local DMA Address 01,02h write (repeated) - * Transmit Page start address 04h read (repeated) - * Receive Configuration Register 0ch read (repeated) - * Transmit Configuration Register 0dh read (repeated) - * Data Configuration Register 0eh read (repeated) - * Interrupt Mask Register 0fh read (repeated) - */ - uint8_t rempkt_ptr; /* 03h read/write ; rmt next-pkt ptr */ - uint8_t localpkt_ptr; /* 05h read/write ; lcl next-pkt ptr */ - uint16_t address_cnt; /* 06,07h read/write ; address cter */ - - /* Page 3 - should never be modified. */ - - /* Novell ASIC state */ - uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ - uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ - - int board; - int is_pci, is_8bit; - const char *name; - uint32_t base_address; - int base_irq; - uint32_t bios_addr, - bios_size, - bios_mask; - uint8_t pnp_regs[256]; - uint8_t pnp_res_data[256]; - bar_t pci_bar[2]; - uint8_t pci_regs[PCI_REGSIZE]; - int tx_timer_index; - int tx_timer_active; - uint8_t maclocal[6]; /* configured MAC (local) address */ - uint8_t eeprom[128]; /* for RTL8029AS */ - rom_t bios_rom; - int card; /* PCI card slot */ - int has_bios; - uint8_t pnp_phase; - uint8_t pnp_magic_count; - uint8_t pnp_address; - uint8_t pnp_res_pos; - uint8_t pnp_csn; - uint8_t pnp_activate; - uint8_t pnp_io_check; - uint8_t pnp_csnsav; - uint16_t pnp_read; - uint64_t pnp_id; - uint8_t pnp_id_checksum; - uint8_t pnp_serial_read_pos; - uint8_t pnp_serial_read_pair; - uint8_t pnp_serial_read; - - /* RTL8019AS/RTL8029AS registers */ - uint8_t config0, config2, config3; - uint8_t _9346cr; -} nic_t; - - -static void nic_rx(void *, uint8_t *, int); -static void nic_tx(nic_t *, uint32_t); - - -static void -nelog(int lvl, const char *fmt, ...) -{ -#ifdef ENABLE_NIC_LOG - va_list ap; - - if (nic_do_log >= lvl) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -nic_interrupt(nic_t *dev, int set) -{ - if (PCI && dev->is_pci) { - if (set) - pci_set_irq(dev->card, PCI_INTA); - else - pci_clear_irq(dev->card, PCI_INTA); - } else { - if (set) - picint(1<base_irq); - else - picintc(1<base_irq); - } -} - - -/* reset - restore state to power-up, cancelling all i/o */ -static void -nic_reset(void *priv) -{ - nic_t *dev = (nic_t *)priv; - int i; - - nelog(1, "%s: reset\n", dev->name); - - if (dev->board >= NE2K_NE2000) { - /* Initialize the MAC address area by doubling the physical address */ - dev->macaddr[0] = dev->physaddr[0]; - dev->macaddr[1] = dev->physaddr[0]; - dev->macaddr[2] = dev->physaddr[1]; - dev->macaddr[3] = dev->physaddr[1]; - dev->macaddr[4] = dev->physaddr[2]; - dev->macaddr[5] = dev->physaddr[2]; - dev->macaddr[6] = dev->physaddr[3]; - dev->macaddr[7] = dev->physaddr[3]; - dev->macaddr[8] = dev->physaddr[4]; - dev->macaddr[9] = dev->physaddr[4]; - dev->macaddr[10] = dev->physaddr[5]; - dev->macaddr[11] = dev->physaddr[5]; - - /* ne2k signature */ - for (i=12; i<32; i++) - dev->macaddr[i] = 0x57; - } else { - /* Initialize the MAC address area by doubling the physical address */ - dev->macaddr[0] = dev->physaddr[0]; - dev->macaddr[1] = dev->physaddr[1]; - dev->macaddr[2] = dev->physaddr[2]; - dev->macaddr[3] = dev->physaddr[3]; - dev->macaddr[4] = dev->physaddr[4]; - dev->macaddr[5] = dev->physaddr[5]; - - /* ne1k signature */ - for (i=6; i<16; i++) - dev->macaddr[i] = 0x57; - } - - /* Zero out registers and memory */ - memset(&dev->CR, 0x00, sizeof(dev->CR) ); - memset(&dev->ISR, 0x00, sizeof(dev->ISR)); - memset(&dev->IMR, 0x00, sizeof(dev->IMR)); - memset(&dev->DCR, 0x00, sizeof(dev->DCR)); - memset(&dev->TCR, 0x00, sizeof(dev->TCR)); - memset(&dev->TSR, 0x00, sizeof(dev->TSR)); - memset(&dev->RSR, 0x00, sizeof(dev->RSR)); - dev->tx_timer_active = 0; - dev->local_dma = 0; - dev->page_start = 0; - dev->page_stop = 0; - dev->bound_ptr = 0; - dev->tx_page_start = 0; - dev->num_coll = 0; - dev->tx_bytes = 0; - dev->fifo = 0; - dev->remote_dma = 0; - dev->remote_start = 0; - dev->remote_bytes = 0; - dev->tallycnt_0 = 0; - dev->tallycnt_1 = 0; - dev->tallycnt_2 = 0; - - dev->curr_page = 0; - - dev->rempkt_ptr = 0; - dev->localpkt_ptr = 0; - dev->address_cnt = 0; - - memset(&dev->mem, 0x00, sizeof(dev->mem)); - - /* Set power-up conditions */ - dev->CR.stop = 1; - dev->CR.rdma_cmd = 4; - dev->ISR.reset = 1; - dev->DCR.longaddr = 1; - - nic_interrupt(dev, 0); -} - - -static void -nic_soft_reset(void *priv) -{ - nic_t *dev = (nic_t *)priv; - - memset(&(dev->ISR), 0x00, sizeof(dev->ISR)); - dev->ISR.reset = 1; -} - - -/* - * Access the 32K private RAM. - * - * The NE2000 memory is accessed through the data port of the - * ASIC (offset 0) after setting up a remote-DMA transfer. - * Both byte and word accesses are allowed. - * The first 16 bytes contains the MAC address at even locations, - * and there is 16K of buffer memory starting at 16K. - */ -static uint32_t -chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) -{ - uint32_t retval = 0; - - if ((len == 2) && (addr & 0x1)) { - nelog(3, "%s: unaligned chipmem word read\n", dev->name); - } - - /* ROM'd MAC address */ - if (dev->board >= NE2K_NE2000) { - if (addr <= 31) { - retval = dev->macaddr[addr % 32]; - if ((len == 2) || (len == 4)) { - retval |= (dev->macaddr[(addr + 1) % 32] << 8); - } - if (len == 4) { - retval |= (dev->macaddr[(addr + 2) % 32] << 16); - retval |= (dev->macaddr[(addr + 3) % 32] << 24); - } - return(retval); - } - - if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { - retval = dev->mem[addr - NE2K_MEMSTART]; - if ((len == 2) || (len == 4)) { - retval |= (dev->mem[addr - NE2K_MEMSTART + 1] << 8); - } - if (len == 4) { - retval |= (dev->mem[addr - NE2K_MEMSTART + 2] << 16); - retval |= (dev->mem[addr - NE2K_MEMSTART + 3] << 24); - } - return(retval); - } - } else { - if (addr <= 15) { - retval = dev->macaddr[addr % 16]; - if (len == 2) { - retval |= (dev->macaddr[(addr + 1) % 16] << 8); - } - return(retval); - } - - if ((addr >= NE1K_MEMSTART) && (addr < NE1K_MEMEND)) { - retval = dev->mem[addr - NE1K_MEMSTART]; - if (len == 2) { - retval |= (dev->mem[addr - NE1K_MEMSTART + 1] << 8); - } - return(retval); - } - } - - nelog(3, "%s: out-of-bounds chipmem read, %04X\n", dev->name, addr); - - if (dev->is_pci) { - return(0xff); - } else { - switch(len) { - case 1: - return(0xff); - case 2: - return(0xffff); - } - } - - return(0xffff); -} - - -static void -chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) -{ - if ((len == 2) && (addr & 0x1)) { - nelog(3, "%s: unaligned chipmem word write\n", dev->name); - } - - if (dev->board >= NE2K_NE2000) { - if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { - dev->mem[addr-NE2K_MEMSTART] = val & 0xff; - if ((len == 2) || (len == 4)) { - dev->mem[addr-NE2K_MEMSTART+1] = val >> 8; - } - if (len == 4) { - dev->mem[addr-NE2K_MEMSTART+2] = val >> 16; - dev->mem[addr-NE2K_MEMSTART+3] = val >> 24; - } - } else { - nelog(3, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); - } - } else { - if ((addr >= NE1K_MEMSTART) && (addr < NE1K_MEMEND)) { - dev->mem[addr-NE1K_MEMSTART] = val & 0xff; - if (len == 2) { - dev->mem[addr-NE1K_MEMSTART+1] = val >> 8; - } - } else { - nelog(3, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); - } - } -} - - -/* - * Access the ASIC I/O space. - * - * This is the high 16 bytes of i/o space (the lower 16 bytes - * is for the DS8390). Only two locations are used: offset 0, - * which is used for data transfer, and offset 0x0f, which is - * used to reset the device. - * - * The data transfer port is used to as 'external' DMA to the - * DS8390. The chip has to have the DMA registers set up, and - * after that, insw/outsw instructions can be used to move - * the appropriate number of bytes to/from the device. - */ -static uint32_t -asic_read(nic_t *dev, uint32_t off, unsigned int len) -{ - uint32_t retval = 0; - - switch(off) { - case 0x00: /* Data register */ - /* A read remote-DMA command must have been issued, - and the source-address and length registers must - have been initialised. */ - if (len > dev->remote_bytes) { - nelog(3, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", - dev->name, len, dev->remote_bytes); - } - - nelog(3, "%s: DMA read: addr=%4x remote_bytes=%d\n", - dev->name, dev->remote_dma,dev->remote_bytes); - retval = chipmem_read(dev, dev->remote_dma, len); - - /* The 8390 bumps the address and decreases the byte count - by the selected word size after every access, not by - the amount of data requested by the host (io_len). */ - if (len == 4) { - dev->remote_dma += len; - } else { - dev->remote_dma += (dev->DCR.wdsize + 1); - } - - if (dev->remote_dma == dev->page_stop << 8) { - dev->remote_dma = dev->page_start << 8; - } - - /* keep s.remote_bytes from underflowing */ - if (dev->remote_bytes > dev->DCR.wdsize) { - if (len == 4) { - dev->remote_bytes -= len; - } else { - dev->remote_bytes -= (dev->DCR.wdsize + 1); - } - } else { - dev->remote_bytes = 0; - } - - /* If all bytes have been written, signal remote-DMA complete */ - if (dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) - nic_interrupt(dev, 1); - } - break; - - case 0x0f: /* Reset register */ - nic_soft_reset(dev); - break; - - default: - nelog(3, "%s: ASIC read invalid address %04x\n", - dev->name, (unsigned)off); - break; - } - - return(retval); -} - - -static void -asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) -{ - nelog(3, "%s: ASIC write addr=0x%02x, value=0x%04x\n", - dev->name, (unsigned)off, (unsigned) val); - - switch(off) { - case 0x00: /* Data register - see asic_read for a description */ - if ((len > 1) && (dev->DCR.wdsize == 0)) { - nelog(3, "%s: DMA write length %d on byte mode operation\n", - dev->name, len); - break; - } - if (dev->remote_bytes == 0) - nelog(3, "%s: DMA write, byte count 0\n", dev->name); - - chipmem_write(dev, dev->remote_dma, val, len); - if (len == 4) - dev->remote_dma += len; - else - dev->remote_dma += (dev->DCR.wdsize + 1); - - if (dev->remote_dma == dev->page_stop << 8) - dev->remote_dma = dev->page_start << 8; - - if (len == 4) - dev->remote_bytes -= len; - else - dev->remote_bytes -= (dev->DCR.wdsize + 1); - - if (dev->remote_bytes > NE2K_MEMSIZ) - dev->remote_bytes = 0; - - /* If all bytes have been written, signal remote-DMA complete */ - if (dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) - nic_interrupt(dev, 1); - } - break; - - case 0x0f: /* Reset register */ - /* end of reset pulse */ - break; - - default: /* this is invalid, but happens under win95 device detection */ - nelog(3, "%s: ASIC write invalid address %04x, ignoring\n", - dev->name, (unsigned)off); - break; - } -} - - -/* Handle reads/writes to the 'zeroth' page of the DS8390 register file. */ -static uint32_t -page0_read(nic_t *dev, uint32_t off, unsigned int len) -{ - uint8_t retval = 0; - - if (len > 1) { - /* encountered with win98 hardware probe */ - nelog(3, "%s: bad length! Page0 read from register 0x%02x, len=%u\n", - dev->name, off, len); - return(retval); - } - - switch(off) { - case 0x01: /* CLDA0 */ - retval = (dev->local_dma & 0xff); - break; - - case 0x02: /* CLDA1 */ - retval = (dev->local_dma >> 8); - break; - - case 0x03: /* BNRY */ - retval = dev->bound_ptr; - break; - - case 0x04: /* TSR */ - retval = ((dev->TSR.ow_coll << 7) | - (dev->TSR.cd_hbeat << 6) | - (dev->TSR.fifo_ur << 5) | - (dev->TSR.no_carrier << 4) | - (dev->TSR.aborted << 3) | - (dev->TSR.collided << 2) | - (dev->TSR.tx_ok)); - break; - - case 0x05: /* NCR */ - retval = dev->num_coll; - break; - - case 0x06: /* FIFO */ - /* reading FIFO is only valid in loopback mode */ - nelog(3, "%s: reading FIFO not supported yet\n", dev->name); - retval = dev->fifo; - break; - - case 0x07: /* ISR */ - retval = ((dev->ISR.reset << 7) | - (dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); - break; - - case 0x08: /* CRDA0 */ - retval = (dev->remote_dma & 0xff); - break; - - case 0x09: /* CRDA1 */ - retval = (dev->remote_dma >> 8); - break; - - case 0x0a: /* reserved / RTL8029ID0 */ - if (dev->board == NE2K_RTL8019AS) { - retval = 0x50; - } else if (dev->board == NE2K_RTL8029AS) { - retval = 0x50; - } else { - nelog(3, "%s: reserved Page0 read - 0x0a\n", dev->name); - retval = 0xff; - } - break; - - case 0x0b: /* reserved / RTL8029ID1 */ - if (dev->board == NE2K_RTL8019AS) { - retval = 0x70; - } else if (dev->board == NE2K_RTL8029AS) { - retval = 0x43; - } else { - nelog(3, "%s: reserved Page0 read - 0x0b\n", dev->name); - retval = 0xff; - } - break; - - case 0x0c: /* RSR */ - retval = ((dev->RSR.deferred << 7) | - (dev->RSR.rx_disabled << 6) | - (dev->RSR.rx_mbit << 5) | - (dev->RSR.rx_missed << 4) | - (dev->RSR.fifo_or << 3) | - (dev->RSR.bad_falign << 2) | - (dev->RSR.bad_crc << 1) | - (dev->RSR.rx_ok)); - break; - - case 0x0d: /* CNTR0 */ - retval = dev->tallycnt_0; - break; - - case 0x0e: /* CNTR1 */ - retval = dev->tallycnt_1; - break; - - case 0x0f: /* CNTR2 */ - retval = dev->tallycnt_2; - break; - - default: - nelog(3, "%s: Page0 register 0x%02x out of range\n", - dev->name, off); - break; - } - - nelog(3, "%s: Page0 read from register 0x%02x, value=0x%02x\n", - dev->name, off, retval); - - return(retval); -} - - -static void -page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) -{ - uint8_t val2; - - /* It appears to be a common practice to use outw on page0 regs... */ - - /* break up outw into two outb's */ - if (len == 2) { - page0_write(dev, off, (val & 0xff), 1); - if (off < 0x0f) - page0_write(dev, off+1, ((val>>8)&0xff), 1); - return; - } - - nelog(3, "%s: Page0 write to register 0x%02x, value=0x%02x\n", - dev->name, off, val); - - switch(off) { - case 0x01: /* PSTART */ - dev->page_start = val; - break; - - case 0x02: /* PSTOP */ - dev->page_stop = val; - break; - - case 0x03: /* BNRY */ - dev->bound_ptr = val; - break; - - case 0x04: /* TPSR */ - dev->tx_page_start = val; - break; - - case 0x05: /* TBCR0 */ - /* Clear out low byte and re-insert */ - dev->tx_bytes &= 0xff00; - dev->tx_bytes |= (val & 0xff); - break; - - case 0x06: /* TBCR1 */ - /* Clear out high byte and re-insert */ - dev->tx_bytes &= 0x00ff; - dev->tx_bytes |= ((val & 0xff) << 8); - break; - - case 0x07: /* ISR */ - val &= 0x7f; /* clear RST bit - status-only bit */ - /* All other values are cleared iff the ISR bit is 1 */ - dev->ISR.pkt_rx &= !((int)((val & 0x01) == 0x01)); - dev->ISR.pkt_tx &= !((int)((val & 0x02) == 0x02)); - dev->ISR.rx_err &= !((int)((val & 0x04) == 0x04)); - dev->ISR.tx_err &= !((int)((val & 0x08) == 0x08)); - dev->ISR.overwrite &= !((int)((val & 0x10) == 0x10)); - dev->ISR.cnt_oflow &= !((int)((val & 0x20) == 0x20)); - dev->ISR.rdma_done &= !((int)((val & 0x40) == 0x40)); - val = ((dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); - val &= ((dev->IMR.rdma_inte << 6) | - (dev->IMR.cofl_inte << 5) | - (dev->IMR.overw_inte << 4) | - (dev->IMR.txerr_inte << 3) | - (dev->IMR.rxerr_inte << 2) | - (dev->IMR.tx_inte << 1) | - (dev->IMR.rx_inte)); - if (val == 0x00) - nic_interrupt(dev, 0); - break; - - case 0x08: /* RSAR0 */ - /* Clear out low byte and re-insert */ - dev->remote_start &= 0xff00; - dev->remote_start |= (val & 0xff); - dev->remote_dma = dev->remote_start; - break; - - case 0x09: /* RSAR1 */ - /* Clear out high byte and re-insert */ - dev->remote_start &= 0x00ff; - dev->remote_start |= ((val & 0xff) << 8); - dev->remote_dma = dev->remote_start; - break; - - case 0x0a: /* RBCR0 */ - /* Clear out low byte and re-insert */ - dev->remote_bytes &= 0xff00; - dev->remote_bytes |= (val & 0xff); - break; - - case 0x0b: /* RBCR1 */ - /* Clear out high byte and re-insert */ - dev->remote_bytes &= 0x00ff; - dev->remote_bytes |= ((val & 0xff) << 8); - break; - - case 0x0c: /* RCR */ - /* Check if the reserved bits are set */ - if (val & 0xc0) { - nelog(3, "%s: RCR write, reserved bits set\n", - dev->name); - } - - /* Set all other bit-fields */ - dev->RCR.errors_ok = ((val & 0x01) == 0x01); - dev->RCR.runts_ok = ((val & 0x02) == 0x02); - dev->RCR.broadcast = ((val & 0x04) == 0x04); - dev->RCR.multicast = ((val & 0x08) == 0x08); - dev->RCR.promisc = ((val & 0x10) == 0x10); - dev->RCR.monitor = ((val & 0x20) == 0x20); - - /* Monitor bit is a little suspicious... */ - if (val & 0x20) nelog(3, "%s: RCR write, monitor bit set!\n", - dev->name); - break; - - case 0x0d: /* TCR */ - /* Check reserved bits */ - if (val & 0xe0) nelog(3, "%s: TCR write, reserved bits set\n", - dev->name); - - /* Test loop mode (not supported) */ - if (val & 0x06) { - dev->TCR.loop_cntl = (val & 0x6) >> 1; - nelog(3, "%s: TCR write, loop mode %d not supported\n", - dev->name, dev->TCR.loop_cntl); - } else { - dev->TCR.loop_cntl = 0; - } - - /* Inhibit-CRC not supported. */ - if (val & 0x01) nelog(3, - "%s: TCR write, inhibit-CRC not supported\n",dev->name); - - /* Auto-transmit disable very suspicious */ - if (val & 0x08) nelog(3, - "%s: TCR write, auto transmit disable not supported\n", - dev->name); - - /* Allow collision-offset to be set, although not used */ - dev->TCR.coll_prio = ((val & 0x08) == 0x08); - break; - - case 0x0e: /* DCR */ - /* the loopback mode is not suppported yet */ - if (! (val & 0x08)) nelog(3, - "%s: DCR write, loopback mode selected\n", dev->name); - - /* It is questionable to set longaddr and auto_rx, since - * they are not supported on the NE2000. Print a warning - * and continue. */ - if (val & 0x04) - nelog(3, "%s: DCR write - LAS set ???\n", dev->name); - if (val & 0x10) - nelog(3, "%s: DCR write - AR set ???\n", dev->name); - - /* Set other values. */ - dev->DCR.wdsize = ((val & 0x01) == 0x01); - dev->DCR.endian = ((val & 0x02) == 0x02); - dev->DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ - dev->DCR.loop = ((val & 0x08) == 0x08); - dev->DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ - dev->DCR.fifo_size = (val & 0x50) >> 5; - break; - - case 0x0f: /* IMR */ - /* Check for reserved bit */ - if (val & 0x80) - nelog(3, "%s: IMR write, reserved bit set\n",dev->name); - - /* Set other values */ - dev->IMR.rx_inte = ((val & 0x01) == 0x01); - dev->IMR.tx_inte = ((val & 0x02) == 0x02); - dev->IMR.rxerr_inte = ((val & 0x04) == 0x04); - dev->IMR.txerr_inte = ((val & 0x08) == 0x08); - dev->IMR.overw_inte = ((val & 0x10) == 0x10); - dev->IMR.cofl_inte = ((val & 0x20) == 0x20); - dev->IMR.rdma_inte = ((val & 0x40) == 0x40); - val2 = ((dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); - if (((val & val2) & 0x7f) == 0) - nic_interrupt(dev, 0); - else - nic_interrupt(dev, 1); - break; - - default: - nelog(3, "%s: Page0 write, bad register 0x%02x\n", - dev->name, off); - break; - } -} - - -/* Handle reads/writes to the first page of the DS8390 register file. */ -static uint32_t -page1_read(nic_t *dev, uint32_t off, unsigned int len) -{ - nelog(3, "%s: Page1 read from register 0x%02x, len=%u\n", - dev->name, off, len); - - switch(off) { - case 0x01: /* PAR0-5 */ - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - return(dev->physaddr[off - 1]); - - case 0x07: /* CURR */ - nelog(3, "%s: returning current page: 0x%02x\n", - dev->name, (dev->curr_page)); - return(dev->curr_page); - - case 0x08: /* MAR0-7 */ - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - return(dev->mchash[off - 8]); - - default: - nelog(3, "%s: Page1 read register 0x%02x out of range\n", - dev->name, off); - return(0); - } -} - - -static void -page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) -{ - nelog(3, "%s: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", - dev->name, off, len, val); - - switch(off) { - case 0x01: /* PAR0-5 */ - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - dev->physaddr[off - 1] = val; - if (off == 6) nelog(3, - "%s: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, - dev->physaddr[0], dev->physaddr[1], - dev->physaddr[2], dev->physaddr[3], - dev->physaddr[4], dev->physaddr[5]); - break; - - case 0x07: /* CURR */ - dev->curr_page = val; - break; - - case 0x08: /* MAR0-7 */ - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - dev->mchash[off - 8] = val; - break; - - default: - nelog(3, "%s: Page1 write register 0x%02x out of range\n", - dev->name, off); - break; - } -} - - -/* Handle reads/writes to the second page of the DS8390 register file. */ -static uint32_t -page2_read(nic_t *dev, uint32_t off, unsigned int len) -{ - nelog(3, "%s: Page2 read from register 0x%02x, len=%u\n", - dev->name, off, len); - - switch(off) { - case 0x01: /* PSTART */ - return(dev->page_start); - - case 0x02: /* PSTOP */ - return(dev->page_stop); - - case 0x03: /* Remote Next-packet pointer */ - return(dev->rempkt_ptr); - - case 0x04: /* TPSR */ - return(dev->tx_page_start); - - case 0x05: /* Local Next-packet pointer */ - return(dev->localpkt_ptr); - - case 0x06: /* Address counter (upper) */ - return(dev->address_cnt >> 8); - - case 0x07: /* Address counter (lower) */ - return(dev->address_cnt & 0xff); - - case 0x08: /* Reserved */ - case 0x09: - case 0x0a: - case 0x0b: - nelog(3, "%s: reserved Page2 read - register 0x%02x\n", - dev->name, off); - return(0xff); - - case 0x0c: /* RCR */ - return ((dev->RCR.monitor << 5) | - (dev->RCR.promisc << 4) | - (dev->RCR.multicast << 3) | - (dev->RCR.broadcast << 2) | - (dev->RCR.runts_ok << 1) | - (dev->RCR.errors_ok)); - - case 0x0d: /* TCR */ - return ((dev->TCR.coll_prio << 4) | - (dev->TCR.ext_stoptx << 3) | - ((dev->TCR.loop_cntl & 0x3) << 1) | - (dev->TCR.crc_disable)); - - case 0x0e: /* DCR */ - return (((dev->DCR.fifo_size & 0x3) << 5) | - (dev->DCR.auto_rx << 4) | - (dev->DCR.loop << 3) | - (dev->DCR.longaddr << 2) | - (dev->DCR.endian << 1) | - (dev->DCR.wdsize)); - - case 0x0f: /* IMR */ - return ((dev->IMR.rdma_inte << 6) | - (dev->IMR.cofl_inte << 5) | - (dev->IMR.overw_inte << 4) | - (dev->IMR.txerr_inte << 3) | - (dev->IMR.rxerr_inte << 2) | - (dev->IMR.tx_inte << 1) | - (dev->IMR.rx_inte)); - - default: - nelog(3, "%s: Page2 register 0x%02x out of range\n", - dev->name, off); - break; - } - - return(0); -} - - -static void -page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) -{ -/* Maybe all writes here should be BX_PANIC()'d, since they - affect internal operation, but let them through for now - and print a warning. */ - nelog(3, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", - dev->name, off, len, val); - switch(off) { - case 0x01: /* CLDA0 */ - /* Clear out low byte and re-insert */ - dev->local_dma &= 0xff00; - dev->local_dma |= (val & 0xff); - break; - - case 0x02: /* CLDA1 */ - /* Clear out high byte and re-insert */ - dev->local_dma &= 0x00ff; - dev->local_dma |= ((val & 0xff) << 8); - break; - - case 0x03: /* Remote Next-pkt pointer */ - dev->rempkt_ptr = val; - break; - - case 0x04: - nelog(3, "page 2 write to reserved register 0x04\n"); - break; - - case 0x05: /* Local Next-packet pointer */ - dev->localpkt_ptr = val; - break; - - case 0x06: /* Address counter (upper) */ - /* Clear out high byte and re-insert */ - dev->address_cnt &= 0x00ff; - dev->address_cnt |= ((val & 0xff) << 8); - break; - - case 0x07: /* Address counter (lower) */ - /* Clear out low byte and re-insert */ - dev->address_cnt &= 0xff00; - dev->address_cnt |= (val & 0xff); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - nelog(3, "%s: Page2 write to reserved register 0x%02x\n", - dev->name, off); - break; - - default: - nelog(3, "%s: Page2 write, illegal register 0x%02x\n", - dev->name, off); - break; - } -} - - -/* Writes to this page are illegal. */ -static uint32_t -page3_read(nic_t *dev, uint32_t off, unsigned int len) -{ - if (dev->board >= NE2K_RTL8019AS) switch(off) { - case 0x1: /* 9346CR */ - return(dev->_9346cr); - - case 0x3: /* CONFIG0 */ - return(0x00); /* Cable not BNC */ - - case 0x5: /* CONFIG2 */ - return(dev->config2 & 0xe0); - - case 0x6: /* CONFIG3 */ - return(dev->config3 & 0x46); - - case 0x8: /* CSNSAV */ - return((dev->board == NE2K_RTL8019AS) ? dev->pnp_csnsav : 0x00); - - case 0xe: /* 8029ASID0 */ - return(0x29); - - case 0xf: /* 8029ASID1 */ - return(0x08); - - default: - break; - } - - nelog(3, "%s: Page3 read register 0x%02x attempted\n", dev->name, off); - return(0x00); -} - - -static void -page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) -{ - if (dev->board >= NE2K_RTL8019AS) { - nelog(3, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", - dev->name, off, len, val); - - switch(off) { - case 0x01: /* 9346CR */ - dev->_9346cr = (val & 0xfe); - break; - - case 0x05: /* CONFIG2 */ - dev->config2 = (val & 0xe0); - break; - - case 0x06: /* CONFIG3 */ - dev->config3 = (val & 0x46); - break; - - case 0x09: /* HLTCLK */ - break; - - default: - nelog(3, "%s: Page3 write to reserved register 0x%02x\n", - dev->name, off); - break; - } - } else - nelog(3, "%s: Page3 write register 0x%02x attempted\n", dev->name, off); -} - - -/* Routines for handling reads/writes to the Command Register. */ -static uint32_t -read_cr(nic_t *dev) -{ - uint32_t retval; - - retval = (((dev->CR.pgsel & 0x03) << 6) | - ((dev->CR.rdma_cmd & 0x07) << 3) | - (dev->CR.tx_packet << 2) | - (dev->CR.start << 1) | - (dev->CR.stop)); - nelog(3, "%s: read CR returns 0x%02x\n", dev->name, retval); - - return(retval); -} - - -static void -write_cr(nic_t *dev, uint32_t val) -{ - nelog(3, "%s: wrote 0x%02x to CR\n", dev->name, val); - - /* Validate remote-DMA */ - if ((val & 0x38) == 0x00) { - nelog(3, "%s: CR write - invalid rDMA value 0\n", dev->name); - val |= 0x20; /* dma_cmd == 4 is a safe default */ - } - - /* Check for s/w reset */ - if (val & 0x01) { - dev->ISR.reset = 1; - dev->CR.stop = 1; - } else { - dev->CR.stop = 0; - } - - dev->CR.rdma_cmd = (val & 0x38) >> 3; - - /* If start command issued, the RST bit in the ISR */ - /* must be cleared */ - if ((val & 0x02) && !dev->CR.start) - dev->ISR.reset = 0; - - dev->CR.start = ((val & 0x02) == 0x02); - dev->CR.pgsel = (val & 0xc0) >> 6; - - /* Check for send-packet command */ - if (dev->CR.rdma_cmd == 3) { - /* Set up DMA read from receive ring */ - dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; - dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); - nelog(3, "%s: sending buffer #x%x length %d\n", - dev->name, dev->remote_start, dev->remote_bytes); - } - - /* Check for start-tx */ - if ((val & 0x04) && dev->TCR.loop_cntl) { - if (dev->TCR.loop_cntl != 1) { - nelog(3, "%s: loop mode %d not supported\n", - dev->name, dev->TCR.loop_cntl); - } else { - if (dev->board >= NE2K_NE2000) { - nic_rx(dev, - &dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], - dev->tx_bytes); - } else { - nic_rx(dev, - &dev->mem[dev->tx_page_start*256 - NE1K_MEMSTART], - dev->tx_bytes); - } - } - } else if (val & 0x04) { - if (dev->CR.stop || (!dev->CR.start && (dev->board < NE2K_RTL8019AS))) { - if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { - return; /* Solaris9 probe */ - } - nelog(3, "%s: CR write - tx start, dev in reset\n", dev->name); - } - - if (dev->tx_bytes == 0) - nelog(3, "%s: CR write - tx start, tx bytes == 0\n", dev->name); - - /* Send the packet to the system driver */ - dev->CR.tx_packet = 1; - if (dev->board >= NE2K_NE2000) { - network_tx(&dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], - dev->tx_bytes); - } else { - network_tx(&dev->mem[dev->tx_page_start*256 - NE1K_MEMSTART], - dev->tx_bytes); - } - - /* some more debug */ - if (dev->tx_timer_active) - nelog(3, "%s: CR write, tx timer still active\n", dev->name); - - nic_tx(dev, val); - } - - /* Linux probes for an interrupt by setting up a remote-DMA read - * of 0 bytes with remote-DMA completion interrupts enabled. - * Detect this here */ - if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { - nic_interrupt(dev, 1); - if (! dev->is_pci) - nic_interrupt(dev, 0); - } - } -} - - -static uint32_t -nic_read(nic_t *dev, uint32_t addr, unsigned len) -{ - uint32_t retval = 0; - int off = addr - dev->base_address; - - nelog(3, "%s: read addr %x, len %d\n", dev->name, addr, len); - - if (off >= 0x10) { - retval = asic_read(dev, off - 0x10, len); - } else if (off == 0x00) { - retval = read_cr(dev); - } else switch(dev->CR.pgsel) { - case 0x00: - retval = page0_read(dev, off, len); - break; - - case 0x01: - retval = page1_read(dev, off, len); - break; - - case 0x02: - retval = page2_read(dev, off, len); - break; - - case 0x03: - retval = page3_read(dev, off, len); - break; - - default: - nelog(3, "%s: unknown value of pgsel in read - %d\n", - dev->name, dev->CR.pgsel); - break; - } - - return(retval); -} - - -static uint8_t -nic_readb(uint16_t addr, void *priv) -{ - return(nic_read((nic_t *)priv, addr, 1)); -} - - -static uint16_t -nic_readw(uint16_t addr, void *priv) -{ - nic_t *dev = (nic_t *)priv; - - if (dev->DCR.wdsize & 1) - return(nic_read(dev, addr, 2)); - else - return(nic_read(dev, addr, 1)); -} - - -static uint32_t -nic_readl(uint16_t addr, void *priv) -{ - return(nic_read((nic_t *)priv, addr, 4)); -} - - -static void -nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) -{ - int off = addr - dev->base_address; - - nelog(3, "%s: write addr %x, value %x len %d\n", dev->name, addr, val, len); - - /* The high 16 bytes of i/o space are for the ne2000 asic - - the low 16 bytes are for the DS8390, with the current - page being selected by the PS0,PS1 registers in the - command register */ - if (off >= 0x10) { - asic_write(dev, off - 0x10, val, len); - } else if (off == 0x00) { - write_cr(dev, val); - } else switch(dev->CR.pgsel) { - case 0x00: - page0_write(dev, off, val, len); - break; - - case 0x01: - page1_write(dev, off, val, len); - break; - - case 0x02: - page2_write(dev, off, val, len); - break; - - case 0x03: - page3_write(dev, off, val, len); - break; - - default: - nelog(3, "%s: unknown value of pgsel in write - %d\n", - dev->name, dev->CR.pgsel); - break; - } -} - - -static void -nic_writeb(uint16_t addr, uint8_t val, void *priv) -{ - nic_write((nic_t *)priv, addr, val, 1); -} - - -static void -nic_writew(uint16_t addr, uint16_t val, void *priv) -{ - nic_t *dev = (nic_t *)priv; - - if (dev->DCR.wdsize & 1) - nic_write(dev, addr, val, 2); - else - nic_write(dev, addr, val, 1); -} - - -static void -nic_writel(uint16_t addr, uint32_t val, void *priv) -{ - nic_write((nic_t *)priv, addr, val, 4); -} - - -static void nic_iocheckset(nic_t *dev, uint16_t addr); -static void nic_iocheckremove(nic_t *dev, uint16_t addr); -static void nic_ioset(nic_t *dev, uint16_t addr); -static void nic_ioremove(nic_t *dev, uint16_t addr); - - -static uint8_t -nic_pnp_io_check_readb(uint16_t addr, void *priv) -{ - nic_t *dev = (nic_t *) priv; - - return((dev->pnp_io_check & 0x01) ? 0x55 : 0xAA); -} - - -static uint8_t -nic_pnp_readb(uint16_t addr, void *priv) -{ - nic_t *dev = (nic_t *) priv; - uint8_t bit, next_shift; - uint8_t ret = 0xFF; - - /* Plug and Play Registers */ - switch(dev->pnp_address) { - /* Card Control Registers */ - case 0x01: /* Serial Isolation */ - if (dev->pnp_phase != PNP_PHASE_ISOLATION) { - ret = 0x00; - break; - } - if (dev->pnp_serial_read_pair) { - dev->pnp_serial_read <<= 1; - /* TODO: Support for multiple PnP devices. - if (pnp_get_bus_data() != dev->pnp_serial_read) - dev->pnp_phase = PNP_PHASE_SLEEP; - } else { - */ - if (!dev->pnp_serial_read_pos) { - dev->pnp_res_pos = 0x1B; - dev->pnp_phase = PNP_PHASE_CONFIG; - nelog(1, "\nASSIGN CSN phase\n"); - } - } else { - if (dev->pnp_serial_read_pos < 64) { - bit = (dev->pnp_id >> dev->pnp_serial_read_pos) & 0x01; - next_shift = (!!(dev->pnp_id_checksum & 0x02) ^ !!(dev->pnp_id_checksum & 0x01) ^ bit) & 0x01; - dev->pnp_id_checksum >>= 1; - dev->pnp_id_checksum |= (next_shift << 7); - } else { - if (dev->pnp_serial_read_pos == 64) - dev->eeprom[0x1A] = dev->pnp_id_checksum; - bit = (dev->pnp_id_checksum >> (dev->pnp_serial_read_pos & 0x07)) & 0x01; - } - dev->pnp_serial_read = bit ? 0x55 : 0x00; - dev->pnp_serial_read_pos = (dev->pnp_serial_read_pos + 1) % 72; - } - dev->pnp_serial_read_pair ^= 1; - ret = dev->pnp_serial_read; - break; - case 0x04: /* Resource Data */ - ret = dev->eeprom[dev->pnp_res_pos]; - dev->pnp_res_pos++; - break; - case 0x05: /* Status */ - ret = 0x01; - break; - case 0x06: /* Card Select Number (CSN) */ - nelog(1, "Card Select Number (CSN)\n"); - ret = dev->pnp_csn; - break; - case 0x07: /* Logical Device Number */ - nelog(1, "Logical Device Number\n"); - ret = 0x00; - break; - case 0x30: /* Activate */ - nelog(1, "Activate\n"); - ret = dev->pnp_activate; - break; - case 0x31: /* I/O Range Check */ - nelog(1, "I/O Range Check\n"); - ret = dev->pnp_io_check; - break; - - /* Logical Device Configuration Registers */ - /* Memory Configuration Registers - We currently force them to stay 0x00 because we currently do not - support a RTL8019AS BIOS. */ - case 0x40: /* BROM base address bits[23:16] */ - case 0x41: /* BROM base address bits[15:0] */ - case 0x42: /* Memory Control */ - ret = 0x00; - break; - - /* I/O Configuration Registers */ - case 0x60: /* I/O base address bits[15:8] */ - ret = (dev->base_address >> 8); - break; - case 0x61: /* I/O base address bits[7:0] */ - ret = (dev->base_address & 0xFF); - break; - - /* Interrupt Configuration Registers */ - case 0x70: /* IRQ level */ - ret = dev->base_irq; - break; - case 0x71: /* IRQ type */ - ret = 0x02; /* high, edge */ - break; - - /* DMA Configuration Registers */ - case 0x74: /* DMA channel select 0 */ - case 0x75: /* DMA channel select 1 */ - ret = 0x04; /* indicating no DMA channel is needed */ - break; - - /* Vendor Defined Registers */ - case 0xF0: /* CONFIG0 */ - case 0xF1: /* CONFIG1 */ - ret = 0x00; - break; - case 0xF2: /* CONFIG2 */ - ret = (dev->config2 & 0xe0); - break; - case 0xF3: /* CONFIG3 */ - ret = (dev->config3 & 0x46); - break; - case 0xF5: /* CSNSAV */ - ret = (dev->pnp_csnsav); - break; - } - - nelog(1, "nic_pnp_readb(%04X) = %02X\n", addr, ret); - return(ret); -} - - -static void nic_pnp_io_set(nic_t *dev, uint16_t read_addr); -static void nic_pnp_io_remove(nic_t *dev); - - -static void -nic_pnp_writeb(uint16_t addr, uint8_t val, void *priv) -{ - nic_t *dev = (nic_t *) priv; - uint16_t new_addr = 0; - - nelog(1, "nic_pnp_writeb(%04X, %02X)\n", addr, val); - - /* Plug and Play Registers */ - switch(dev->pnp_address) { - /* Card Control Registers */ - case 0x00: /* Set RD_DATA port */ - new_addr = val; - new_addr <<= 2; - new_addr |= 3; - nic_pnp_io_remove(dev); - nic_pnp_io_set(dev, new_addr); - nelog(1, "PnP read data address now: %04X\n", new_addr); - break; - case 0x02: /* Config Control */ - if (val & 0x01) { - /* Reset command */ - nic_pnp_io_remove(dev); - memset(dev->pnp_regs, 0, 256); - nelog(1, "All logical devices reset\n"); - } - if (val & 0x02) { - /* Wait for Key command */ - dev->pnp_phase = PNP_PHASE_WAIT_FOR_KEY; - nelog(1, "WAIT FOR KEY phase\n"); - } - if (val & 0x04) { - /* PnP Reset CSN command */ - dev->pnp_csn = dev->pnp_csnsav = 0; - nelog(1, "CSN reset\n"); - } - break; - case 0x03: /* Wake[CSN] */ - nelog(1, "Wake[%02X]\n", val); - if (val == dev->pnp_csn) { - dev->pnp_res_pos = 0x12; - dev->pnp_id_checksum = 0x6A; - if (dev->pnp_phase == PNP_PHASE_SLEEP) { - dev->pnp_phase = val ? PNP_PHASE_CONFIG : PNP_PHASE_ISOLATION; - } - } else { - if ((dev->pnp_phase == PNP_PHASE_CONFIG) || (dev->pnp_phase == PNP_PHASE_ISOLATION)) - dev->pnp_phase = PNP_PHASE_SLEEP; - } - break; - case 0x06: /* Card Select Number (CSN) */ - dev->pnp_csn = dev->pnp_csnsav = val; - dev->pnp_phase = PNP_PHASE_CONFIG; - nelog(1, "CSN set to %02X\n", dev->pnp_csn); - break; - case 0x30: /* Activate */ - if ((dev->pnp_activate ^ val) & 0x01) { - nic_ioremove(dev, dev->base_address); - if (val & 0x01) - nic_ioset(dev, dev->base_address); - - nelog(1, "I/O range %sabled\n", val & 0x02 ? "en" : "dis"); - } - dev->pnp_activate = val; - break; - case 0x31: /* I/O Range Check */ - if ((dev->pnp_io_check ^ val) & 0x02) { - nic_iocheckremove(dev, dev->base_address); - if (val & 0x02) - nic_iocheckset(dev, dev->base_address); - - nelog(1, "I/O range check %sabled\n", val & 0x02 ? "en" : "dis"); - } - dev->pnp_io_check = val; - break; - - /* Logical Device Configuration Registers */ - /* Memory Configuration Registers - We currently force them to stay 0x00 because we currently do not - support a RTL8019AS BIOS. */ - - /* I/O Configuration Registers */ - case 0x60: /* I/O base address bits[15:8] */ - if ((dev->pnp_activate & 0x01) || (dev->pnp_io_check & 0x02)) - nic_ioremove(dev, dev->base_address); - dev->base_address &= 0x00ff; - dev->base_address |= (((uint16_t) val) << 8); - if ((dev->pnp_activate & 0x01) || (dev->pnp_io_check & 0x02)) - nic_ioset(dev, dev->base_address); - nelog(1, "Base address now: %04X\n", dev->base_address); - break; - case 0x61: /* I/O base address bits[7:0] */ - if ((dev->pnp_activate & 0x01) || (dev->pnp_io_check & 0x02)) - nic_ioremove(dev, dev->base_address); - dev->base_address &= 0xff00; - dev->base_address |= val; - if ((dev->pnp_activate & 0x01) || (dev->pnp_io_check & 0x02)) - nic_ioset(dev, dev->base_address); - nelog(1, "Base address now: %04X\n", dev->base_address); - break; - - /* Interrupt Configuration Registers */ - case 0x70: /* IRQ level */ - dev->base_irq = val; - nelog(1, "IRQ now: %02i\n", dev->base_irq); - break; - - /* Vendor Defined Registers */ - case 0xF6: /* Vendor Control */ - dev->pnp_csn = 0; - break; - } - return; -} - - -static void -nic_pnp_io_set(nic_t *dev, uint16_t read_addr) -{ - if ((read_addr >= 0x0200) && (read_addr <= 0x03FF)) { - io_sethandler(read_addr, 1, - nic_pnp_readb, NULL, NULL, - NULL, NULL, NULL, dev); - } - dev->pnp_read = read_addr; -} - - -static void -nic_pnp_io_remove(nic_t *dev) -{ - if ((dev->pnp_read >= 0x0200) && (dev->pnp_read <= 0x03FF)) { - io_removehandler(dev->pnp_read, 1, - nic_pnp_readb, NULL, NULL, - NULL, NULL, NULL, dev); - } -} - - -static void -nic_pnp_address_writeb(uint16_t addr, uint8_t val, void *priv) -{ - nic_t *dev = (nic_t *) priv; - - /* nelog(1, "nic_pnp_address_writeb(%04X, %02X)\n", addr, val); */ - - switch(dev->pnp_phase) { - case PNP_PHASE_WAIT_FOR_KEY: - if (val == pnp_init_key[dev->pnp_magic_count]) { - dev->pnp_magic_count = (dev->pnp_magic_count + 1) & 0x1f; - if (!dev->pnp_magic_count) - dev->pnp_phase = PNP_PHASE_SLEEP; - } else - dev->pnp_magic_count = 0; - break; - default: - dev->pnp_address = val; - break; - } - return; -} - - -static void -nic_iocheckset(nic_t *dev, uint16_t addr) -{ - io_sethandler(addr, 32, - nic_pnp_io_check_readb, NULL, NULL, - NULL, NULL, NULL, dev); -} - - -static void -nic_iocheckremove(nic_t *dev, uint16_t addr) -{ - io_removehandler(addr, 32, - nic_pnp_io_check_readb, NULL, NULL, - NULL, NULL, NULL, dev); -} - - -static void -nic_ioset(nic_t *dev, uint16_t addr) -{ - if (dev->is_pci) { - io_sethandler(addr, 16, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - io_sethandler(addr+16, 16, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - io_sethandler(addr+0x1f, 1, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - } else { - io_sethandler(addr, 16, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - if (dev->is_8bit) { - io_sethandler(addr+16, 16, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - } else { - io_sethandler(addr+16, 16, - nic_readb, nic_readw, NULL, - nic_writeb, nic_writew, NULL, dev); - } - io_sethandler(addr+0x1f, 1, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - } -} - - -static void -nic_ioremove(nic_t *dev, uint16_t addr) -{ - if (dev->is_pci) { - io_removehandler(addr, 16, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - io_removehandler(addr+16, 16, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - io_removehandler(addr+0x1f, 1, - nic_readb, nic_readw, nic_readl, - nic_writeb, nic_writew, nic_writel, dev); - } else { - io_removehandler(addr, 16, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - if (dev->is_8bit) { - io_removehandler(addr+16, 16, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - } else { - io_removehandler(addr+16, 16, - nic_readb, nic_readw, NULL, - nic_writeb, nic_writew, NULL, dev); - } - io_removehandler(addr+0x1f, 1, - nic_readb, NULL, NULL, - nic_writeb, NULL, NULL, dev); - } -} - - -static void -nic_update_bios(nic_t *dev) -{ - int reg_bios_enable; - - reg_bios_enable = 1; - - if (! dev->has_bios) return; - - if (PCI && dev->is_pci) - reg_bios_enable = dev->pci_bar[1].addr_regs[0] & 0x01; - - /* PCI BIOS stuff, just enable_disable. */ - if (reg_bios_enable) { - mem_mapping_set_addr(&dev->bios_rom.mapping, - dev->bios_addr, dev->bios_size); - nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); - } else { - nelog(1, "%s: BIOS disabled\n", dev->name); - mem_mapping_disable(&dev->bios_rom.mapping); - } -} - - -static uint8_t -nic_pci_read(int func, int addr, void *priv) -{ - nic_t *dev = (nic_t *)priv; - uint8_t ret = 0x00; - - switch(addr) { - case 0x00: /* PCI_VID_LO */ - case 0x01: /* PCI_VID_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x02: /* PCI_DID_LO */ - case 0x03: /* PCI_DID_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x04: /* PCI_COMMAND_LO */ - case 0x05: /* PCI_COMMAND_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x06: /* PCI_STATUS_LO */ - case 0x07: /* PCI_STATUS_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x08: /* PCI_REVID */ - ret = 0x00; /* Rev. 00 */ - break; - case 0x09: /* PCI_PIFR */ - ret = 0x00; /* Rev. 00 */ - break; - - case 0x0A: /* PCI_SCR */ - ret = dev->pci_regs[addr]; - break; - - case 0x0B: /* PCI_BCR */ - ret = dev->pci_regs[addr]; - break; - -#if 0 - case 0x0C: /* (reserved) */ - ret = dev->pci_regs[addr]; - break; - - case 0x0D: /* PCI_LTR */ - case 0x0E: /* PCI_HTR */ - ret = dev->pci_regs[addr]; - break; - - case 0x0F: /* (reserved) */ - ret = dev->pci_regs[addr]; - break; -#endif - - case 0x10: /* PCI_BAR 7:5 */ - ret = (dev->pci_bar[0].addr_regs[0] & 0xe0) | 0x01; - break; - case 0x11: /* PCI_BAR 15:8 */ - ret = dev->pci_bar[0].addr_regs[1]; - break; - case 0x12: /* PCI_BAR 23:16 */ - ret = dev->pci_bar[0].addr_regs[2]; - break; - case 0x13: /* PCI_BAR 31:24 */ - ret = dev->pci_bar[0].addr_regs[3]; - break; - - case 0x2C: /* PCI_SVID_LO */ - case 0x2D: /* PCI_SVID_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x2E: /* PCI_SID_LO */ - case 0x2F: /* PCI_SID_HI */ - ret = dev->pci_regs[addr]; - break; - - case 0x30: /* PCI_ROMBAR */ - ret = dev->pci_bar[1].addr_regs[0] & 0x01; - break; - case 0x31: /* PCI_ROMBAR 15:11 */ - ret = dev->pci_bar[1].addr_regs[1] & 0x80; - break; - case 0x32: /* PCI_ROMBAR 23:16 */ - ret = dev->pci_bar[1].addr_regs[2]; - break; - case 0x33: /* PCI_ROMBAR 31:24 */ - ret = dev->pci_bar[1].addr_regs[3]; - break; - - case 0x3C: /* PCI_ILR */ - ret = dev->pci_regs[addr]; - break; - - case 0x3D: /* PCI_IPR */ - ret = dev->pci_regs[addr]; - break; - } - - nelog(2, "%s: PCI_Read(%d, %04x) = %02x\n", dev->name, func, addr, ret); - - return(ret); -} - - -static void -nic_pci_write(int func, int addr, uint8_t val, void *priv) -{ - nic_t *dev = (nic_t *)priv; - uint8_t valxor; - - nelog(2, "%s: PCI_Write(%d, %04x, %02x)\n", dev->name, func, addr, val); - - switch(addr) { - case 0x04: /* PCI_COMMAND_LO */ - valxor = (val & 0x03) ^ dev->pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) - { - nic_ioremove(dev, dev->base_address); - if ((dev->base_address != 0) && (val & PCI_COMMAND_IO)) - { - nic_ioset(dev, dev->base_address); - } - } -#if 0 - if (val & PCI_COMMAND_MEMORY) { - ... - } -#endif - dev->pci_regs[addr] = val & 0x03; - break; - -#if 0 - case 0x0C: /* (reserved) */ - dev->pci_regs[addr] = val; - break; - - case 0x0D: /* PCI_LTR */ - dev->pci_regs[addr] = val; - break; - - case 0x0E: /* PCI_HTR */ - dev->pci_regs[addr] = val; - break; - - case 0x0F: /* (reserved) */ - dev->pci_regs[addr] = val; - break; -#endif - - case 0x10: /* PCI_BAR */ - val &= 0xe0; /* 0xe0 acc to RTL DS */ - val |= 0x01; /* re-enable IOIN bit */ - /*FALLTHROUGH*/ - - case 0x11: /* PCI_BAR */ - case 0x12: /* PCI_BAR */ - case 0x13: /* PCI_BAR */ - /* Remove old I/O. */ - nic_ioremove(dev, dev->base_address); - - /* Set new I/O as per PCI request. */ - dev->pci_bar[0].addr_regs[addr & 3] = val; - - /* Then let's calculate the new I/O base. */ - dev->base_address = dev->pci_bar[0].addr & 0xffe0; - - /* Log the new base. */ - nelog(1, "%s: PCI: new I/O base is %04X\n", - dev->name, dev->base_address); - /* We're done, so get out of the here. */ - if (dev->pci_regs[4] & PCI_COMMAND_IO) - { - if (dev->base_address != 0) - { - nic_ioset(dev, dev->base_address); - } - } - break; - - case 0x30: /* PCI_ROMBAR */ - case 0x31: /* PCI_ROMBAR */ - case 0x32: /* PCI_ROMBAR */ - case 0x33: /* PCI_ROMBAR */ - dev->pci_bar[1].addr_regs[addr & 3] = val; - /* dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; */ - dev->pci_bar[1].addr &= 0xffff8001; - dev->bios_addr = dev->pci_bar[1].addr; - nic_update_bios(dev); - return; - - case 0x3C: /* PCI_ILR */ - nelog(1, "%s: IRQ now: %i\n", dev->name, val); - dev->base_irq = val; - dev->pci_regs[addr] = dev->base_irq; - return; - } -} - - -/* - * Return the 6-bit index into the multicast - * table. Stolen unashamedly from FreeBSD's if_ed.c - */ -static int -mcast_index(const void *dst) -{ -#define POLYNOMIAL 0x04c11db6 - uint32_t crc = 0xffffffffL; - int carry, i, j; - uint8_t b; - uint8_t *ep = (uint8_t *)dst; - - for (i=6; --i>=0;) { - b = *ep++; - for (j = 8; --j >= 0;) { - carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); - crc <<= 1; - b >>= 1; - if (carry) - crc = ((crc ^ POLYNOMIAL) | carry); - } - } - return(crc >> 26); -#undef POLYNOMIAL -} - - -static void -nic_tx(nic_t *dev, uint32_t val) -{ - dev->CR.tx_packet = 0; - dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; - - /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte) - nic_interrupt(dev, 1); - dev->tx_timer_active = 0; -} - - -/* - * Called by the platform-specific code when an Ethernet frame - * has been received. The destination address is tested to see - * if it should be accepted, and if the RX ring has enough room, - * it is copied into it and the receive process is updated. - */ -static void -nic_rx(void *priv, uint8_t *buf, int io_len) -{ - static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - nic_t *dev = (nic_t *)priv; - uint8_t pkthdr[4]; - uint8_t *startptr; - int pages, avail; - int idx, nextpage; - int endbytes; - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 1); - - if (io_len != 60) - nelog(2, "%s: rx_frame with length %d\n", dev->name, io_len); - - if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; - - /* - * Add the pkt header + CRC to the length, and work - * out how many 256-byte pages the frame would occupy. - */ - pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; - if (dev->curr_page < dev->bound_ptr) { - avail = dev->bound_ptr - dev->curr_page; - } else { - avail = (dev->page_stop - dev->page_start) - - (dev->curr_page - dev->bound_ptr); - } - - /* - * Avoid getting into a buffer overflow condition by - * not attempting to do partial receives. The emulation - * to handle this condition seems particularly painful. - */ - if ((avail < pages) -#if NE2K_NEVER_FULL_RING - || (avail == pages) -#endif - ) { - nelog(1, "%s: no space\n", dev->name); - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); - return; - } - - if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { - nelog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); - return; - } - - /* Some computers don't care... */ - if (io_len < 60) - io_len = 60; - - nelog(2, "%s: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", - dev->name, - buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], - io_len); - - /* Do address filtering if not in promiscuous mode. */ - if (! dev->RCR.promisc) { - /* If this is a broadcast frame.. */ - if (! memcmp(buf, bcast_addr, 6)) { - /* Broadcast not enabled, we're done. */ - if (! dev->RCR.broadcast) { - nelog(2, "%s: RX BC disabled\n", dev->name); - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); - return; - } - } - - /* If this is a multicast frame.. */ - else if (buf[0] & 0x01) { - /* Multicast not enabled, we're done. */ - if (! dev->RCR.multicast) { -#if 1 - nelog(2, "%s: RX MC disabled\n", dev->name); -#endif - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); - return; - } - - /* Are we listening to this multicast address? */ - idx = mcast_index(buf); - if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { - nelog(2, "%s: RX MC not listed\n", dev->name); - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); - return; - } - } - - /* Unicast, must be for us.. */ - else if (memcmp(buf, dev->physaddr, 6)) return; - } else { - nelog(2, "%s: RX promiscuous receive\n", dev->name); - } - - nextpage = dev->curr_page + pages; - if (nextpage >= dev->page_stop) - nextpage -= (dev->page_stop - dev->page_start); - - /* Set up packet header. */ - pkthdr[0] = 0x01; /* RXOK - packet is OK */ - if (buf[0] & 0x01) - pkthdr[0] |= 0x20; /* MULTICAST packet */ - pkthdr[1] = nextpage; /* ptr to next packet */ - pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */ - pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */ - nelog(2, "%s: RX pkthdr [%02x %02x %02x %02x]\n", - dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); - - /* Copy into buffer, update curpage, and signal interrupt if config'd */ - if (dev->board >= NE2K_NE2000) - startptr = &dev->mem[(dev->curr_page * 256) - NE2K_MEMSTART]; - else - startptr = &dev->mem[(dev->curr_page * 256) - NE1K_MEMSTART]; - memcpy(startptr, pkthdr, sizeof(pkthdr)); - if ((nextpage > dev->curr_page) || - ((dev->curr_page + pages) == dev->page_stop)) { - memcpy(startptr+sizeof(pkthdr), buf, io_len); - } else { - endbytes = (dev->page_stop - dev->curr_page) * 256; - memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr)); - if (dev->board >= NE2K_NE2000) - startptr = &dev->mem[(dev->page_start * 256) - NE2K_MEMSTART]; - else - startptr = &dev->mem[(dev->page_start * 256) - NE1K_MEMSTART]; - memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8); - } - dev->curr_page = nextpage; - - dev->RSR.rx_ok = 1; - dev->RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; - dev->ISR.pkt_rx = 1; - - if (dev->IMR.rx_inte) - nic_interrupt(dev, 1); - - //FIXME: move to upper layer - ui_sb_update_icon(SB_NETWORK, 0); -} - - -static void -nic_rom_init(nic_t *dev, wchar_t *s) -{ - uint32_t temp; - FILE *f; - - if (s == NULL) return; - - if (dev->bios_addr == 0) return; - - if ((f = rom_fopen(s, L"rb")) != NULL) { - fseek(f, 0L, SEEK_END); - temp = ftell(f); - fclose(f); - dev->bios_size = 0x10000; - if (temp <= 0x8000) - dev->bios_size = 0x8000; - if (temp <= 0x4000) - dev->bios_size = 0x4000; - if (temp <= 0x2000) - dev->bios_size = 0x2000; - dev->bios_mask = (dev->bios_size >> 8) & 0xff; - dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; - } else { - dev->bios_addr = 0x00000; - dev->bios_size = 0; - return; - } - - /* Create a memory mapping for the space. */ - rom_init(&dev->bios_rom, s, dev->bios_addr, - dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL); - - nelog(1, "%s: BIOS configured at %06lX (size %ld)\n", - dev->name, dev->bios_addr, dev->bios_size); -} - - -static void * -nic_init(const device_t *info) -{ - uint32_t mac; - wchar_t *rom; - nic_t *dev; -#ifdef ENABLE_NIC_LOG - int i; -#endif - int c; - char *ansi_id = "REALTEK PLUG & PLAY ETHERNET CARD"; - uint64_t *eeprom_pnp_id; - - /* Get the desired debug level. */ -#ifdef ENABLE_NIC_LOG - i = device_get_config_int("debug"); - if (i > 0) nic_do_log = i; -#endif - - dev = malloc(sizeof(nic_t)); - memset(dev, 0x00, sizeof(nic_t)); - dev->name = info->name; - dev->board = info->local; - rom = NULL; - switch(dev->board) { - case NE2K_NE1000: - dev->is_8bit = 1; - /*FALLTHROUGH*/ - - case NE2K_NE2000: - dev->maclocal[0] = 0x00; /* 00:00:D8 (Novell OID) */ - dev->maclocal[1] = 0x00; - dev->maclocal[2] = 0xD8; - rom = (dev->board == NE2K_NE1000) ? NULL : ROM_PATH_NE2000; - break; - - case NE2K_RTL8019AS: - case NE2K_RTL8029AS: - dev->is_pci = (dev->board == NE2K_RTL8029AS) ? 1 : 0; - dev->maclocal[0] = 0x00; /* 00:E0:4C (Realtek OID) */ - dev->maclocal[1] = 0xE0; - dev->maclocal[2] = 0x4C; - rom = (dev->board == NE2K_RTL8019AS) ? ROM_PATH_RTL8019 : ROM_PATH_RTL8029; - break; - } - - if (dev->board >= NE2K_RTL8019AS) { - dev->base_address = 0x340; - dev->base_irq = 12; - if (dev->board == NE2K_RTL8029AS) { - dev->bios_addr = 0xD0000; - dev->has_bios = device_get_config_int("bios"); - } else { - dev->bios_addr = 0x00000; - dev->has_bios = 0; - } - } else { - dev->base_address = device_get_config_hex16("base"); - dev->base_irq = device_get_config_int("irq"); - if (dev->board == NE2K_NE2000) { - dev->bios_addr = device_get_config_hex20("bios_addr"); - dev->has_bios = !!dev->bios_addr; - } else { - dev->bios_addr = 0x00000; - dev->has_bios = 0; - } - } - - /* See if we have a local MAC address configured. */ - mac = device_get_config_mac("mac", -1); - - /* - * Make this device known to the I/O system. - * PnP and PCI devices start with address spaces inactive. - */ - if (dev->board < NE2K_RTL8019AS) - nic_ioset(dev, dev->base_address); - - /* Set up our BIOS ROM space, if any. */ - nic_rom_init(dev, rom); - - /* Set up our BIA. */ - if (mac & 0xff000000) { - /* Generate new local MAC. */ - dev->maclocal[3] = random_generate(); - dev->maclocal[4] = random_generate(); - dev->maclocal[5] = random_generate(); - mac = (((int) dev->maclocal[3]) << 16); - mac |= (((int) dev->maclocal[4]) << 8); - mac |= ((int) dev->maclocal[5]); - device_set_config_mac("mac", mac); - } else { - dev->maclocal[3] = (mac>>16) & 0xff; - dev->maclocal[4] = (mac>>8) & 0xff; - dev->maclocal[5] = (mac & 0xff); - } - memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); - - nelog(0, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, dev->base_address, dev->base_irq, - dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], - dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]); - - if (dev->board >= NE2K_RTL8019AS) { - if (dev->is_pci) { - /* - * Configure the PCI space registers. - * - * We do this here, so the I/O routines are generic. - */ - memset(dev->pci_regs, 0, PCI_REGSIZE); - - dev->pci_regs[0x00] = (PCI_VENDID&0xff); - dev->pci_regs[0x01] = (PCI_VENDID>>8); - dev->pci_regs[0x02] = (PCI_DEVID&0xff); - dev->pci_regs[0x03] = (PCI_DEVID>>8); - - dev->pci_regs[0x04] = 0x03; /* IOEN */ - dev->pci_regs[0x05] = 0x00; - dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */ - - dev->pci_regs[0x09] = 0x00; /* PIFR */ - - dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */ - dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */ - - dev->pci_regs[0x2C] = (PCI_VENDID&0xff); - dev->pci_regs[0x2D] = (PCI_VENDID>>8); - dev->pci_regs[0x2E] = (PCI_DEVID&0xff); - dev->pci_regs[0x2F] = (PCI_DEVID>>8); - - dev->pci_regs[0x3D] = PCI_INTA; /* PCI_IPR */ - - /* Enable our address space in PCI. */ - dev->pci_bar[0].addr_regs[0] = 0x01; - - /* Enable our BIOS space in PCI, if needed. */ - if (dev->bios_addr > 0) { - dev->pci_bar[1].addr = 0xFFFF8000; - dev->pci_bar[1].addr_regs[1] = dev->bios_mask; - } else { - dev->pci_bar[1].addr = 0; - dev->bios_size = 0; - } - - mem_mapping_disable(&dev->bios_rom.mapping); - - /* Add device to the PCI bus, keep its slot number. */ - dev->card = pci_add_card(PCI_ADD_NORMAL, - nic_pci_read, nic_pci_write, dev); - } else { - io_sethandler(0x0279, 1, - NULL, NULL, NULL, - nic_pnp_address_writeb, NULL, NULL, dev); - - dev->pnp_id = PNP_DEVID; - dev->pnp_id <<= 32LL; - dev->pnp_id |= PNP_VENDID; - dev->pnp_phase = PNP_PHASE_WAIT_FOR_KEY; - } - - /* Initialize the RTL8029 EEPROM. */ - memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); - - if (dev->board == NE2K_RTL8029AS) { - memcpy(&dev->eeprom[0x02], dev->maclocal, 6); - - dev->eeprom[0x76] = - dev->eeprom[0x7A] = - dev->eeprom[0x7E] = (PCI_DEVID&0xff); - dev->eeprom[0x77] = - dev->eeprom[0x7B] = - dev->eeprom[0x7F] = (dev->board == NE2K_RTL8019AS) ? (PNP_DEVID>>8) : (PCI_DEVID>>8); - dev->eeprom[0x78] = - dev->eeprom[0x7C] = (PCI_VENDID&0xff); - dev->eeprom[0x79] = - dev->eeprom[0x7D] = (PCI_VENDID>>8); - } else { - eeprom_pnp_id = (uint64_t *) &dev->eeprom[0x12]; - *eeprom_pnp_id = dev->pnp_id; - - /* TAG: Plug and Play Version Number. */ - dev->eeprom[0x1B] = 0x0A; /* Item byte */ - dev->eeprom[0x1C] = 0x10; /* PnP version */ - dev->eeprom[0x1D] = 0x10; /* Vendor version */ - - /* TAG: ANSI Identifier String. */ - dev->eeprom[0x1E] = 0x82; /* Item byte */ - dev->eeprom[0x1F] = 0x22; /* Length bits 7-0 */ - dev->eeprom[0x20] = 0x00; /* Length bits 15-8 */ - memcpy(&dev->eeprom[0x21], ansi_id, 0x22); - - /* TAG: Logical Device ID. */ - dev->eeprom[0x43] = 0x16; /* Item byte */ - dev->eeprom[0x44] = 0x4A; /* Logical device ID0 */ - dev->eeprom[0x45] = 0x8C; /* Logical device ID1 */ - dev->eeprom[0x46] = 0x80; /* Logical device ID2 */ - dev->eeprom[0x47] = 0x19; /* Logical device ID3 */ - dev->eeprom[0x48] = 0x02; /* Flag0 (02=BROM/disabled) */ - dev->eeprom[0x49] = 0x00; /* Flag 1 */ - - /* TAG: Compatible Device ID (NE2000) */ - dev->eeprom[0x4A] = 0x1C; /* Item byte */ - dev->eeprom[0x4B] = 0x41; /* Compatible ID0 */ - dev->eeprom[0x4C] = 0xD0; /* Compatible ID1 */ - dev->eeprom[0x4D] = 0x80; /* Compatible ID2 */ - dev->eeprom[0x4E] = 0xD6; /* Compatible ID3 */ - - /* TAG: I/O Format */ - dev->eeprom[0x4F] = 0x47; /* Item byte */ - dev->eeprom[0x50] = 0x00; /* I/O information */ - dev->eeprom[0x51] = 0x20; /* Min. I/O base bits 7-0 */ - dev->eeprom[0x52] = 0x02; /* Min. I/O base bits 15-8 */ - dev->eeprom[0x53] = 0x80; /* Max. I/O base bits 7-0 */ - dev->eeprom[0x54] = 0x03; /* Max. I/O base bits 15-8 */ - dev->eeprom[0x55] = 0x20; /* Base alignment */ - dev->eeprom[0x56] = 0x20; /* Range length */ - - /* TAG: IRQ Format. */ - dev->eeprom[0x57] = 0x23; /* Item byte */ - dev->eeprom[0x58] = 0x38; /* IRQ mask bits 7-0 */ - dev->eeprom[0x59] = 0x9E; /* IRQ mask bits 15-8 */ - dev->eeprom[0x5A] = 0x01; /* IRQ information */ - - /* TAG: END Tag */ - dev->eeprom[0x5B] = 0x79; /* Item byte */ - for (c = 0x1b; c < 0x5c; c++) /* Checksum (2's compl) */ - dev->eeprom[0x5C] += dev->eeprom[c]; - dev->eeprom[0x5C] = -dev->eeprom[0x5C]; - - io_sethandler(0x0A79, 1, - NULL, NULL, NULL, - nic_pnp_writeb, NULL, NULL, dev); - } - } - - /* Reset the board. */ - nic_reset(dev); - - /* Attach ourselves to the network module. */ - network_attach(dev, dev->physaddr, nic_rx); - - nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, - dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); - - return(dev); -} - - -static void -nic_close(void *priv) -{ - nic_t *dev = (nic_t *)priv; - - /* Make sure the platform layer is shut down. */ - network_close(); - - nic_ioremove(dev, dev->base_address); - - nelog(1, "%s: closed\n", dev->name); - - free(dev); -} - - -static const device_config_t ne1000_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, - { - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } -}; - -static const device_config_t ne2000_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, - { - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, - { - { - "Disabled", 0x00000 - }, - { - "D000", 0xD0000 - }, - { - "D800", 0xD8000 - }, - { - "C800", 0xC8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -static const device_config_t rtl8019as_config[] = -{ - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } -}; - -static const device_config_t rtl8029as_config[] = -{ - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } -}; - - -const device_t ne1000_device = { - "Novell NE1000", - DEVICE_ISA, - NE2K_NE1000, - nic_init, nic_close, NULL, - NULL, NULL, NULL, - ne1000_config -}; - -const device_t ne2000_device = { - "Novell NE2000", - DEVICE_ISA | DEVICE_AT, - NE2K_NE2000, - nic_init, nic_close, NULL, - NULL, NULL, NULL, - ne2000_config -}; - -const device_t rtl8019as_device = { - "Realtek RTL8019AS", - DEVICE_ISA | DEVICE_AT, - NE2K_RTL8019AS, - nic_init, nic_close, NULL, - NULL, NULL, NULL, - rtl8019as_config -}; - -const device_t rtl8029as_device = { - "Realtek RTL8029AS", - DEVICE_PCI, - NE2K_RTL8029AS, - nic_init, nic_close, NULL, - NULL, NULL, NULL, - rtl8029as_config -}; diff --git a/src - Cópia/network/net_ne2000.h b/src - Cópia/network/net_ne2000.h deleted file mode 100644 index 0453a3ba5..000000000 --- a/src - Cópia/network/net_ne2000.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 NE2000 ethernet controller. - * - * Version: @(#)net_ne2000.h 1.0.2 2018/03/15 - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * 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 NET_NE2000_H -# define NET_NE2000_H - - -enum { - NE2K_NONE = 0, - NE2K_NE1000, /* 8-bit ISA NE1000 */ - NE2K_NE2000, /* 16-bit ISA NE2000 */ - NE2K_RTL8019AS, /* 16-bit ISA PnP Realtek 8019AS */ - NE2K_RTL8029AS /* 32-bit PCI Realtek 8029AS */ -}; - - -extern const device_t ne1000_device; -extern const device_t ne2000_device; -extern const device_t rtl8019as_device; -extern const device_t rtl8029as_device; - - -#endif /*NET_NE2000_H*/ diff --git a/src - Cópia/network/net_pcap.c b/src - Cópia/network/net_pcap.c deleted file mode 100644 index 78cf72f91..000000000 --- a/src - Cópia/network/net_pcap.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * 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. - * - * Handle WinPcap library processing. - * - * Version: @(#)net_pcap.c 1.0.4 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "network.h" - - -typedef int bpf_int32; -typedef unsigned int bpf_u_int32; - -/* - * The instruction data structure. - */ -struct bpf_insn { - unsigned short code; - unsigned char jt; - unsigned char jf; - bpf_u_int32 k; -}; - -/* - * Structure for "pcap_compile()", "pcap_setfilter()", etc.. - */ -struct bpf_program { - unsigned int bf_len; - struct bpf_insn *bf_insns; -}; - -typedef struct pcap_if pcap_if_t; - -typedef struct timeval { - long tv_sec; - long tv_usec; -} timeval; - -#define PCAP_ERRBUF_SIZE 256 - -struct pcap_pkthdr { - struct timeval ts; - bpf_u_int32 caplen; - bpf_u_int32 len; -}; - -struct pcap_if { - struct pcap_if *next; - char *name; - char *description; - void *addresses; - unsigned int flags; -}; - - -static volatile void *pcap_handle; /* handle to WinPcap DLL */ -static volatile void *pcap; /* handle to WinPcap library */ -static volatile thread_t *poll_tid; -static const netcard_t *poll_card; /* netcard linked to us */ -static event_t *poll_state; - - -/* Pointers to the real functions. */ -static const char *(*f_pcap_lib_version)(void); -static int (*f_pcap_findalldevs)(pcap_if_t **,char *); -static void (*f_pcap_freealldevs)(void *); -static void *(*f_pcap_open_live)(const char *,int,int,int,char *); -static int (*f_pcap_compile)(void *,void *, - const char *,int,bpf_u_int32); -static int (*f_pcap_setfilter)(void *,void *); -static const unsigned char - *(*f_pcap_next)(void *,void *); -static int (*f_pcap_sendpacket)(void *,const unsigned char *,int); -static void (*f_pcap_close)(void *); -static dllimp_t pcap_imports[] = { - { "pcap_lib_version", &f_pcap_lib_version }, - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_compile", &f_pcap_compile }, - { "pcap_setfilter", &f_pcap_setfilter }, - { "pcap_next", &f_pcap_next }, - { "pcap_sendpacket", &f_pcap_sendpacket }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, -}; - - -#ifdef ENABLE_PCAP_LOG -int pcap_do_log = ENABLE_PCAP_LOG; -#endif - - -static void -pcap_log(const char *format, ...) -{ -#ifdef ENABLE_PCAP_LOG - va_list ap; - - if (pcap_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle the receiving of frames from the channel. */ -static void -poll_thread(void *arg) -{ - uint8_t *mac = (uint8_t *)arg; - uint8_t *data = NULL; - struct pcap_pkthdr h; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; - event_t *evt; - - pcap_log("PCAP: polling started.\n"); - thread_set_event(poll_state); - - /* Create a waitable event. */ - evt = thread_create_event(); - - /* As long as the channel is open.. */ - while (pcap != NULL) { - /* Request ownership of the device. */ - network_wait(1); - - /* Wait for a poll request. */ - network_poll(); - - if (pcap == NULL) break; - - /* Wait for the next packet to arrive. */ - data = (uint8_t *)f_pcap_next((void *)pcap, &h); - if (data != NULL) { - /* Received MAC. */ - mac_cmp32[0] = *(uint32_t *)(data+6); - mac_cmp16[0] = *(uint16_t *)(data+10); - - /* Local MAC. */ - mac_cmp32[1] = *(uint32_t *)mac; - mac_cmp16[1] = *(uint16_t *)(mac+4); - if ((mac_cmp32[0] != mac_cmp32[1]) || - (mac_cmp16[0] != mac_cmp16[1])) { - - poll_card->rx(poll_card->priv, data, h.caplen); - } else { - /* Mark as invalid packet. */ - data = NULL; - } - } - - /* If we did not get anything, wait a while. */ - if (data == NULL) - thread_wait_event(evt, 10); - - /* Release ownership of the device. */ - network_wait(0); - } - - /* No longer needed. */ - if (evt != NULL) - thread_destroy_event(evt); - - pcap_log("PCAP: polling stopped.\n"); - thread_set_event(poll_state); -} - - -/* - * Prepare the (Win)Pcap module for use. - * - * This is called only once, during application init, - * to check for availability of PCAP, and to retrieve - * a list of (usable) intefaces for it. - */ -int -net_pcap_prepare(netdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist, *dev; - int i = 0; - - /* Local variables. */ - pcap = NULL; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) return(-1); - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - pcap_log("PCAP: error in pcap_findalldevs: %s\n", errbuf); - return(-1); - } - - for (dev=devlist; dev!=NULL; dev=dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return(i); -} - - -/* - * Initialize (Win)Pcap for use. - * - * This is called on every 'cycle' of the emulator, - * if and as long the NetworkType is set to PCAP, - * and also as long as we have a NetCard defined. - */ -int -net_pcap_init(void) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - char *str; - - /* Did we already load the library? */ - if (pcap_handle == NULL) return(-1); -#if 0 - // no, we don't.. - /* Load the DLL if needed. We already know it exists. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) return(-1); -#endif - - /* Get the PCAP library name and version. */ - strcpy(errbuf, f_pcap_lib_version()); - str = strchr(errbuf, '('); - if (str != NULL) *(str-1) = '\0'; - pcap_log("PCAP: initializing, %s\n", errbuf); - - /* Get the value of our capture interface. */ - if ((network_host[0] == '\0') || !strcmp(network_host, "none")) { - pcap_log("PCAP: no interface configured!\n"); - return(-1); - } - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - - return(0); -} - - -/* Close up shop. */ -void -net_pcap_close(void) -{ - void *pc; - - if (pcap == NULL) return; - - pcap_log("PCAP: closing.\n"); - - /* Tell the polling thread to shut down. */ - pc = (void *)pcap; pcap = NULL; - - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - network_busy(0); - - /* Wait for the thread to finish. */ - pcap_log("PCAP: waiting for thread to end...\n"); - thread_wait_event(poll_state, -1); - pcap_log("PCAP: thread ended\n"); - thread_destroy_event(poll_state); - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - } - - /* OK, now shut down Pcap itself. */ - f_pcap_close(pc); - pcap = NULL; - -#if 0 - // no, we don't.. - /* Unload the DLL if possible. */ - if (pcap_handle != NULL) { - dynld_close((void *)pcap_handle); - pcap_handle = NULL; - } -#endif -} - - -/* - * Reset (Win)Pcap and activate it. - * - * This is called on every 'cycle' of the emulator, - * if and as long the NetworkType is set to PCAP, - * and also as long as we have a NetCard defined. - * - * We already know we have PCAP available, as this - * is called when the network activates itself and - * tries to attach to the network module. - */ -int -net_pcap_reset(const netcard_t *card, uint8_t *mac) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - char filter_exp[255]; - struct bpf_program fp; - - /* Open a PCAP live channel. */ - if ((pcap = f_pcap_open_live(network_host, /* interface name */ - 1518, /* max packet size */ - 1, /* promiscuous mode? */ - 10, /* timeout in msec */ - errbuf)) == NULL) { /* error buffer */ - pcap_log(" Unable to open device: %s!\n", network_host); - return(-1); - } - pcap_log("PCAP: interface: %s\n", network_host); - - /* Create a MAC address based packet filter. */ - pcap_log("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - if (f_pcap_compile((void *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - if (f_pcap_setfilter((void *)pcap, &fp) != 0) { - pcap_log("PCAP: error installing filter (%s) !\n", filter_exp); - f_pcap_close((void *)pcap); - return(-1); - } - } else { - pcap_log("PCAP: could not compile filter (%s) !\n", filter_exp); - f_pcap_close((void *)pcap); - return(-1); - } - - /* Save the callback info. */ - poll_card = card; - - pcap_log("PCAP: starting thread..\n"); - poll_state = thread_create_event(); - poll_tid = thread_create(poll_thread, mac); - thread_wait_event(poll_state, -1); - - return(0); -} - - -/* Send a packet to the Pcap interface. */ -void -net_pcap_in(uint8_t *bufp, int len) -{ - if (pcap == NULL) return; - - network_busy(1); - - f_pcap_sendpacket((void *)pcap, bufp, len); - - network_busy(0); -} diff --git a/src - Cópia/network/net_slirp.c b/src - Cópia/network/net_slirp.c deleted file mode 100644 index 3285702f4..000000000 --- a/src - Cópia/network/net_slirp.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * 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. - * - * Handle SLiRP library processing. - * - * Version: @(#)net_slirp.c 1.0.3 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "slirp/slirp.h" -#include "slirp/queue.h" -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "network.h" - - -static volatile queueADT slirpq; /* SLiRP library handle */ -static volatile thread_t *poll_tid; -static const netcard_t *poll_card; /* netcard attached to us */ -static event_t *poll_state; - - -#ifdef ENABLE_SLIRP_LOG -int slirp_do_log = ENABLE_SLIRP_LOG; -#endif - - -static void -slirp_log(const char *format, ...) -{ -#ifdef ENABLE_SLIRP_LOG - va_list ap; - - if (slirp_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static void -slirp_tic(void) -{ - int ret2, nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int tmo; - - /* Let SLiRP create a list of all open sockets. */ - nfds = -1; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ - if (tmo < 0) - tmo = 500; - - tv.tv_sec = 0; - tv.tv_usec = tmo; - - /* Now wait for something to happen, or at most 'tmo' usec. */ - ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); - - /* If something happened, let SLiRP handle it. */ - if (ret2 >= 0) - slirp_select_poll(&rfds, &wfds, &xfds); -} - - -/* Handle the receiving of frames. */ -static void -poll_thread(UNUSED(void *arg)) -{ - struct queuepacket *qp; - event_t *evt; - - slirp_log("SLiRP: polling started.\n"); - thread_set_event(poll_state); - - /* Create a waitable event. */ - evt = thread_create_event(); - - while (slirpq != NULL) { - /* Request ownership of the queue. */ - network_wait(1); - - /* Wait for a poll request. */ - network_poll(); - - /* See if there is any work. */ - slirp_tic(); - - /* Our queue may have been nuked.. */ - if (slirpq == NULL) break; - - /* Wait for the next packet to arrive. */ - if (QueuePeek(slirpq) != 0) { - /* Grab a packet from the queue. */ - qp = QueueDelete(slirpq); - slirp_log("SLiRP: inQ:%d got a %dbyte packet @%08lx\n", - QueuePeek(slirpq), qp->len, qp); - - poll_card->rx(poll_card->priv, (uint8_t *)qp->data, qp->len); - - /* Done with this one. */ - free(qp); - } else { - /* If we did not get anything, wait a while. */ - thread_wait_event(evt, 10); - } - - /* Release ownership of the queue. */ - network_wait(0); - } - - /* No longer needed. */ - if (evt != NULL) - thread_destroy_event(evt); - - slirp_log("SLiRP: polling stopped.\n"); - thread_set_event(poll_state); -} - - -/* Initialize SLiRP for use. */ -int -net_slirp_init(void) -{ - slirp_log("SLiRP: initializing..\n"); - - if (slirp_init() != 0) { - slirp_log("SLiRP could not be initialized!\n"); - return(-1); - } - - slirpq = QueueCreate(); - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - - return(0); -} - - -/* Initialize SLiRP for use. */ -int -net_slirp_reset(const netcard_t *card, uint8_t *mac) -{ - /* Save the callback info. */ - poll_card = card; - - slirp_log("SLiRP: creating thread..\n"); - poll_state = thread_create_event(); - poll_tid = thread_create(poll_thread, mac); - thread_wait_event(poll_state, -1); - - return(0); -} - - -void -net_slirp_close(void) -{ - queueADT sl; - - if (slirpq == NULL) return; - - slirp_log("SLiRP: closing.\n"); - - /* Tell the polling thread to shut down. */ - sl = slirpq; slirpq = NULL; - - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - network_busy(0); - - /* Wait for the thread to finish. */ - slirp_log("SLiRP: waiting for thread to end...\n"); - thread_wait_event(poll_state, -1); - slirp_log("SLiRP: thread ended\n"); - thread_destroy_event(poll_state); - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - } - - /* OK, now shut down SLiRP itself. */ - QueueDestroy(sl); - slirp_exit(0); -} - - -/* Send a packet to the SLiRP interface. */ -void -net_slirp_in(uint8_t *pkt, int pkt_len) -{ - if (slirpq == NULL) return; - - network_busy(1); - - slirp_input((const uint8_t *)pkt, pkt_len); - - network_busy(0); -} - - -/* Needed by SLiRP library. */ -void -slirp_output(const uint8_t *pkt, int pkt_len) -{ - struct queuepacket *qp; - - if (slirpq != NULL) { - qp = (struct queuepacket *)malloc(sizeof(struct queuepacket)); - qp->len = pkt_len; - memcpy(qp->data, pkt, pkt_len); - QueueEnter(slirpq, qp); - } -} - - -/* Needed by SLiRP library. */ -int -slirp_can_output(void) -{ - return((slirpq != NULL)?1:0); -} diff --git a/src - Cópia/network/network.c b/src - Cópia/network/network.c deleted file mode 100644 index e96bf9251..000000000 --- a/src - Cópia/network/network.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * 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. - * - * Implementation of the network module. - * - * NOTE The definition of the netcard_t is currently not optimal; - * it should be malloc'ed and then linked to the NETCARD def. - * Will be done later. - * - * Version: @(#)network.c 1.0.4 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../ui.h" -#include "network.h" -#include "net_ne2000.h" - - -static netcard_t net_cards[] = { - { "None", "none", NULL, - NULL }, - { "[ISA] Novell NE1000", "ne1k", &ne1000_device, - NULL }, - { "[ISA] Novell NE2000", "ne2k", &ne2000_device, - NULL }, - { "[ISA] Realtek RTL8019AS", "ne2kpnp", &rtl8019as_device, - NULL }, - { "[PCI] Realtek RTL8029AS", "ne2kpci", &rtl8029as_device, - NULL }, - { "", "", NULL, - NULL } -}; - - -/* Global variables. */ -int network_type; -int network_ndev; -int network_card; -char network_host[512]; -netdev_t network_devs[32]; -#ifdef ENABLE_NIC_LOG -int nic_do_log = ENABLE_NIC_LOG; -#endif -static mutex_t *network_mutex; -static uint8_t *network_mac; - - -static struct { - volatile int busy, - queue_in_use; - - event_t *wake_poll_thread, - *poll_complete, - *queue_not_in_use; -} poll_data; - - -#ifdef ENABLE_NETWORK_LOG -int network_do_log = ENABLE_NETWORK_LOG; -#endif - - -static void -network_log(const char *format, ...) -{ -#ifdef ENABLE_NETWORK_LOG - va_list ap; - - if (network_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -void -network_wait(uint8_t wait) -{ - if (wait) - thread_wait_mutex(network_mutex); - else - thread_release_mutex(network_mutex); -} - - -void -network_poll(void) -{ - while (poll_data.busy) - thread_wait_event(poll_data.wake_poll_thread, -1); - - thread_reset_event(poll_data.wake_poll_thread); -} - - -void -network_busy(uint8_t set) -{ - poll_data.busy = !!set; - - if (! set) - thread_set_event(poll_data.wake_poll_thread); -} - - -void -network_end(void) -{ - thread_set_event(poll_data.poll_complete); -} - - -/* - * Initialize the configured network cards. - * - * This function gets called only once, from the System - * Platform initialization code (currently in pc.c) to - * set our local stuff to a known state. - */ -void -network_init(void) -{ - int i; - - /* Initialize to a known state. */ - network_type = NET_TYPE_NONE; - network_card = 0; - - /* Create a first device entry that's always there, as needed by UI. */ - strcpy(network_devs[0].device, "none"); - strcpy(network_devs[0].description, "None"); - network_ndev = 1; - - /* Initialize the Pcap system module, if present. */ - i = net_pcap_prepare(&network_devs[network_ndev]); - if (i > 0) - network_ndev += i; -} - - -/* - * Attach a network card to the system. - * - * This function is called by a hardware driver ("card") after it has - * finished initializing itself, to link itself to the platform support - * modules. - */ -void -network_attach(void *dev, uint8_t *mac, NETRXCB rx) -{ - if (network_card == 0) return; - - /* Save the card's info. */ - net_cards[network_card].priv = dev; - net_cards[network_card].rx = rx; - network_mac = mac; - - /* Create the network events. */ - poll_data.wake_poll_thread = thread_create_event(); - poll_data.poll_complete = thread_create_event(); - - /* Activate the platform module. */ - switch(network_type) { - case NET_TYPE_PCAP: - (void)net_pcap_reset(&net_cards[network_card], network_mac); - break; - - case NET_TYPE_SLIRP: - (void)net_slirp_reset(&net_cards[network_card], network_mac); - break; - } -} - - -/* Stop any network activity. */ -void -network_close(void) -{ - /* If already closed, do nothing. */ - if (network_mutex == NULL) return; - - /* Force-close the PCAP module. */ - net_pcap_close(); - - /* Force-close the SLIRP module. */ - net_slirp_close(); - - /* Close the network events. */ - if (poll_data.wake_poll_thread != NULL) { - thread_destroy_event(poll_data.wake_poll_thread); - poll_data.wake_poll_thread = NULL; - } - if (poll_data.poll_complete != NULL) { - thread_destroy_event(poll_data.poll_complete); - poll_data.poll_complete = NULL; - } - - /* Close the network thread mutex. */ - thread_close_mutex(network_mutex); - network_mutex = NULL; - network_mac = NULL; - - network_log("NETWORK: closed.\n"); -} - - -/* - * Reset the network card(s). - * - * This function is called each time the system is reset, - * either a hard reset (including power-up) or a soft reset - * including C-A-D reset.) It is responsible for connecting - * everything together. - */ -void -network_reset(void) -{ - int i = -1; - -#ifdef ENABLE_NIC_LOG - network_log("NETWORK: reset (type=%d, card=%d) debug=%d\n", - network_type, network_card, nic_do_log); -#else - network_log("NETWORK: reset (type=%d, card=%d)\n", - network_type, network_card); -#endif - ui_sb_update_icon(SB_NETWORK, 0); - - /* Just in case.. */ - network_close(); - - /* If no active card, we're done. */ - if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; - - network_mutex = thread_create_mutex(L"VARCem.NetMutex"); - - /* Initialize the platform module. */ - switch(network_type) { - case NET_TYPE_PCAP: - i = net_pcap_init(); - break; - - case NET_TYPE_SLIRP: - i = net_slirp_init(); - break; - } - - if (i < 0) { - /* Tell user we can't do this (at the moment.) */ - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2102); - - // FIXME: we should ask in the dialog if they want to - // reconfigure or quit, and throw them into the - // Settings dialog if yes. - - /* Disable network. */ - network_type = NET_TYPE_NONE; - - return; - } - - network_log("NETWORK: set up for %s, card='%s'\n", - (network_type==NET_TYPE_SLIRP)?"SLiRP":"Pcap", - net_cards[network_card].name); - - /* Add the (new?) card to the I/O system. */ - if (net_cards[network_card].device) { - network_log("NETWORK: adding device '%s'\n", - net_cards[network_card].name); - device_add(net_cards[network_card].device); - } -} - - -/* Transmit a packet to one of the network providers. */ -void -network_tx(uint8_t *bufp, int len) -{ - ui_sb_update_icon(SB_NETWORK, 1); - - switch(network_type) { - case NET_TYPE_PCAP: - net_pcap_in(bufp, len); - break; - - case NET_TYPE_SLIRP: - net_slirp_in(bufp, len); - break; - } - - ui_sb_update_icon(SB_NETWORK, 0); -} - - -int -network_dev_to_id(char *devname) -{ - int i = 0; - - for (i=0; iconfig ? 1 : 0); -} - - -/* UI */ -char * -network_card_get_internal_name(int card) -{ - return((char *)net_cards[card].internal_name); -} - - -/* UI */ -int -network_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen((char *)net_cards[c].internal_name)) { - if (! strcmp((char *)net_cards[c].internal_name, s)) - return(c); - c++; - } - - return(-1); -} diff --git a/src - Cópia/network/network.h b/src - Cópia/network/network.h deleted file mode 100644 index bdd4beb54..000000000 --- a/src - Cópia/network/network.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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 network module. - * - * Version: @(#)network.h 1.0.2 2018/03/15 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef EMU_NETWORK_H -# define EMU_NETWORK_H -# include - - -/* Network provider types. */ -#define NET_TYPE_NONE 0 /* networking disabled */ -#define NET_TYPE_PCAP 1 /* use the (Win)Pcap API */ -#define NET_TYPE_SLIRP 2 /* use the SLiRP port forwarder */ - -/* Supported network cards. */ -enum { - NONE = 0, - NE1000, - NE2000, - RTL8019AS, - RTL8029AS -}; - - -typedef void (*NETRXCB)(void *, uint8_t *, int); - - -typedef struct { - const char *name; - const char *internal_name; - const device_t *device; - void *priv; - int (*poll)(void *); - NETRXCB rx; -} netcard_t; - -typedef struct { - char device[128]; - char description[128]; -} netdev_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global variables. */ -extern int nic_do_log; /* config */ -extern int network_ndev; -extern netdev_t network_devs[32]; - - -/* Function prototypes. */ -extern void network_wait(uint8_t wait); -extern void network_poll(void); -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_close(void); -extern void network_reset(void); -extern int network_available(void); -extern void network_tx(uint8_t *, int); - -extern int net_pcap_prepare(netdev_t *); -extern int net_pcap_init(void); -extern int net_pcap_reset(const netcard_t *, uint8_t *); -extern void net_pcap_close(void); -extern void net_pcap_in(uint8_t *, int); - -extern int net_slirp_init(void); -extern int net_slirp_reset(const netcard_t *, uint8_t *); -extern void net_slirp_close(void); -extern void net_slirp_in(uint8_t *, int); - -extern int network_dev_to_id(char *); -extern int network_card_available(int); -extern char *network_card_getname(int); -extern int network_card_has_config(int); -extern char *network_card_get_internal_name(int); -extern int network_card_get_from_internal_name(char *); -extern const device_t *network_card_getdevice(int); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_NETWORK_H*/ diff --git a/src - Cópia/network/pcap_if.c b/src - Cópia/network/pcap_if.c deleted file mode 100644 index 439dbfa94..000000000 --- a/src - Cópia/network/pcap_if.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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. - * - * Simple program to show usage of (Win)Pcap. - * - * Based on the "libpcap" examples. - * - * Version: @(#)pcap_if.c 1.0.10 2018/03/10 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../plat.h" -#include "../plat_dynld.h" - - -static void *pcap_handle; /* handle to WinPcap DLL */ - - -/* Pointers to the real functions. */ -static int (*f_pcap_findalldevs)(pcap_if_t **,char *); -static void (*f_pcap_freealldevs)(pcap_if_t *); -static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); -static int (*f_pcap_next_ex)(pcap_t*,struct pcap_pkthdr**,const unsigned char**); -static void (*f_pcap_close)(pcap_t *); -static dllimp_t pcap_imports[] = { - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_next_ex", &f_pcap_next_ex }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, -}; - - -typedef struct { - char device[128]; - char description[128]; -} capdev_t; - - -/* Retrieve an easy-to-use list of devices. */ -static int -get_devlist(capdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist, *dev; - int i = 0; - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); - return(-1); - } - - for (dev=devlist; dev!=NULL; dev=dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; - i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return(i); -} - - -/* Simple HEXDUMP routine for raw data. */ -static void -hex_dump(unsigned char *bufp, int len) -{ - char asci[20]; - unsigned char c; - long addr; - - addr = 0; - while (len-- > 0) { - c = bufp[addr]; - if ((addr % 16) == 0) - printf("%04lx %02x", addr, c); - else - printf(" %02x", c); - asci[(addr & 15)] = (uint8_t)isprint(c) ? c : '.'; - if ((++addr % 16) == 0) { - asci[16] = '\0'; - printf(" | %s |\n", asci); - } - } - - if (addr % 16) { - while (addr % 16) { - printf(" "); - asci[(addr & 15)] = ' '; - addr++; - } - asci[16] = '\0'; - printf(" | %s |\n", asci); - } -} - - -/* Print a standard Ethernet MAC address. */ -static void -eth_praddr(unsigned char *ptr) -{ - printf("%02x:%02x:%02x:%02x:%02x:%02x", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); -} - - -/* Print a standard Ethernet header. */ -static int -eth_prhdr(unsigned char *ptr) -{ - unsigned short type; - - printf("Ethernet "); - eth_praddr(ptr+6); - printf(" > "); - eth_praddr(ptr); - type = (ptr[12] << 8) | ptr[13]; - printf(" type %04x\n", type); - - return(14); -} - - -/* Capture packets from the network, and print them. */ -static int -start_cap(char *dev) -{ - char temp[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr *hdr; - const unsigned char *pkt; - struct tm *ltime; - time_t now; - pcap_t *pcap; - int rc; - - /* Open the device for reading from it. */ - pcap = f_pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); - if (pcap == NULL) { - fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); - return(2); - } - - printf("Listening on '%s'..\n", dev); - for (;;) { - rc = f_pcap_next_ex(pcap, &hdr, &pkt); - if (rc < 0) break; - - /* Did we time out? */ - if (rc == 0) continue; - - /* Convert the timestamp to readable format. */ - now = hdr->ts.tv_sec; - ltime = localtime(&now); - strftime(temp, sizeof(temp), "%H:%M:%S", ltime); - - /* Process and print the packet. */ - printf("\n<< %s,%.6ld len=%u\n", - temp, hdr->ts.tv_usec, hdr->len); - rc = eth_prhdr((unsigned char *)pkt); - hex_dump((unsigned char *)pkt+rc, hdr->len-rc); - } - - /* All done, close up. */ - f_pcap_close(pcap); - - return(0); -} - - -/* Show a list of available network interfaces. */ -static void -show_devs(capdev_t *list, int num) -{ - int i; - - if (num > 0) { - printf("Available network interfaces:\n\n"); - - for (i=0; idevice); - if (list->description[0] != '\0') - printf(" (%s)\n", list->description); - else - printf(" (No description available)\n"); - list++; - printf("\n"); - } - } else { - printf("No interfaces found!\nMake sure WinPcap is installed.\n"); - } -} - - -void -pclog(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - - -int -main(int argc, char **argv) -{ - capdev_t interfaces[32]; - int numdev, i; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) { -#ifdef _WIN32 - fprintf(stderr, "Unable to load WinPcap DLL !\n"); -#else - fprintf(stderr, "Unable to load libpcap.so !\n"); -#endif - return(1); - } - - /* Get the list. */ - numdev = get_devlist(interfaces); - - if (argc == 1) { - /* No arguments, just show the list. */ - show_devs(interfaces, numdev); - - dynld_close(pcap_handle); - - return(numdev); - } - - /* Assume argument to be the interface number to listen on. */ - i = atoi(argv[1]); - if (i < 0 || i > numdev) { - fprintf(stderr, "Invalid interface number %d !\n", i); - - dynld_close(pcap_handle); - - return(1); - } - - /* Looks good, go and listen.. */ - i = start_cap(interfaces[i-1].device); - - dynld_close(pcap_handle); - - return(i); -} diff --git a/src - Cópia/network/slirp/COPYRIGHT.txt b/src - Cópia/network/slirp/COPYRIGHT.txt deleted file mode 100644 index 62ccebae1..000000000 --- a/src - Cópia/network/slirp/COPYRIGHT.txt +++ /dev/null @@ -1,61 +0,0 @@ -Slirp was written by Danny Gasparovski. -Copyright (c), 1995,1996 All Rights Reserved. - -Slirp is maintained by Kelly Price - -Slirp is free software; "free" as in you don't have to pay for it, and you -are free to do whatever you want with it. I do not accept any donations, -monetary or otherwise, for Slirp. Instead, I would ask you to pass this -potential donation to your favorite charity. In fact, I encourage -*everyone* who finds Slirp useful to make a small donation to their -favorite charity (for example, GreenPeace). This is not a requirement, but -a suggestion from someone who highly values the service they provide. - -The copyright terms and conditions: - ----BEGIN--- - - Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - DANNY GASPAROVSKI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----END--- - -This basically means you can do anything you want with the software, except -1) call it your own, and 2) claim warranty on it. There is no warranty for -this software. None. Nada. If you lose a million dollars while using -Slirp, that's your loss not mine. So, ***USE AT YOUR OWN RISK!***. - -If these conditions cannot be met due to legal restrictions (E.g. where it -is against the law to give out Software without warranty), you must cease -using the software and delete all copies you have. - -Slirp uses code that is copyrighted by the following people/organizations: - -Juha Pirkola. -Gregory M. Christy. -The Regents of the University of California. -Carnegie Mellon University. -The Australian National University. -RSA Data Security, Inc. - -Please read the top of each source file for the details on the various -copyrights. \ No newline at end of file diff --git a/src - Cópia/network/slirp/VERSION.txt b/src - Cópia/network/slirp/VERSION.txt deleted file mode 100644 index 0dd1c2b2b..000000000 --- a/src - Cópia/network/slirp/VERSION.txt +++ /dev/null @@ -1 +0,0 @@ -qemu 0.9.0 (2007/02/05) \ No newline at end of file diff --git a/src - Cópia/network/slirp/bootp.c b/src - Cópia/network/slirp/bootp.c deleted file mode 100644 index 9cbca7520..000000000 --- a/src - Cópia/network/slirp/bootp.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * QEMU BOOTP/DHCP server - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "slirp.h" - -/* XXX: only DHCP is supported */ - -#define NB_ADDR 16 - -#define START_ADDR 15 - -#define LEASE_TIME (24 * 3600) - -typedef struct { - uint8_t allocated; - uint8_t macaddr[6]; -} BOOTPClient; - -BOOTPClient bootp_clients[NB_ADDR]; - -static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; - -static BOOTPClient *get_new_addr(struct in_addr *paddr) -{ - BOOTPClient *bc; - int i; - - for(i = 0; i < NB_ADDR; i++) { - if (!bootp_clients[i].allocated) - goto found; - } - return NULL; - found: - bc = &bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); - return bc; -} - -static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr) -{ - BOOTPClient *bc; - int i; - - for(i = 0; i < NB_ADDR; i++) { - if (!memcmp(macaddr, bootp_clients[i].macaddr, 6)) - goto found; - } - return NULL; - found: - bc = &bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); - return bc; -} - -static void dhcp_decode(const uint8_t *buf, int size, - int *pmsg_type) -{ - const uint8_t *p, *p_end; - int len, tag; - - *pmsg_type = 0; - - p = buf; - p_end = buf + size; - if (size < 5) - return; - if (memcmp(p, rfc1533_cookie, 4) != 0) - return; - p += 4; - while (p < p_end) { - tag = p[0]; - if (tag == RFC1533_PAD) { - p++; - } else if (tag == RFC1533_END) { - break; - } else { - p++; - if (p >= p_end) - break; - len = *p++; - - switch(tag) { - case RFC2132_MSG_TYPE: - if (len >= 1) - *pmsg_type = p[0]; - break; - default: - break; - } - p += len; - } - } -} - -static void bootp_reply(struct bootp_t *bp) -{ - BOOTPClient *bc; - struct SLIRPmbuf *m; - struct bootp_t *rbp; - struct sockaddr_in saddr, daddr; - struct in_addr dns_addr; - int dhcp_msg_type, val; - uint8_t *q; - - /* extract exact DHCP msg type */ - dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); - - if (dhcp_msg_type == 0) - dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ - - if (dhcp_msg_type != DHCPDISCOVER && - dhcp_msg_type != DHCPREQUEST) - return; - /* XXX: this is a hack to get the client mac address */ - memcpy(client_ethaddr, bp->bp_hwaddr, 6); - - if ((m = m_get()) == NULL) - return; - m->m_data += if_maxlinkhdr; - rbp = (struct bootp_t *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - memset(rbp, 0, sizeof(struct bootp_t)); - - if (dhcp_msg_type == DHCPDISCOVER) { - new_addr: - bc = get_new_addr(&daddr.sin_addr); - if (!bc) - return; - memcpy(bc->macaddr, client_ethaddr, 6); - } else { - bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); - if (!bc) { - /* if never assigned, behaves as if it was already - assigned (windows fix because it remembers its address) */ - goto new_addr; - } - } - - saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); - saddr.sin_port = htons(BOOTP_SERVER); - - daddr.sin_port = htons(BOOTP_CLIENT); - - rbp->bp_op = BOOTP_REPLY; - rbp->bp_xid = bp->bp_xid; - rbp->bp_htype = 1; - rbp->bp_hlen = 6; - memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); - - rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ - rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ - - q = rbp->bp_vend; - memcpy(q, rfc1533_cookie, 4); - q += 4; - - if (dhcp_msg_type == DHCPDISCOVER) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPOFFER; - } else if (dhcp_msg_type == DHCPREQUEST) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPACK; - } - - if (dhcp_msg_type == DHCPDISCOVER || - dhcp_msg_type == DHCPREQUEST) { - *q++ = RFC2132_SRV_ID; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_NETMASK; - *q++ = 4; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0x00; - - *q++ = RFC1533_GATEWAY; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_DNS; - *q++ = 4; - dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); - memcpy(q, &dns_addr, 4); - q += 4; - - *q++ = RFC2132_LEASE_TIME; - *q++ = 4; - val = htonl(LEASE_TIME); - memcpy(q, &val, 4); - q += 4; - - if (*slirp_hostname) { - val = strlen(slirp_hostname); - *q++ = RFC1533_HOSTNAME; - *q++ = val; - memcpy(q, slirp_hostname, val); - q += val; - } - } - *q++ = RFC1533_END; - - m->m_len = sizeof(struct bootp_t) - - sizeof(struct ip) - sizeof(struct udphdr); - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); -} - -void bootp_input(struct SLIRPmbuf *m) -{ - struct bootp_t *bp = mtod(m, struct bootp_t *); - - if (bp->bp_op == BOOTP_REQUEST) { - bootp_reply(bp); - } -} diff --git a/src - Cópia/network/slirp/bootp.h b/src - Cópia/network/slirp/bootp.h deleted file mode 100644 index b2ee26e95..000000000 --- a/src - Cópia/network/slirp/bootp.h +++ /dev/null @@ -1,121 +0,0 @@ -/* bootp/dhcp defines */ - -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 - -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 - -#define RFC1533_COOKIE 99, 130, 83, 99 -#define RFC1533_PAD 0 -#define RFC1533_NETMASK 1 -#define RFC1533_TIMEOFFSET 2 -#define RFC1533_GATEWAY 3 -#define RFC1533_TIMESERVER 4 -#define RFC1533_IEN116NS 5 -#define RFC1533_DNS 6 -#define RFC1533_LOGSERVER 7 -#define RFC1533_COOKIESERVER 8 -#define RFC1533_LPRSERVER 9 -#define RFC1533_IMPRESSSERVER 10 -#define RFC1533_RESOURCESERVER 11 -#define RFC1533_HOSTNAME 12 -#define RFC1533_BOOTFILESIZE 13 -#define RFC1533_MERITDUMPFILE 14 -#define RFC1533_DOMAINNAME 15 -#define RFC1533_SWAPSERVER 16 -#define RFC1533_ROOTPATH 17 -#define RFC1533_EXTENSIONPATH 18 -#define RFC1533_IPFORWARDING 19 -#define RFC1533_IPSOURCEROUTING 20 -#define RFC1533_IPPOLICYFILTER 21 -#define RFC1533_IPMAXREASSEMBLY 22 -#define RFC1533_IPTTL 23 -#define RFC1533_IPMTU 24 -#define RFC1533_IPMTUPLATEAU 25 -#define RFC1533_INTMTU 26 -#define RFC1533_INTLOCALSUBNETS 27 -#define RFC1533_INTBROADCAST 28 -#define RFC1533_INTICMPDISCOVER 29 -#define RFC1533_INTICMPRESPOND 30 -#define RFC1533_INTROUTEDISCOVER 31 -#define RFC1533_INTROUTESOLICIT 32 -#define RFC1533_INTSTATICROUTES 33 -#define RFC1533_LLTRAILERENCAP 34 -#define RFC1533_LLARPCACHETMO 35 -#define RFC1533_LLETHERNETENCAP 36 -#define RFC1533_TCPTTL 37 -#define RFC1533_TCPKEEPALIVETMO 38 -#define RFC1533_TCPKEEPALIVEGB 39 -#define RFC1533_NISDOMAIN 40 -#define RFC1533_NISSERVER 41 -#define RFC1533_NTPSERVER 42 -#define RFC1533_VENDOR 43 -#define RFC1533_NBNS 44 -#define RFC1533_NBDD 45 -#define RFC1533_NBNT 46 -#define RFC1533_NBSCOPE 47 -#define RFC1533_XFS 48 -#define RFC1533_XDM 49 - -#define RFC2132_REQ_ADDR 50 -#define RFC2132_LEASE_TIME 51 -#define RFC2132_MSG_TYPE 53 -#define RFC2132_SRV_ID 54 -#define RFC2132_PARAM_LIST 55 -#define RFC2132_MAX_SIZE 57 -#define RFC2132_RENEWAL_TIME 58 -#define RFC2132_REBIND_TIME 59 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPACK 5 - -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 - -#define RFC1533_VENDOR_MAGIC 128 -#define RFC1533_VENDOR_ADDPARM 129 -#define RFC1533_VENDOR_ETHDEV 130 -#define RFC1533_VENDOR_HOWTO 132 -#define RFC1533_VENDOR_MNUOPTS 160 -#define RFC1533_VENDOR_SELECTION 176 -#define RFC1533_VENDOR_MOTD 184 -#define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 - -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#define DHCP_OPT_LEN 312 - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct bootp_t { - struct ip ip; - struct udphdr udp; - uint8_t bp_op; - uint8_t bp_htype; - uint8_t bp_hlen; - uint8_t bp_hops; - uint32_t bp_xid; - uint16_t bp_secs; - uint16_t unused; - struct in_addr bp_ciaddr; - struct in_addr bp_yiaddr; - struct in_addr bp_siaddr; - struct in_addr bp_giaddr; - uint8_t bp_hwaddr[16]; - uint8_t bp_sname[64]; - uint8_t bp_file[128]; - uint8_t bp_vend[DHCP_OPT_LEN]; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -void bootp_input(struct SLIRPmbuf *m); diff --git a/src - Cópia/network/slirp/cksum.c b/src - Cópia/network/slirp/cksum.c deleted file mode 100644 index eb0ae547f..000000000 --- a/src - Cópia/network/slirp/cksum.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 1988, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 - * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp - */ - -#include "slirp.h" - -/* - * Checksum routine for Internet Protocol family headers (Portable Version). - * - * This routine is very heavily used in the network - * code and should be modified for each CPU to be as fast as possible. - * - * XXX Since we will never span more than 1 SLIRPmbuf, we can optimise this - */ - -#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) -#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} - -int cksum(struct SLIRPmbuf *m, int len) -{ - register u_int16_t *w; - register int sum = 0; - register int mlen = 0; - int byte_swapped = 0; - - union { - u_int8_t c[2]; - u_int16_t s; - } s_util; - union { - u_int16_t s[2]; - u_int32_t l; - } l_util; - - if (m->m_len == 0) - goto cont; - w = mtod(m, u_int16_t *); - - mlen = m->m_len; - - if (len < mlen) - mlen = len; - len -= mlen; - /* - * Force to even boundary. - */ - if ((1 & (intptr_t) w) && (mlen > 0)) { - REDUCE; - sum <<= 8; - s_util.c[0] = *(u_int8_t *)w; - w = (u_int16_t *)((int8_t *)w + 1); - mlen--; - byte_swapped = 1; - } - /* - * Unroll the loop to make overhead from - * branches &c small. - */ - while ((mlen -= 32) >= 0) { - sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; - sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; - sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; - sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; - w += 16; - } - mlen += 32; - while ((mlen -= 8) >= 0) { - sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; - w += 4; - } - mlen += 8; - if (mlen == 0 && byte_swapped == 0) - goto cont; - REDUCE; - while ((mlen -= 2) >= 0) { - sum += *w++; - } - - if (byte_swapped) { - REDUCE; - sum <<= 8; - byte_swapped = 0; - if (mlen == -1) { - s_util.c[1] = *(u_int8_t *)w; - sum += s_util.s; - mlen = 0; - } else - - mlen = -1; - } else if (mlen == -1) - s_util.c[0] = *(u_int8_t *)w; - -cont: -#ifdef SLIRP_DEBUG - if (len) { - DEBUG_ERROR((dfd, "cksum: out of data\n")); - DEBUG_ERROR((dfd, " len = %d\n", len)); - } -#endif - if (mlen == -1) { - /* The last SLIRPmbuf has odd # of bytes. Follow the - standard (the odd byte may be shifted left by 8 bits - or not as determined by endian-ness of the machine) */ - s_util.c[1] = 0; - sum += s_util.s; - } - REDUCE; - return (~sum & 0xffff); -} diff --git a/src - Cópia/network/slirp/config-host.h b/src - Cópia/network/slirp/config-host.h deleted file mode 100644 index 2983fc727..000000000 --- a/src - Cópia/network/slirp/config-host.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Automatically generated by configure - do not modify */ -#define CONFIG_QEMU_SHAREDIR "/c/Program Files/Qemu" -#define HOST_I386 1 -#define HOST_LONG_BITS 32 -#define CONFIG_WIN32 1 -#define CONFIG_GDBSTUB 1 -#define CONFIG_SLIRP 1 -#define QEMU_VERSION "0.9.0" -#define CONFIG_UNAME_RELEASE "" diff --git a/src - Cópia/network/slirp/config.h b/src - Cópia/network/slirp/config.h deleted file mode 100644 index d9043ae85..000000000 --- a/src - Cópia/network/slirp/config.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Automatically generated by configure - do not modify */ -#include "config-host.h" -#define CONFIG_QEMU_PREFIX "/usr/gnemul/qemu-i386" -#define TARGET_ARCH "i386" -#define TARGET_I386 1 -#define USE_KQEMU 1 -#define CONFIG_SOFTMMU 1 -#define CONFIG_SDL 1 -#define HAVE_STRDUP 1 diff --git a/src - Cópia/network/slirp/ctl.h b/src - Cópia/network/slirp/ctl.h deleted file mode 100644 index 4a8576dc1..000000000 --- a/src - Cópia/network/slirp/ctl.h +++ /dev/null @@ -1,7 +0,0 @@ -#define CTL_CMD 0 -#define CTL_EXEC 1 -#define CTL_ALIAS 2 -#define CTL_DNS 3 - -#define CTL_SPECIAL "10.0.2.0" -#define CTL_LOCAL "10.0.2.15" diff --git a/src - Cópia/network/slirp/debug.c b/src - Cópia/network/slirp/debug.c deleted file mode 100644 index eef2c7de1..000000000 --- a/src - Cópia/network/slirp/debug.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * Portions copyright (c) 2000 Kelly Price. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _WIN32 -# include -#endif -#include "slirp.h" - -FILE *dfd = NULL; -#ifdef SLIRP_DEBUG -int dostats = 1; -#else -int dostats = 0; -#endif -int slirp_debug = 0; - -#ifndef _MSC_VER -extern char *strerror _P((int)); -#endif - -/* Carry over one item from main.c so that the tty's restored. - * Only done when the tty being used is /dev/tty --RedWolf */ -extern struct termios slirp_tty_settings; -extern int slirp_tty_restore; - - -void -debug_init(file, dbg) - char *file; - int dbg; -{ - /* Close the old debugging file */ - if (dfd) - fclose(dfd); - - dfd = fopen(file,"w"); - if (dfd != NULL) { -#if 1 - fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION); -#endif - fprintf(dfd,"Debugging Started level %i.\r\n",dbg); - fflush(dfd); - slirp_debug = dbg; - } else { - lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n", - file, strerror(errno)); - } -} - -/* - * Dump a packet in the same format as tcpdump -x - */ -#ifdef SLIRP_DEBUG -void -dump_packet(dat, n) - void *dat; - int n; -{ - u_char *pptr = (u_char *)dat; - int j,k; - - n /= 16; - n++; - DEBUG_MISC((dfd, "PACKET DUMPED: \n")); - for(j = 0; j < n; j++) { - for(k = 0; k < 6; k++) - DEBUG_MISC((dfd, "%02x ", *pptr++)); - DEBUG_MISC((dfd, "\n")); - fflush(dfd); - } -} -#endif - -#if 0 -/* - * Statistic routines - * - * These will print statistics to the screen, the debug file (dfd), or - * a buffer, depending on "type", so that the stats can be sent over - * the link as well. - */ - -void -ttystats(ttyp) - struct ttys *ttyp; -{ - struct slirp_ifstats *is = &ttyp->ifstats; - char buff[512]; - - lprint(" \r\n"); - - if (if_comp & IF_COMPRESS) - strcpy(buff, "on"); - else if (if_comp & IF_NOCOMPRESS) - strcpy(buff, "off"); - else - strcpy(buff, "off (for now)"); - lprint("Unit %d:\r\n", ttyp->unit); - lprint(" using %s encapsulation (VJ compression is %s)\r\n", ( -#ifdef USE_PPP - ttyp->proto==PROTO_PPP?"PPP": -#endif - "SLIP"), buff); - lprint(" %d baudrate\r\n", ttyp->baud); - lprint(" interface is %s\r\n", ttyp->up?"up":"down"); - lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid); -#ifndef FULL_BOLT - lprint(" towrite is %d bytes\r\n", ttyp->towrite); -#endif - if (ttyp->zeros) - lprint(" %d zeros have been typed\r\n", ttyp->zeros); - else if (ttyp->ones) - lprint(" %d ones have been typed\r\n", ttyp->ones); - lprint("Interface stats:\r\n"); - lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes); - lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes); - lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes); - lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes); - lprint(" %6d bad input packets\r\n", is->in_mbad); -} - -void -allttystats() -{ - struct ttys *ttyp; - - for (ttyp = ttys; ttyp; ttyp = ttyp->next) - ttystats(ttyp); -} -#endif - -void -ipstats() -{ - lprint(" \r\n"); - - lprint("IP stats:\r\n"); - lprint(" %6d total packets received (%d were unaligned)\r\n", - ipstat.ips_total, ipstat.ips_unaligned); - lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers); - lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum); - lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort); - lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall); - lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen); - lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen); - lprint(" %6d fragments received\r\n", ipstat.ips_fragments); - lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped); - lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout); - lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled); - lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented); - lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments); - lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto); - lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); -} - -#if 0 -void -vjstats() -{ - lprint(" \r\n"); - - lprint("VJ compression stats:\r\n"); - - lprint(" %6d outbound packets (%d compressed)\r\n", - comp_s.sls_packets, comp_s.sls_compressed); - lprint(" %6d searches for connection stats (%d misses)\r\n", - comp_s.sls_searches, comp_s.sls_misses); - lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin); - lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin); - lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin); - lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed); -} -#endif - -void -tcpstats() -{ - lprint(" \r\n"); - - lprint("TCP stats:\r\n"); - - lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal); - lprint(" %6d data packets (%d bytes)\r\n", - tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte); - lprint(" %6d data packets retransmitted (%d bytes)\r\n", - tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte); - lprint(" %6d ack-only packets (%d delayed)\r\n", - tcpstat.tcps_sndacks, tcpstat.tcps_delack); - lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg); - lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe); - lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup); - lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl); - lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin); - - lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); - lprint(" %6d acks (for %d bytes)\r\n", - tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte); - lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack); - lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch); - lprint(" %6d packets received in sequence (%d bytes)\r\n", - tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte); - lprint(" %6d completely duplicate packets (%d bytes)\r\n", - tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte); - - lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n", - tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte); - lprint(" %6d out-of-order packets (%d bytes)\r\n", - tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte); - lprint(" %6d packets of data after window (%d bytes)\r\n", - tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin); - lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe); - lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd); - lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose); - lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum); - lprint(" %6d discarded for bad header offset fields\r\n", - tcpstat.tcps_rcvbadoff); - - lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt); - lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts); - lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects); - lprint(" %6d connections closed (including %d drop)\r\n", - tcpstat.tcps_closed, tcpstat.tcps_drops); - lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops); - lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n", - tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated); - lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo); - lprint(" %6d connections dropped by rxmt timeout\r\n", - tcpstat.tcps_timeoutdrop); - lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo); - lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo); - lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe); - lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops); - lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack); - lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat); - lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss); - - -/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */ -/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */ - -} - -void -udpstats() -{ - lprint(" \r\n"); - - lprint("UDP stats:\r\n"); - lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets); - lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops); - lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum); - lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen); - lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss); - lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); -} - -void -icmpstats() -{ - lprint(" \r\n"); - lprint("ICMP stats:\r\n"); - lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received); - lprint(" %6d were too short\r\n", icmpstat.icps_tooshort); - lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum); - lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp); - lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype); - lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); -} - -void -mbufstats() -{ - struct SLIRPmbuf *m; - int i; - - lprint(" \r\n"); - - lprint("Mbuf stats:\r\n"); - - lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); - - i = 0; - for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next) - i++; - lprint(" %6d mbufs on free list\r\n", i); - - i = 0; - for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) - i++; - lprint(" %6d mbufs on used list\r\n", i); - lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); -} - - -void sockstats(void) -{ - char buff[256]; - int n; - struct SLIRPsocket *so; - - lprint(" \r\n"); - - lprint( - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); - - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - - n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - lprint("%s %3d %15s %5d ", - buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); - lprint("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - - } - - for (so = udb.so_next; so != &udb; so = so->so_next) { - - n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - lprint("%s %3d %15s %5d ", - buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); - lprint("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - } -} - - - -void printf_sockstats(void) -{ - char buff[256]; - int n; - struct SLIRPsocket *so; - - printf(" \r\n"); - - printf( - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); - - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - - n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - printf("%s %3d %15s %5d ", - buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); - printf("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - - } - - for (so = udb.so_next; so != &udb; so = so->so_next) { - - n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - printf("%s %3d %15s %5d ", - buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); - printf("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - } -printf("\n\n"); -} - -//Simple code to purge and close open sockets. -//This way we can open/close/open/close.. -void purgesocks(void) -{ - struct SLIRPsocket *so; - - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - - closesocket(so->s); //close the socket - } -} - -#if 1 -void -slirp_exit(exit_status) - int exit_status; -{ -// struct ttys *ttyp; - - DEBUG_CALL("slirp_exit"); - DEBUG_ARG("exit_status = %d", exit_status); - - if (dostats) { - lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf; - if (!dfd) - debug_init("slirp_stats", 0xf); - lprint_arg = (char **)&dfd; - - ipstats(); - tcpstats(); - udpstats(); - icmpstats(); - mbufstats(); - sockstats(); - fclose(dfd); -// allttystats(); -// vjstats(); - } - -// for (ttyp = ttys; ttyp; ttyp = ttyp->next) -// tty_detached(ttyp, 1); - -// if (slirp_forked) { -// /* Menendez time */ -// if (kill(getppid(), SIGQUIT) < 0) -// lprint("Couldn't kill parent process %ld!\n", -// (long) getppid()); -// } - - /* Restore the terminal if we gotta */ -// if(slirp_tty_restore) -// tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */ -// exit(exit_status); - - //This will iterate though the sockets, and close them all (think redirects) - //PCem will have SLiRP open, close several times, which trips up SLiRP - //So for now I go through the sockets and close them - purgesocks(); - -} -#endif diff --git a/src - Cópia/network/slirp/debug.h b/src - Cópia/network/slirp/debug.h deleted file mode 100644 index a1eafa130..000000000 --- a/src - Cópia/network/slirp/debug.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define PRN_STDERR 1 -#define PRN_SPRINTF 2 - -extern FILE *dfd; -extern FILE *lfd; -extern int dostats; -extern int slirp_debug; - -#define DBG_CALL 0x1 -#define DBG_MISC 0x2 -#define DBG_ERROR 0x4 -#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR - -#ifdef SLIRP_DEBUG -#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); } -#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); } -#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); } -#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); } -#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); } - - -#else - -#define DEBUG_CALL(x) -#define DEBUG_ARG(x, y) -#define DEBUG_ARGS(x) -#define DEBUG_MISC(x) -#define DEBUG_ERROR(x) - -#endif - -void debug_init _P((char *, int)); -void allttystats _P((void)); -void ipstats _P((void)); -void vjstats _P((void)); -void tcpstats _P((void)); -void udpstats _P((void)); -void icmpstats _P((void)); -void mbufstats _P((void)); -void sockstats _P((void)); -void slirp_exit _P((int)); - diff --git a/src - Cópia/network/slirp/icmp_var.h b/src - Cópia/network/slirp/icmp_var.h deleted file mode 100644 index 9af222fb7..000000000 --- a/src - Cópia/network/slirp/icmp_var.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93 - * icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp - */ - -#ifndef _NETINET_ICMP_VAR_H_ -#define _NETINET_ICMP_VAR_H_ - -/* - * Variables related to this implementation - * of the internet control message protocol. - */ -struct icmpstat { -/* statistics related to input messages processed */ - u_long icps_received; /* #ICMP packets received */ - u_long icps_tooshort; /* packet < ICMP_MINLEN */ - u_long icps_checksum; /* bad checksum */ - u_long icps_notsupp; /* #ICMP packets not supported */ - u_long icps_badtype; /* #with bad type feild */ - u_long icps_reflect; /* number of responses */ -}; - -/* - * Names for ICMP sysctl objects - */ -#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ -#define ICMPCTL_STATS 2 /* statistics (read-only) */ -#define ICMPCTL_MAXID 3 - -#define ICMPCTL_NAMES { \ - { 0, 0 }, \ - { "maskrepl", CTLTYPE_INT }, \ - { "stats", CTLTYPE_STRUCT }, \ -} - -extern struct icmpstat icmpstat; - -#endif diff --git a/src - Cópia/network/slirp/if.c b/src - Cópia/network/slirp/if.c deleted file mode 100644 index 24f1b9947..000000000 --- a/src - Cópia/network/slirp/if.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include "slirp.h" - -int if_mtu, if_mru; -int if_comp; -int if_maxlinkhdr; -int if_queued = 0; /* Number of packets queued so far */ -int if_thresh = 10; /* Number of packets queued before we start sending - * (to prevent allocing too many SLIRPmbufs) */ - -struct SLIRPmbuf if_fastq; /* fast queue (for interactive data) */ -struct SLIRPmbuf if_batchq; /* queue for non-interactive data */ -struct SLIRPmbuf *next_m; /* Pointer to next SLIRPmbuf to output */ - -#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) - -void -ifs_insque(ifm, ifmhead) - struct SLIRPmbuf *ifm, *ifmhead; -{ - ifm->ifs_next = ifmhead->ifs_next; - ifmhead->ifs_next = ifm; - ifm->ifs_prev = ifmhead; - ifm->ifs_next->ifs_prev = ifm; -} - -void -ifs_remque(ifm) - struct SLIRPmbuf *ifm; -{ - ifm->ifs_prev->ifs_next = ifm->ifs_next; - ifm->ifs_next->ifs_prev = ifm->ifs_prev; -} - -void -if_init() -{ -#if 0 - /* - * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, - * and 8 bytes for PPP, but need to have it on an 8byte boundary - */ -#ifdef USE_PPP - if_maxlinkhdr = 48; -#else - if_maxlinkhdr = 40; -#endif -#else - /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ - if_maxlinkhdr = 2 + 14 + 40; -#endif - if_mtu = 1500; - if_mru = 1500; - if_comp = IF_AUTOCOMP; - if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; - if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; - // sl_compress_init(&comp_s); - next_m = &if_batchq; -} - -#if 0 -/* - * This shouldn't be needed since the modem is blocking and - * we don't expect any signals, but what the hell.. - */ -inline int -writen(fd, bptr, n) - int fd; - char *bptr; - int n; -{ - int ret; - int total; - - /* This should succeed most of the time */ - ret = send(fd, bptr, n,0); - if (ret == n || ret <= 0) - return ret; - - /* Didn't write everything, go into the loop */ - total = ret; - while (n > total) { - ret = send(fd, bptr+total, n-total,0); - if (ret <= 0) - return ret; - total += ret; - } - return total; -} - -/* - * if_input - read() the tty, do "top level" processing (ie: check for any escapes), - * and pass onto (*ttyp->if_input) - * - * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. - */ -#define INBUFF_SIZE 2048 /* XXX */ -void -if_input(ttyp) - struct ttys *ttyp; -{ - u_char if_inbuff[INBUFF_SIZE]; - int if_n; - - DEBUG_CALL("if_input"); - DEBUG_ARG("ttyp = %lx", (long)ttyp); - - if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); - - DEBUG_MISC((dfd, " read %d bytes\n", if_n)); - - if (if_n <= 0) { - if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { - if (ttyp->up) - link_up--; - tty_detached(ttyp, 0); - } - return; - } - if (if_n == 1) { - if (*if_inbuff == '0') { - ttyp->ones = 0; - if (++ttyp->zeros >= 5) - slirp_exit(0); - return; - } - if (*if_inbuff == '1') { - ttyp->zeros = 0; - if (++ttyp->ones >= 5) - tty_detached(ttyp, 0); - return; - } - } - ttyp->ones = ttyp->zeros = 0; - - (*ttyp->if_input)(ttyp, if_inbuff, if_n); -} -#endif - -/* - * if_output: Queue packet into an output queue. - * There are 2 output queue's, if_fastq and if_batchq. - * Each output queue is a doubly linked list of double linked lists - * of SLIRPmbufs, each list belonging to one "session" (socket). This - * way, we can output packets fairly by sending one packet from each - * session, instead of all the packets from one session, then all packets - * from the next session, etc. Packets on the if_fastq get absolute - * priority, but if one session hogs the link, it gets "downgraded" - * to the batchq until it runs out of packets, then it'll return - * to the fastq (eg. if the user does an ls -alR in a telnet session, - * it'll temporarily get downgraded to the batchq) - */ -void -if_output(so, ifm) - struct SLIRPsocket *so; - struct SLIRPmbuf *ifm; -{ - struct SLIRPmbuf *ifq; - int on_fastq = 1; - - DEBUG_CALL("if_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("ifm = %lx", (long)ifm); - - /* - * First remove the SLIRPmbuf from m_usedlist, - * since we're gonna use m_next and m_prev ourselves - * XXX Shouldn't need this, gotta change dtom() etc. - */ - if (ifm->m_flags & M_USEDLIST) { - remque(ifm); - ifm->m_flags &= ~M_USEDLIST; - } - - /* - * See if there's already a batchq list for this session. - * This can include an interactive session, which should go on fastq, - * but gets too greedy... hence it'll be downgraded from fastq to batchq. - * We mustn't put this packet back on the fastq (or we'll send it out of order) - * XXX add cache here? - */ - for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { - if (so == ifq->ifq_so) { - /* A match! */ - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } - - /* No match, check which queue to put it on */ - if (so && (so->so_iptos & IPTOS_LOWDELAY)) { - ifq = if_fastq.ifq_prev; - on_fastq = 1; - /* - * Check if this packet is a part of the last - * packet's session - */ - if (ifq->ifq_so == so) { - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } else - ifq = if_batchq.ifq_prev; - - /* Create a new doubly linked list for this session */ - ifm->ifq_so = so; - ifs_init(ifm); - insque(ifm, ifq); - -diddit: - ++if_queued; - - if (so) { - /* Update *_queued */ - so->so_queued++; - so->so_nqueued++; - /* - * Check if the interactive session should be downgraded to - * the batchq. A session is downgraded if it has queued 6 - * packets without pausing, and at least 3 of those packets - * have been sent over the link - * (XXX These are arbitrary numbers, probably not optimal..) - */ - if (on_fastq && ((so->so_nqueued >= 6) && - (so->so_nqueued - so->so_queued) >= 3)) { - - /* Remove from current queue... */ - remque(ifm->ifs_next); - - /* ...And insert in the new. That'll teach ya! */ - insque(ifm->ifs_next, &if_batchq); - } - } - -#ifndef FULL_BOLT - /* - * This prevents us from malloc()ing too many SLIRPmbufs - */ - if (link_up) { - /* if_start will check towrite */ - if_start(); - } -#endif -} - -/* - * Send a packet - * We choose a packet based on it's position in the output queues; - * If there are packets on the fastq, they are sent FIFO, before - * everything else. Otherwise we choose the first packet from the - * batchq and send it. the next packet chosen will be from the session - * after this one, then the session after that one, and so on.. So, - * for example, if there are 3 ftp session's fighting for bandwidth, - * one packet will be sent from the first session, then one packet - * from the second session, then one packet from the third, then back - * to the first, etc. etc. - */ -void -if_start(void) -{ - struct SLIRPmbuf *ifm, *ifqt; - - DEBUG_CALL("if_start"); - - if (if_queued == 0) - return; /* Nothing to do */ - - again: - /* check if we can really output */ - if (!slirp_can_output()) - return; - - /* - * See which queue to get next packet from - * If there's something in the fastq, select it immediately - */ - if (if_fastq.ifq_next != &if_fastq) { - ifm = if_fastq.ifq_next; - } else { - /* Nothing on fastq, see if next_m is valid */ - if (next_m != &if_batchq) - ifm = next_m; - else - ifm = if_batchq.ifq_next; - - /* Set which packet to send on next iteration */ - next_m = ifm->ifq_next; - } - /* Remove it from the queue */ - ifqt = ifm->ifq_prev; - remque(ifm); - --if_queued; - - /* If there are more packets for this session, re-queue them */ - if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { - insque(ifm->ifs_next, ifqt); - ifs_remque(ifm); - } - - /* Update so_queued */ - if (ifm->ifq_so) { - if (--ifm->ifq_so->so_queued == 0) - /* If there's no more queued, reset nqueued */ - ifm->ifq_so->so_nqueued = 0; - } - - /* Encapsulate the packet for sending */ - if_encap((uint8_t*)ifm->m_data, ifm->m_len); - - m_free(ifm); - - if (if_queued) - goto again; -} diff --git a/src - Cópia/network/slirp/if.h b/src - Cópia/network/slirp/if.h deleted file mode 100644 index 85a5a96d2..000000000 --- a/src - Cópia/network/slirp/if.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _IF_H_ -#define _IF_H_ - -#define IF_COMPRESS 0x01 /* We want compression */ -#define IF_NOCOMPRESS 0x02 /* Do not do compression */ -#define IF_AUTOCOMP 0x04 /* Autodetect (default) */ -#define IF_NOCIDCOMP 0x08 /* CID compression */ - -/* Needed for FreeBSD */ -#undef if_mtu -extern int if_mtu; -extern int if_mru; /* MTU and MRU */ -extern int if_comp; /* Flags for compression */ -extern int if_maxlinkhdr; -extern int if_queued; /* Number of packets queued so far */ -extern int if_thresh; /* Number of packets queued before we start sending - * (to prevent allocing too many SLIRPmbufs) */ - -extern struct SLIRPmbuf if_fastq; /* fast queue (for interactive data) */ -extern struct SLIRPmbuf if_batchq; /* queue for non-interactive data */ -extern struct SLIRPmbuf *next_m; - -#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) - -/* Interface statistics */ -struct slirp_ifstats { - u_int out_pkts; /* Output packets */ - u_int out_bytes; /* Output bytes */ - u_int out_errpkts; /* Output Error Packets */ - u_int out_errbytes; /* Output Error Bytes */ - u_int in_pkts; /* Input packets */ - u_int in_bytes; /* Input bytes */ - u_int in_errpkts; /* Input Error Packets */ - u_int in_errbytes; /* Input Error Bytes */ - - u_int bytes_saved; /* Number of bytes that compression "saved" */ - /* ie: number of bytes that didn't need to be sent over the link - * because of compression */ - - u_int in_mbad; /* Bad incoming packets */ -}; - -#endif diff --git a/src - Cópia/network/slirp/ip.h b/src - Cópia/network/slirp/ip.h deleted file mode 100644 index 5fa673963..000000000 --- a/src - Cópia/network/slirp/ip.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip.h 8.1 (Berkeley) 6/10/93 - * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp - */ - -#ifndef _IP_H_ -#define _IP_H_ - -#ifdef WORDS_BIGENDIAN -# ifndef NTOHL -# define NTOHL(d) -# endif -# ifndef NTOHS -# define NTOHS(d) -# endif -# ifndef HTONL -# define HTONL(d) -# endif -# ifndef HTONS -# define HTONS(d) -# endif -#else -# ifndef NTOHL -# define NTOHL(d) ((d) = ntohl((d))) -# endif -# ifndef NTOHS -# define NTOHS(d) ((d) = ntohs((u_int16_t)(d))) -# endif -# ifndef HTONL -# define HTONL(d) ((d) = htonl((d))) -# endif -# ifndef HTONS -# define HTONS(d) ((d) = htons((u_int16_t)(d))) -# endif -#endif - -typedef u_int32_t n_long; /* long as received from the net */ - -/* - * Definitions for internet protocol version 4. - * Per RFC 791, September 1981. - */ -#define IPVERSION 4 - -#if defined(_MSC_VER) -#pragma pack(push, 1) -#endif - -/* - * Structure of an internet header, naked of options. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ip { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, /* version */ - ip_hl:4; /* header length */ -#else - u_char ip_hl:4, /* header length */ - ip_v:4; /* version */ -#endif - u_int8_t ip_tos; /* type of service */ - u_int16_t ip_len; /* total length */ - u_int16_t ip_id; /* identification */ - u_int16_t ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* don't fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_int8_t ip_ttl; /* time to live */ - u_int8_t ip_p; /* protocol */ - u_int16_t ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) //WAS 0 -#endif - -#define IP_MAXPACKET 65535 /* maximum packet size */ - -/* - * Definitions for IP type of service (ip_tos) - */ -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 - -/* - * Definitions for options. - */ -#define IPOPT_COPIED(o) ((o)&0x80) -#define IPOPT_CLASS(o) ((o)&0x60) -#define IPOPT_NUMBER(o) ((o)&0x1f) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_DEBMEAS 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_EOL 0 /* end of option list */ -#define IPOPT_NOP 1 /* no operation */ - -#define IPOPT_RR 7 /* record packet route */ -#define IPOPT_TS 68 /* timestamp */ -#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ -#define IPOPT_LSRR 131 /* loose source route */ -#define IPOPT_SATID 136 /* satnet id */ -#define IPOPT_SSRR 137 /* strict source route */ - -/* - * Offsets to fields in options other than EOL and NOP. - */ -#define IPOPT_OPTVAL 0 /* option ID */ -#define IPOPT_OLEN 1 /* option length */ -#define IPOPT_OFFSET 2 /* offset within option */ -#define IPOPT_MINOFF 4 /* min value of above */ - -/* - * Time stamp option structure. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ip_timestamp { - u_int8_t ipt_code; /* IPOPT_TS */ - u_int8_t ipt_len; /* size of structure (variable) */ - u_int8_t ipt_ptr; /* index of current entry */ -#ifdef WORDS_BIGENDIAN - u_char ipt_oflw:4, /* overflow counter */ - ipt_flg:4; /* flags, see below */ -#else - u_char ipt_flg:4, /* flags, see below */ - ipt_oflw:4; /* overflow counter */ -#endif - union ipt_timestamp { - n_long ipt_time[1]; - struct ipt_ta { - struct in_addr ipt_addr; - n_long ipt_time; - } ipt_ta[1]; - } ipt_timestamp; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -/* flag bits for ipt_flg */ -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -/* bits for security (not byte swapped) */ -#define IPOPT_SECUR_UNCLASS 0x0000 -#define IPOPT_SECUR_CONFID 0xf135 -#define IPOPT_SECUR_EFTO 0x789a -#define IPOPT_SECUR_MMMM 0xbc4d -#define IPOPT_SECUR_RESTR 0xaf13 -#define IPOPT_SECUR_SECRET 0xd788 -#define IPOPT_SECUR_TOPSECRET 0x6bc5 - -/* - * Internet implementation parameters. - */ -#define MAXTTL 255 /* maximum time to live (seconds) */ -#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ -#define IPFRAGTTL 60 /* time to live for frags, slowhz */ -#define IPTTLDEC 1 /* subtracted when forwarding */ - -#define IP_MSS 576 /* default maximum segment size */ - -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include -#else -#if SIZEOF_CHAR_P == 4 -typedef SLIRPcaddr_t caddr32_t; -#else -typedef u_int32_t caddr32_t; -#endif -#endif - -#ifdef __amd64__ -typedef uintptr_t ipqp_32; -typedef uintptr_t ipasfragp_32; -#else -#if SIZEOF_CHAR_P == 4 -typedef struct ipq *ipqp_32; -typedef struct ipasfrag *ipasfragp_32; -#else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; -#endif -#endif - -/* - * Overlay for ip header used by other protocols (tcp, udp). - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ipovly { -#ifdef __amd64__ - uintptr_t ih_next, ih_prev; /* for protocol sequence q's */ -#else - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ -#endif - u_int8_t ih_x1; /* (unused) */ - u_int8_t ih_pr; /* protocol */ - u_int16_t ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -#if defined(_MSC_VER) -#pragma pack(pop) -#endif - -/* - * Ip reassembly queue structure. Each fragment - * being reassembled is attached to one of these structures. - * They are timed out after ipq_ttl drops to 0, and may also - * be reclaimed if memory becomes tight. - * size 28 bytes - */ -struct ipq { -#ifdef __amd64__ - uintptr_t next,prev; /* to other reass headers */ -#else - ipqp_32 next,prev; /* to other reass headers */ -#endif - u_int8_t ipq_ttl; /* time for reass q to live */ - u_int8_t ipq_p; /* protocol of this fragment */ - u_int16_t ipq_id; /* sequence id for reassembly */ - ipasfragp_32 ipq_next,ipq_prev; - /* to ip headers of fragments */ - struct in_addr ipq_src,ipq_dst; -}; - -/* - * Ip header, when holding a fragment. - * - * Note: ipf_next must be at same offset as ipq_next above - */ -struct ipasfrag { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, - ip_hl:4; -#else - u_char ip_hl:4, - ip_v:4; -#endif - /* BUG : u_int changed to u_int8_t. - * sizeof(u_int)==4 on linux 2.0 - */ - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit - * to avoid destroying tos (PPPDTRuu); - * copied from (ip_off&IP_MF) */ - u_int16_t ip_len; - u_int16_t ip_id; - u_int16_t ip_off; - u_int8_t ip_ttl; - u_int8_t ip_p; - u_int16_t ip_sum; - ipasfragp_32 ipf_next; /* next fragment */ - ipasfragp_32 ipf_prev; /* previous fragment */ -}; - -/* - * Structure stored in mbuf in inpcb.ip_options - * and passed to ip_output when ip options are in use. - * The actual length of the options (including ipopt_dst) - * is in m_len. - */ -#define MAX_IPOPTLEN 40 - -struct ipoption { - struct in_addr ipopt_dst; /* first-hop dst if source routed */ - int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ -}; - -/* - * Structure attached to inpcb.ip_moptions and - * passed to ip_output when IP multicast options are in use. - */ - -struct ipstat { - u_long ips_total; /* total packets received */ - u_long ips_badsum; /* checksum bad */ - u_long ips_tooshort; /* packet too short */ - u_long ips_toosmall; /* not enough data */ - u_long ips_badhlen; /* ip header length < data size */ - u_long ips_badlen; /* ip length < ip header length */ - u_long ips_fragments; /* fragments received */ - u_long ips_fragdropped; /* frags dropped (dups, out of space) */ - u_long ips_fragtimeout; /* fragments timed out */ - u_long ips_forward; /* packets forwarded */ - u_long ips_cantforward; /* packets rcvd for unreachable dest */ - u_long ips_redirectsent; /* packets forwarded on same net */ - u_long ips_noproto; /* unknown or unsupported protocol */ - u_long ips_delivered; /* datagrams delivered to upper level*/ - u_long ips_localout; /* total ip packets generated here */ - u_long ips_odropped; /* lost packets due to nobufs, etc. */ - u_long ips_reassembled; /* total packets reassembled ok */ - u_long ips_fragmented; /* datagrams successfully fragmented */ - u_long ips_ofragments; /* output fragments created */ - u_long ips_cantfrag; /* don't fragment flag was set, etc. */ - u_long ips_badoptions; /* error in option processing */ - u_long ips_noroute; /* packets discarded due to no route */ - u_long ips_badvers; /* ip version != 4 */ - u_long ips_rawout; /* total raw ip packets generated */ - u_long ips_unaligned; /* times the ip packet was not aligned */ -}; - -extern struct ipstat ipstat; -extern struct ipq ipq; /* ip reass. queue */ -extern u_int16_t ip_id; /* ip packet ctr, for ids */ -extern int ip_defttl; /* default IP ttl */ - -#endif diff --git a/src - Cópia/network/slirp/ip_icmp.c b/src - Cópia/network/slirp/ip_icmp.c deleted file mode 100644 index 7bd787863..000000000 --- a/src - Cópia/network/slirp/ip_icmp.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 - * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp - */ - -#include "slirp.h" -#include "ip_icmp.h" - -struct icmpstat icmpstat; - -/* The message sent when emulating PING */ -/* Be nice and tell them it's just a psuedo-ping packet */ -char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n"; - -/* list of actions for icmp_error() on RX of an icmp message */ -static int icmp_flush[19] = { -/* ECHO REPLY (0) */ 0, - 1, - 1, -/* DEST UNREACH (3) */ 1, -/* SOURCE QUENCH (4)*/ 1, -/* REDIRECT (5) */ 1, - 1, - 1, -/* ECHO (8) */ 0, -/* ROUTERADVERT (9) */ 1, -/* ROUTERSOLICIT (10) */ 1, -/* TIME EXCEEDED (11) */ 1, -/* PARAMETER PROBLEM (12) */ 1, -/* TIMESTAMP (13) */ 0, -/* TIMESTAMP REPLY (14) */ 0, -/* INFO (15) */ 0, -/* INFO REPLY (16) */ 0, -/* ADDR MASK (17) */ 0, -/* ADDR MASK REPLY (18) */ 0 -}; - -/* - * Process a received ICMP message. - */ -void -icmp_input(m, hlen) - struct SLIRPmbuf *m; - int hlen; -{ - register struct icmp *icp; - register struct ip *ip=mtod(m, struct ip *); - int icmplen=ip->ip_len; - /* int code; */ - - DEBUG_CALL("icmp_input"); - DEBUG_ARG("m = %lx", (long )m); - DEBUG_ARG("m_len = %d", m->m_len); - - icmpstat.icps_received++; - - /* - * Locate icmp structure in SLIRPmbuf, and check - * that its not corrupted and of at least minimum length. - */ - if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ - icmpstat.icps_tooshort++; - freeit: - m_freem(m); - goto end_error; - } - - m->m_len -= hlen; - m->m_data += hlen; - icp = mtod(m, struct icmp *); - if (cksum(m, icmplen)) { - icmpstat.icps_checksum++; - goto freeit; - } - m->m_len += hlen; - m->m_data -= hlen; - - /* icmpstat.icps_inhist[icp->icmp_type]++; */ - /* code = icp->icmp_code; */ - - DEBUG_ARG("icmp_type = %d", icp->icmp_type); - switch (icp->icmp_type) { - case ICMP_ECHO: - icp->icmp_type = ICMP_ECHOREPLY; - ip->ip_len += hlen; /* since ip_input subtracts this */ - if (ip->ip_dst.s_addr == alias_addr.s_addr) { - icmp_reflect(m); - } else { - struct SLIRPsocket *so; - struct sockaddr_in addr; - if ((so = socreate()) == NULL) goto freeit; - if(udp_attach(so) == -1) { - DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", - errno,strerror(errno))); - sofree(so); - m_free(m); - goto end_error; - } - so->so_m = m; - so->so_faddr = ip->ip_dst; - so->so_fport = htons(7); - so->so_laddr = ip->ip_src; - so->so_lport = htons(9); - so->so_iptos = ip->ip_tos; - so->so_type = IPPROTO_ICMP; - so->so_state = SS_ISFCONNECTED; - - /* Send the packet */ - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else { - addr.sin_addr = so->so_faddr; - } - addr.sin_port = so->so_fport; - if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0, - (struct sockaddr *)&addr, sizeof(addr)) == -1) { - DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n", - errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); - udp_detach(so); - } - } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ - break; - case ICMP_UNREACH: - /* XXX? report error? close socket? */ - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - case ICMP_SOURCEQUENCH: - case ICMP_TSTAMP: - case ICMP_MASKREQ: - case ICMP_REDIRECT: - icmpstat.icps_notsupp++; - m_freem(m); - break; - - default: - icmpstat.icps_badtype++; - m_freem(m); - } /* swith */ - -end_error: - /* m is m_free()'d xor put in a socket xor or given to ip_send */ - return; -} - - -/* - * Send an ICMP message in response to a situation - * - * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do). - * MUST NOT change this header information. - * MUST NOT reply to a multicast/broadcast IP address. - * MUST NOT reply to a multicast/broadcast MAC address. - * MUST reply to only the first fragment. - */ -/* - * Send ICMP_UNREACH back to the source regarding msrc. - * SLIRPmbuf *msrc is used as a template, but is NOT m_free()'d. - * It is reported as the bad ip packet. The header should - * be fully correct and in host byte order. - * ICMP fragmentation is illegal. All machines must accept 576 bytes in one - * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548 - */ - -#define ICMP_MAXDATALEN (IP_MSS-28) -void -icmp_error(struct SLIRPmbuf *msrc, u_char type, u_char code, int minsize, char *message) -{ - unsigned hlen, shlen, s_ip_len; - register struct ip *ip; - register struct icmp *icp; - register struct SLIRPmbuf *m; - - DEBUG_CALL("icmp_error"); - DEBUG_ARG("msrc = %lx", (long )msrc); - DEBUG_ARG("msrc_len = %d", msrc->m_len); - - if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; - - /* check msrc */ - if(!msrc) goto end_error; - ip = mtod(msrc, struct ip *); -#if SLIRP_DEBUG - { char bufa[20], bufb[20]; - strcpy(bufa, inet_ntoa(ip->ip_src)); - strcpy(bufb, inet_ntoa(ip->ip_dst)); - DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); - } -#endif - if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */ - - shlen=ip->ip_hl << 2; - s_ip_len=ip->ip_len; - if(ip->ip_p == IPPROTO_ICMP) { - icp = (struct icmp *)((char *)ip + shlen); - /* - * Assume any unknown ICMP type is an error. This isn't - * specified by the RFC, but think about it.. - */ - if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error; - } - - /* make a copy */ - if(!(m=m_get())) goto end_error; /* get SLIRPmbuf */ - { u_int new_m_size; - new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; - if(new_m_size>m->m_size) m_inc(m, new_m_size); - } - memcpy(m->m_data, msrc->m_data, msrc->m_len); - m->m_len = msrc->m_len; /* copy msrc to m */ - - /* make the header of the reply packet */ - ip = mtod(m, struct ip *); - hlen= sizeof(struct ip ); /* no options in reply */ - - /* fill in icmp */ - m->m_data += hlen; - m->m_len -= hlen; - - icp = mtod(m, struct icmp *); - - if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */ - else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */ - s_ip_len=ICMP_MAXDATALEN; - - m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ - - /* min. size = 8+sizeof(struct ip)+8 */ - - icp->icmp_type = type; - icp->icmp_code = code; - icp->icmp_id = 0; - icp->icmp_seq = 0; - - memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */ - HTONS(icp->icmp_ip.ip_len); - HTONS(icp->icmp_ip.ip_id); - HTONS(icp->icmp_ip.ip_off); - -#if SLIRP_DEBUG - if(message) { /* DEBUG : append message to ICMP packet */ - int message_len; - char *cpnt; - message_len=strlen(message); - if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN; - cpnt=(char *)m->m_data+m->m_len; - memcpy(cpnt, message, message_len); - m->m_len+=message_len; - } -#endif - - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, m->m_len); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - ip->ip_hl = hlen >> 2; - ip->ip_len = (u_int16_t)m->m_len; - - ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ - - ip->ip_ttl = MAXTTL; - ip->ip_p = IPPROTO_ICMP; - ip->ip_dst = ip->ip_src; /* ip adresses */ - ip->ip_src = alias_addr; - - (void ) ip_output((struct SLIRPsocket *)NULL, m); - - icmpstat.icps_reflect++; - -end_error: - return; -} -#undef ICMP_MAXDATALEN - -/* - * Reflect the ip packet back to the source - */ -void -icmp_reflect(m) - struct SLIRPmbuf *m; -{ - register struct ip *ip = mtod(m, struct ip *); - int hlen = ip->ip_hl << 2; - int optlen = hlen - sizeof(struct ip ); - register struct icmp *icp; - - /* - * Send an icmp packet back to the ip level, - * after supplying a checksum. - */ - m->m_data += hlen; - m->m_len -= hlen; - icp = mtod(m, struct icmp *); - - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, ip->ip_len - hlen); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - if (optlen > 0) { - /* - * Strip out original options by copying rest of first - * SLIRPmbuf's data back, and adjust the IP length. - */ - memmove((SLIRPcaddr_t)(ip + 1), (SLIRPcaddr_t)ip + hlen, - (unsigned )(m->m_len - hlen)); - hlen -= optlen; - ip->ip_hl = hlen >> 2; - ip->ip_len -= optlen; - m->m_len -= optlen; - } - - ip->ip_ttl = MAXTTL; - { /* swap */ - struct in_addr icmp_dst; - icmp_dst = ip->ip_dst; - ip->ip_dst = ip->ip_src; - ip->ip_src = icmp_dst; - } - - (void ) ip_output((struct SLIRPsocket *)NULL, m); - - icmpstat.icps_reflect++; -} diff --git a/src - Cópia/network/slirp/ip_icmp.h b/src - Cópia/network/slirp/ip_icmp.h deleted file mode 100644 index 20fcda1bd..000000000 --- a/src - Cópia/network/slirp/ip_icmp.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 - * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp - */ - -#ifndef _NETINET_IP_ICMP_H_ -#define _NETINET_IP_ICMP_H_ - -/* - * Interface Control Message Protocol Definitions. - * Per RFC 792, September 1981. - */ - -typedef u_int32_t n_time; - -/* - * Structure of an icmp header. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct icmp { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - u_short icd_id; - u_short icd_seq; - } ih_idseq; - int ih_void; - - /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ - struct ih_pmtu { - u_short ipm_void; - u_short ipm_nextmtu; - } ih_pmtu; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu - union { - struct id_ts { - n_time its_otime; - n_time its_rtime; - n_time its_ttime; - } id_ts; - struct id_ip { - struct ip idi_ip; - /* options and then 64 bits of data */ - } id_ip; - uint32_t id_mask; - char id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(0) -#endif - -/* - * Lower bounds on packet lengths for various types. - * For the error advice packets must first insure that the - * packet is large enought to contain the returned ip header. - * Only then can we do the check to see if 64 bits of packet - * data have been returned, since we need to check the returned - * ip header length. - */ -#define ICMP_MINLEN 8 /* abs minimum */ -#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ -#define ICMP_MASKLEN 12 /* address mask */ -#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ -#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) - /* N.B.: must separately check that ip_hl >= 5 */ - -/* - * Definition of type and code field values. - */ -#define ICMP_ECHOREPLY 0 /* echo reply */ -#define ICMP_UNREACH 3 /* dest unreachable, codes: */ -#define ICMP_UNREACH_NET 0 /* bad net */ -#define ICMP_UNREACH_HOST 1 /* bad host */ -#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ -#define ICMP_UNREACH_PORT 3 /* bad port */ -#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ -#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ -#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ -#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ -#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ -#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ -#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ -#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ -#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ -#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ -#define ICMP_REDIRECT 5 /* shorter route, codes: */ -#define ICMP_REDIRECT_NET 0 /* for network */ -#define ICMP_REDIRECT_HOST 1 /* for host */ -#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ -#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ -#define ICMP_ECHO 8 /* echo service */ -#define ICMP_ROUTERADVERT 9 /* router advertisement */ -#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ -#define ICMP_TIMXCEED 11 /* time exceeded, code: */ -#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ -#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ -#define ICMP_PARAMPROB 12 /* ip header bad */ -#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ -#define ICMP_TSTAMP 13 /* timestamp request */ -#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ -#define ICMP_IREQ 15 /* information request */ -#define ICMP_IREQREPLY 16 /* information reply */ -#define ICMP_MASKREQ 17 /* address mask request */ -#define ICMP_MASKREPLY 18 /* address mask reply */ - -#define ICMP_MAXTYPE 18 - -#define ICMP_INFOTYPE(type) \ - ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ - (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ - (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ - (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ - (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) - -void icmp_input _P((struct SLIRPmbuf *, int)); -void icmp_error _P((struct SLIRPmbuf *, u_char, u_char, int, char *)); -void icmp_reflect _P((struct SLIRPmbuf *)); - -#endif diff --git a/src - Cópia/network/slirp/ip_input.c b/src - Cópia/network/slirp/ip_input.c deleted file mode 100644 index c2337f883..000000000 --- a/src - Cópia/network/slirp/ip_input.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 - * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ -#include - -#include "slirp.h" -#include "ip_icmp.h" - -int ip_defttl; -struct ipstat ipstat; -struct ipq ipq; - -/* - * IP initialization: fill in IP protocol switch table. - * All protocols not implemented in kernel go to raw IP protocol handler. - */ -void -ip_init() -{ - ipq.next = ipq.prev = (ipqp_32)&ipq; - ip_id = tt.tv_sec & 0xffff; - udp_init(); - tcp_init(); - ip_defttl = IPDEFTTL; -} - -/* - * Ip input routine. Checksum and byte swap header. If fragmented - * try to reassemble. Process options. Pass to next level. - */ -void -ip_input(m) - struct SLIRPmbuf *m; -{ - register struct ip *ip; - u_int hlen; - - DEBUG_CALL("ip_input"); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m_len = %d", m->m_len); - - ipstat.ips_total++; - - if (m->m_len < sizeof (struct ip)) { - ipstat.ips_toosmall++; - return; - } - - ip = mtod(m, struct ip *); - - if (ip->ip_v != IPVERSION) { - ipstat.ips_badvers++; - goto bad; - } - - hlen = ip->ip_hl << 2; - if (hlenm->m_len) {/* min header length */ - ipstat.ips_badhlen++; /* or packet too short */ - goto bad; - } - - /* keep ip header intact for ICMP reply - * ip->ip_sum = cksum(m, hlen); - * if (ip->ip_sum) { - */ - if(cksum(m,hlen)) { - ipstat.ips_badsum++; - goto bad; - } - - /* - * Convert fields to host representation. - */ - NTOHS(ip->ip_len); - if (ip->ip_len < hlen) { - ipstat.ips_badlen++; - goto bad; - } - NTOHS(ip->ip_id); - NTOHS(ip->ip_off); - - /* - * Check that the amount of data in the buffers - * is as at least much as the IP header would have us expect. - * Trim SLIRPmbufs if longer than we expect. - * Drop packet if shorter than we expect. - */ - if (m->m_len < ip->ip_len) { - ipstat.ips_tooshort++; - goto bad; - } - /* Should drop packet if SLIRPmbuf too long? hmmm... */ - if (m->m_len > ip->ip_len) - m_adj(m, ip->ip_len - m->m_len); - - /* check ip_ttl for a correct ICMP reply */ - if(ip->ip_ttl==0 || ip->ip_ttl==1) { - icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl"); - goto bad; - } - - /* - * Process options and, if not destined for us, - * ship it on. ip_dooptions returns 1 when an - * error was detected (causing an icmp message - * to be sent and the original packet to be freed). - */ -/* We do no IP options */ -/* if (hlen > sizeof (struct ip) && ip_dooptions(m)) - * goto next; - */ - /* - * If offset or IP_MF are set, must reassemble. - * Otherwise, nothing need be done. - * (We could look in the reassembly queue to see - * if the packet was previously fragmented, - * but it's not worth the time; just let them time out.) - * - * XXX This should fail, don't fragment yet - */ - if (ip->ip_off &~ IP_DF) { - register struct ipq *fp; - /* - * Look for queue of fragments - * of this datagram. - */ - for (fp = (struct ipq *) ipq.next; fp != &ipq; - fp = (struct ipq *) fp->next) - if (ip->ip_id == fp->ipq_id && - ip->ip_src.s_addr == fp->ipq_src.s_addr && - ip->ip_dst.s_addr == fp->ipq_dst.s_addr && - ip->ip_p == fp->ipq_p) - goto found; - fp = 0; - found: - - /* - * Adjust ip_len to not reflect header, - * set ip_mff if more fragments are expected, - * convert offset of this to bytes. - */ - ip->ip_len -= hlen; - if (ip->ip_off & IP_MF) - ((struct ipasfrag *)ip)->ipf_mff |= 1; - else - ((struct ipasfrag *)ip)->ipf_mff &= ~1; - - ip->ip_off <<= 3; - - /* - * If datagram marked as having more fragments - * or if this is not the first fragment, - * attempt reassembly; if it succeeds, proceed. - */ - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { - ipstat.ips_fragments++; - ip = ip_reass((struct ipasfrag *)ip, fp); - if (ip == 0) - return; - ipstat.ips_reassembled++; - m = dtom(ip); - } else - if (fp) - ip_freef(fp); - - } else - ip->ip_len -= hlen; - - /* - * Switch out to protocol's input routine. - */ - ipstat.ips_delivered++; - switch (ip->ip_p) { - case IPPROTO_TCP: - tcp_input(m, hlen, (struct SLIRPsocket *)NULL); - break; - case IPPROTO_UDP: - udp_input(m, hlen); - break; - case IPPROTO_ICMP: - icmp_input(m, hlen); - break; - default: - ipstat.ips_noproto++; - m_free(m); - } - return; -bad: - m_freem(m); - return; -} - -/* - * Take incoming datagram fragment and try to - * reassemble it into whole datagram. If a chain for - * reassembly of this datagram already exists, then it - * is given as fp; otherwise have to make a chain. - */ -struct ip * -ip_reass(ip, fp) - register struct ipasfrag *ip; - register struct ipq *fp; -{ - register struct SLIRPmbuf *m = dtom(ip); - register struct ipasfrag *q; - int hlen = ip->ip_hl << 2; - int i, next; - - DEBUG_CALL("ip_reass"); - DEBUG_ARG("ip = %lx", (long)ip); - DEBUG_ARG("fp = %lx", (long)fp); - DEBUG_ARG("m = %lx", (long)m); - - /* - * Presence of header sizes in SLIRPmbufs - * would confuse code below. - * Fragment m_data is concatenated. - */ - m->m_data += hlen; - m->m_len -= hlen; - - /* - * If first fragment to arrive, create a reassembly queue. - */ - if (fp == 0) { - struct SLIRPmbuf *t; - if ((t = m_get()) == NULL) goto dropfrag; - fp = mtod(t, struct ipq *); - insque_32(fp, &ipq); - fp->ipq_ttl = IPFRAGTTL; - fp->ipq_p = ip->ip_p; - fp->ipq_id = ip->ip_id; - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; - fp->ipq_src = ((struct ip *)ip)->ip_src; - fp->ipq_dst = ((struct ip *)ip)->ip_dst; - q = (struct ipasfrag *)fp; - goto insert; - } - - /* - * Find a segment which begins after this one does. - */ - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *)q->ipf_next) - if (q->ip_off > ip->ip_off) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if (q->ipf_prev != (ipasfragp_32)fp) { - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; - if (i > 0) { - if (i >= ip->ip_len) - goto dropfrag; - m_adj(dtom(ip), i); - ip->ip_off += i; - ip->ip_len -= i; - } - } - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; - q->ip_off += i; - m_adj(dtom(q), i); - break; - } - q = (struct ipasfrag *) q->ipf_next; - m_freem(dtom((struct ipasfrag *) q->ipf_prev)); - ip_deq((struct ipasfrag *) q->ipf_prev); - } - -insert: - /* - * Stick new segment in its place; - * check for complete reassembly. - */ - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); - next = 0; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *) q->ipf_next) { - if (q->ip_off != next) - return (0); - next += q->ip_len; - } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) - return (0); - - /* - * Reassembly is complete; concatenate fragments. - */ - q = (struct ipasfrag *) fp->ipq_next; - m = dtom(q); - - q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag *)fp) { - struct SLIRPmbuf *t; - t = dtom(q); - q = (struct ipasfrag *) q->ipf_next; - m_cat(m, t); - } - - /* - * Create header for new ip packet by - * modifying header of first packet; - * dequeue and discard fragment reassembly header. - * Make header visible. - */ - ip = (struct ipasfrag *) fp->ipq_next; - - /* - * If the fragments concatenated to an SLIRPmbuf that's - * bigger than the total size of the fragment, then and - * m_ext buffer was alloced. But fp->ipq_next points to - * the old buffer (in the SLIRPmbuf), so we must point ip - * into the new buffer. - */ - if (m->m_flags & M_EXT) { - int delta; - delta = (char *)ip - m->m_dat; - ip = (struct ipasfrag *)(m->m_ext + delta); - } - - /* DEBUG_ARG("ip = %lx", (long)ip); - * ip=(struct ipasfrag *)m->m_data; */ - - ip->ip_len = next; - ip->ipf_mff &= ~1; - ((struct ip *)ip)->ip_src = fp->ipq_src; - ((struct ip *)ip)->ip_dst = fp->ipq_dst; - remque_32(fp); - (void) m_free(dtom(fp)); - m = dtom(ip); - m->m_len += (ip->ip_hl << 2); - m->m_data -= (ip->ip_hl << 2); - - return ((struct ip *)ip); - -dropfrag: - ipstat.ips_fragdropped++; - m_freem(m); - return (0); -} - -/* - * Free a fragment reassembly header and all - * associated datagrams. - */ -void -ip_freef(fp) - struct ipq *fp; -{ - register struct ipasfrag *q, *p; - - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = p) { - p = (struct ipasfrag *) q->ipf_next; - ip_deq(q); - m_freem(dtom(q)); - } - remque_32(fp); - (void) m_free(dtom(fp)); -} - -/* - * Put an ip fragment on a reassembly chain. - * Like insque, but pointers in middle of structure. - */ -void -ip_enq(p, prev) - register struct ipasfrag *p, *prev; -{ - DEBUG_CALL("ip_enq"); - DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = (ipasfragp_32) prev; - p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; - prev->ipf_next = (ipasfragp_32) p; -} - -/* - * To ip_enq as remque is to insque. - */ -void -ip_deq(p) - register struct ipasfrag *p; -{ - ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; - ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; -} - -/* - * IP timer processing; - * if a timer expires on a reassembly - * queue, discard it. - */ -void -ip_slowtimo() -{ - register struct ipq *fp; - - DEBUG_CALL("ip_slowtimo"); - - fp = (struct ipq *) ipq.next; - if (fp == 0) - return; - - while (fp != &ipq) { - --fp->ipq_ttl; - fp = (struct ipq *) fp->next; - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { - ipstat.ips_fragtimeout++; - ip_freef((struct ipq *) fp->prev); - } - } -} - -/* - * Do option processing on a datagram, - * possibly discarding it if bad options are encountered, - * or forwarding it if source-routed. - * Returns 1 if packet has been forwarded/freed, - * 0 if the packet should be processed further. - */ - -#ifdef notdef - -int -ip_dooptions(m) - struct SLIRPmbuf *m; -{ - register struct ip *ip = mtod(m, struct ip *); - register u_char *cp; - register struct ip_timestamp *ipt; - register struct in_ifaddr *ia; -/* int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; */ - int opt, optlen, cnt, off, code, type, forward = 0; - struct in_addr *sin, dst; -typedef u_int32_t n_time; - n_time ntime; - - dst = ip->ip_dst; - cp = (u_char *)(ip + 1); - cnt = (ip->ip_hl << 2) - sizeof (struct ip); - for (; cnt > 0; cnt -= optlen, cp += optlen) { - opt = cp[IPOPT_OPTVAL]; - if (opt == IPOPT_EOL) - break; - if (opt == IPOPT_NOP) - optlen = 1; - else { - optlen = cp[IPOPT_OLEN]; - if (optlen <= 0 || optlen > cnt) { - code = &cp[IPOPT_OLEN] - (u_char *)ip; - goto bad; - } - } - switch (opt) { - - default: - break; - - /* - * Source routing with record. - * Find interface with current destination address. - * If none on this machine then drop if strictly routed, - * or do nothing if loosely routed. - * Record interface address and bring up next address - * component. If strictly routed make sure next - * address is on directly accessible net. - */ - case IPOPT_LSRR: - case IPOPT_SSRR: - if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { - code = &cp[IPOPT_OFFSET] - (u_char *)ip; - goto bad; - } - ipaddr.sin_addr = ip->ip_dst; - ia = (struct in_ifaddr *) - ifa_ifwithaddr((struct sockaddr *)&ipaddr); - if (ia == 0) { - if (opt == IPOPT_SSRR) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_SRCFAIL; - goto bad; - } - /* - * Loose routing, and not at next destination - * yet; nothing to do except forward. - */ - break; - } - off--; / * 0 origin * / - if (off > optlen - sizeof(struct in_addr)) { - /* - * End of source route. Should be for us. - */ - save_rte(cp, ip->ip_src); - break; - } - /* - * locate outgoing interface - */ - bcopy((SLIRPcaddr_t)(cp + off), (SLIRPcaddr_t)&ipaddr.sin_addr, - sizeof(ipaddr.sin_addr)); - if (opt == IPOPT_SSRR) { -#define INA struct in_ifaddr * -#define SA struct sockaddr * - if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0) - ia = (INA)ifa_ifwithnet((SA)&ipaddr); - } else - ia = ip_rtaddr(ipaddr.sin_addr); - if (ia == 0) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_SRCFAIL; - goto bad; - } - ip->ip_dst = ipaddr.sin_addr; - bcopy((SLIRPcaddr_t)&(IA_SIN(ia)->sin_addr), - (SLIRPcaddr_t)(cp + off), sizeof(struct in_addr)); - cp[IPOPT_OFFSET] += sizeof(struct in_addr); - /* - * Let ip_intr's mcast routing check handle mcast pkts - */ - forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)); - break; - - case IPOPT_RR: - if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { - code = &cp[IPOPT_OFFSET] - (u_char *)ip; - goto bad; - } - /* - * If no space remains, ignore. - */ - off--; * 0 origin * - if (off > optlen - sizeof(struct in_addr)) - break; - bcopy((SLIRPcaddr_t)(&ip->ip_dst), (SLIRPcaddr_t)&ipaddr.sin_addr, - sizeof(ipaddr.sin_addr)); - /* - * locate outgoing interface; if we're the destination, - * use the incoming interface (should be same). - */ - if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 && - (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_HOST; - goto bad; - } - bcopy((SLIRPcaddr_t)&(IA_SIN(ia)->sin_addr), - (SLIRPcaddr_t)(cp + off), sizeof(struct in_addr)); - cp[IPOPT_OFFSET] += sizeof(struct in_addr); - break; - - case IPOPT_TS: - code = cp - (u_char *)ip; - ipt = (struct ip_timestamp *)cp; - if (ipt->ipt_len < 5) - goto bad; - if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) { - if (++ipt->ipt_oflw == 0) - goto bad; - break; - } - sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); - switch (ipt->ipt_flg) { - - case IPOPT_TS_TSONLY: - break; - - case IPOPT_TS_TSANDADDR: - if (ipt->ipt_ptr + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) - goto bad; - ipaddr.sin_addr = dst; - ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr, - m->m_pkthdr.rcvif); - if (ia == 0) - continue; - bcopy((SLIRPcaddr_t)&IA_SIN(ia)->sin_addr, - (SLIRPcaddr_t)sin, sizeof(struct in_addr)); - ipt->ipt_ptr += sizeof(struct in_addr); - break; - - case IPOPT_TS_PRESPEC: - if (ipt->ipt_ptr + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) - goto bad; - bcopy((SLIRPcaddr_t)sin, (SLIRPcaddr_t)&ipaddr.sin_addr, - sizeof(struct in_addr)); - if (ifa_ifwithaddr((SA)&ipaddr) == 0) - continue; - ipt->ipt_ptr += sizeof(struct in_addr); - break; - - default: - goto bad; - } - ntime = iptime(); - bcopy((SLIRPcaddr_t)&ntime, (SLIRPcaddr_t)cp + ipt->ipt_ptr - 1, - sizeof(n_time)); - ipt->ipt_ptr += sizeof(n_time); - } - } - if (forward) { - ip_forward(m, 1); - return (1); - } - } - } - return (0); -bad: - /* ip->ip_len -= ip->ip_hl << 2; XXX icmp_error adds in hdr length */ - -/* Not yet */ - icmp_error(m, type, code, 0, 0); - - ipstat.ips_badoptions++; - return (1); -} - -#endif /* notdef */ - -/* - * Strip out IP options, at higher - * level protocol in the kernel. - * Second argument is buffer to which options - * will be moved, and return value is their length. - * (XXX) should be deleted; last arg currently ignored. - */ -void -ip_stripoptions(m, mopt) - struct SLIRPmbuf *m; - struct SLIRPmbuf *mopt; -{ - register int i; - struct ip *ip = mtod(m, struct ip *); - register SLIRPcaddr_t opts; - int olen; - - olen = (ip->ip_hl<<2) - sizeof (struct ip); - opts = (SLIRPcaddr_t)(ip + 1); - i = m->m_len - (sizeof (struct ip) + olen); - memcpy(opts, opts + olen, (unsigned)i); - m->m_len -= olen; - - ip->ip_hl = sizeof(struct ip) >> 2; -} diff --git a/src - Cópia/network/slirp/ip_output.c b/src - Cópia/network/slirp/ip_output.c deleted file mode 100644 index c3f243e76..000000000 --- a/src - Cópia/network/slirp/ip_output.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include "slirp.h" - -u_int16_t ip_id; - -/* - * IP output. The packet in SLIRPmbuf chain m contains a skeletal IP - * header (with len, off, ttl, proto, tos, src, dst). - * The SLIRPmbuf chain containing the packet will be freed. - * The SLIRPmbuf opt, if present, will not be freed. - */ -int -ip_output(so, m0) - struct SLIRPsocket *so; - struct SLIRPmbuf *m0; -{ - struct ip *ip; - struct SLIRPmbuf *m = m0; - u_int hlen = sizeof(struct ip ); - u_int len, off; - int error = 0; - - DEBUG_CALL("ip_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m0 = %lx", (long)m0); - - /* We do no options */ -/* if (opt) { - * m = ip_insertoptions(m, opt, &len); - * hlen = len; - * } - */ - ip = mtod(m, struct ip *); - /* - * Fill in IP header. - */ - ip->ip_v = IPVERSION; - ip->ip_off &= IP_DF; - ip->ip_id = htons(ip_id++); - ip->ip_hl = hlen >> 2; - ipstat.ips_localout++; - - /* - * Verify that we have any chance at all of being able to queue - * the packet or packet fragments - */ - /* XXX Hmmm... */ -/* if (if_queued > if_thresh && towrite <= 0) { - * error = ENOBUFS; - * goto bad; - * } - */ - - /* - * If small enough for interface, can just send directly. - */ - if ((u_int16_t)ip->ip_len <= if_mtu) { - ip->ip_len = htons((u_int16_t)ip->ip_len); - ip->ip_off = htons((u_int16_t)ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); - - if_output(so, m); - goto done; - } - - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - if (ip->ip_off & IP_DF) { - error = -1; - ipstat.ips_cantfrag++; - goto bad; - } - - len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */ - if (len < 8) { - error = -1; - goto bad; - } - - { - int mhlen, firstlen = len; - struct SLIRPmbuf **mnext = &m->m_nextpkt; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { - struct ip *mhip; - m = m_get(); - if (m == 0) { - error = -1; - ipstat.ips_odropped++; - goto sendorfree; - } - m->m_data += if_maxlinkhdr; - mhip = mtod(m, struct ip *); - *mhip = *ip; - - /* No options */ -/* if (hlen > sizeof (struct ip)) { - * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); - * mhip->ip_hl = mhlen >> 2; - * } - */ - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); - if (ip->ip_off & IP_MF) - mhip->ip_off |= IP_MF; - if (off + len >= (u_int16_t)ip->ip_len) - len = (u_int16_t)ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_int16_t)(len + mhlen)); - - if (m_copy(m, m0, off, len) < 0) { - error = -1; - goto sendorfree; - } - - mhip->ip_off = htons((u_int16_t)mhip->ip_off); - mhip->ip_sum = 0; - mhip->ip_sum = cksum(m, mhlen); - *mnext = m; - mnext = &m->m_nextpkt; - ipstat.ips_ofragments++; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m = m0; - m_adj(m, hlen + firstlen - ip->ip_len); - ip->ip_len = htons((u_int16_t)m->m_len); - ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); -sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_nextpkt; - m->m_nextpkt = 0; - if (error == 0) - if_output(so, m); - else - m_freem(m); - } - - if (error == 0) - ipstat.ips_fragmented++; - } - -done: - return (error); - -bad: - m_freem(m0); - goto done; -} diff --git a/src - Cópia/network/slirp/libslirp.h b/src - Cópia/network/slirp/libslirp.h deleted file mode 100644 index 8a1aa31e6..000000000 --- a/src - Cópia/network/slirp/libslirp.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _LIBSLIRP_H -#define _LIBSLIRP_H - -#ifdef _WIN32 -#include -int inet_aton(const char *cp, struct in_addr *ia); -#else -#include -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -int slirp_init(void); - -int slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds); - -void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds); - -void slirp_input(const uint8 *pkt, int pkt_len); - -/* you must provide the following functions: */ -int slirp_can_output(void); -void slirp_output(const uint8 *pkt, int pkt_len); - -int slirp_redir(int is_udp, int host_port, - struct in_addr guest_addr, int guest_port); -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, - int guest_port); - -extern const char *tftp_prefix; -extern char slirp_hostname[33]; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src - Cópia/network/slirp/main.h b/src - Cópia/network/slirp/main.h deleted file mode 100644 index 181b6ae88..000000000 --- a/src - Cópia/network/slirp/main.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#define TOWRITEMAX 512 - -extern struct timeval tt; -extern int link_up; -extern int slirp_socket; -extern int slirp_socket_unit; -extern int slirp_socket_port; -extern u_int32_t slirp_socket_addr; -extern char *slirp_socket_passwd; -extern int ctty_closed; - -/* - * Get the difference in 2 times from updtim() - * Allow for wraparound times, "just in case" - * x is the greater of the 2 (current time) and y is - * what it's being compared against. - */ -#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y) - -extern char *slirp_tty; -extern char *exec_shell; -extern u_int curtime; -extern fd_set *global_readfds, *global_writefds, *global_xfds; -extern struct in_addr ctl_addr; -extern struct in_addr special_addr; -extern struct in_addr alias_addr; -extern struct in_addr our_addr; -extern struct in_addr loopback_addr; -extern struct in_addr dns_addr; -extern char *username; -extern char *socket_path; -extern int towrite_max; -extern int ppp_exit; -extern int so_options; -extern int tcp_keepintvl; -extern uint8_t client_ethaddr[6]; - -#define PROTO_SLIP 0x1 -#ifdef USE_PPP -#define PROTO_PPP 0x2 -#endif - -void if_encap(const uint8_t *ip_data, int ip_data_len); diff --git a/src - Cópia/network/slirp/mbuf.c b/src - Cópia/network/slirp/mbuf.c deleted file mode 100644 index c7f3f3fe8..000000000 --- a/src - Cópia/network/slirp/mbuf.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -/* - * mbuf's in SLiRP are much simpler than the real mbufs in - * FreeBSD. They are fixed size, determined by the MTU, - * so that one whole packet can fit. Mbuf's cannot be - * chained together. If there's more data than the mbuf - * could hold, an external malloced buffer is pointed to - * by m_ext (and the data pointers) and M_EXT is set in - * the flags - */ - -#include -#include "slirp.h" - -struct mbuf *mbutl; -char *mclrefcnt; -int mbuf_alloced = 0; -struct SLIRPmbuf m_freelist, m_usedlist; -int mbuf_thresh = 30; -int mbuf_max = 0; -size_t msize; - -void -m_init() -{ - m_freelist.m_next = m_freelist.m_prev = &m_freelist; - m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; - msize_init(); -} - -void msize_init() -{ - /* - * Find a nice value for msize - * XXX if_maxlinkhdr already in mtu - */ - msize = (if_mtu>if_mru?if_mtu:if_mru) + - if_maxlinkhdr + sizeof(struct m_hdr ) + 6; -} - -/* - * Get an mbuf from the free list, if there are none - * malloc one - * - * Because fragmentation can occur if we alloc new mbufs and - * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, - * which tells m_free to actually free() it - */ -struct SLIRPmbuf * m_get() -{ - struct SLIRPmbuf *m; - int flags = 0; - - DEBUG_CALL("m_get"); - - if (m_freelist.m_next == &m_freelist) { - m = (struct SLIRPmbuf *)malloc(msize); - if (m == NULL) goto end_error; - mbuf_alloced++; - if (mbuf_alloced > mbuf_thresh) - flags = M_DOFREE; - if (mbuf_alloced > mbuf_max) - mbuf_max = mbuf_alloced; - } else { - m = m_freelist.m_next; - remque(m); - } - - /* Insert it in the used list */ - insque(m,&m_usedlist); - m->m_flags = (flags | M_USEDLIST); - - /* Initialise it */ - m->m_size = msize - sizeof(struct m_hdr); - m->m_data = m->m_dat; - m->m_len = 0; - m->m_nextpkt = 0; - m->m_prevpkt = 0; -end_error: - DEBUG_ARG("m = %lx", (long )m); - return m; -} - -//For some reason this fails in GDB saying tehre is no m_flags member -void -m_free(m) - struct SLIRPmbuf *m; -{ - - DEBUG_CALL("m_free"); - DEBUG_ARG("m = %lx", (long )m); - - if(m) { - /* Remove from m_usedlist */ - if (m->m_flags & M_USEDLIST) - remque(m); - - - - /* If it's M_EXT, free() it */ - if (m->m_flags & M_EXT) - free(m->m_ext); - - /* - * Either free() it or put it on the free list - */ - if (m->m_flags & M_DOFREE) { - free(m); - mbuf_alloced--; - } else if ((m->m_flags & M_FREELIST) == 0) { - insque(m,&m_freelist); - m->m_flags = M_FREELIST; /* Clobber other flags */ - } - } /* if(m) */ -} - -/* - * Copy data from one mbuf to the end of - * the other.. if result is too big for one mbuf, malloc() - * an M_EXT data segment - */ -void -m_cat(m, n) - struct SLIRPmbuf *m, *n; -{ - /* - * If there's no room, realloc - */ - if (M_FREEROOM(m) < n->m_len) - m_inc(m,m->m_size+MINCSIZE); - - memcpy(m->m_data+m->m_len, n->m_data, n->m_len); - m->m_len += n->m_len; - - m_free(n); -} - - -/* make m size bytes large */ -void -m_inc(m, size) - struct SLIRPmbuf *m; - int size; -{ - int datasize; - - /* some compiles throw up on gotos. This one we can fake. */ - if(m->m_size>size) return; - - if (m->m_flags & M_EXT) { - datasize = m->m_data - m->m_ext; - m->m_ext = (char *)realloc(m->m_ext,size); -/* if (m->m_ext == NULL) - * return (struct SLIRPmbuf *)NULL; - */ - m->m_data = m->m_ext + datasize; - } else { - char *dat; - datasize = m->m_data - m->m_dat; - dat = (char *)malloc(size); -/* if (dat == NULL) - * return (struct SLIRPmbuf *)NULL; - */ - memcpy(dat, m->m_dat, m->m_size); - - m->m_ext = dat; - m->m_data = m->m_ext + datasize; - m->m_flags |= M_EXT; - } - - m->m_size = size; - -} - - - -void -m_adj(m, len) - struct SLIRPmbuf *m; - int len; -{ - if (m == NULL) - return; - if (len >= 0) { - /* Trim from head */ - m->m_data += len; - m->m_len -= len; - } else { - /* Trim from tail */ - len = -len; - m->m_len -= len; - } -} - - -/* - * Copy len bytes from m, starting off bytes into n - */ -int -m_copy(n, m, off, len) - struct SLIRPmbuf *n, *m; - int off, len; -{ - if (len > M_FREEROOM(n)) - return -1; - - memcpy((n->m_data + n->m_len), (m->m_data + off), len); - n->m_len += len; - return 0; -} - - -/* - * Given a pointer into an mbuf, return the mbuf - * XXX This is a kludge, I should eliminate the need for it - * Fortunately, it's not used often - */ -struct SLIRPmbuf * -dtom(dat) - void *dat; -{ - struct SLIRPmbuf *m; - - DEBUG_CALL("dtom"); - DEBUG_ARG("dat = %lx", (long )dat); - - /* bug corrected for M_EXT buffers */ - for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) { - if (m->m_flags & M_EXT) { - if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) - return m; - } else { - if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) - return m; - } - } - - DEBUG_ERROR((dfd, "dtom failed")); - - return (struct SLIRPmbuf *)0; -} - diff --git a/src - Cópia/network/slirp/mbuf.h b/src - Cópia/network/slirp/mbuf.h deleted file mode 100644 index 4921506b5..000000000 --- a/src - Cópia/network/slirp/mbuf.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 - * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp - */ - -#ifndef _MBUF_H_ -#define _MBUF_H_ - -#define m_freem m_free - - -#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ - -/* - * Macros for type conversion - * mtod(m,t) - convert mbuf pointer to data pointer of correct type - * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX) - */ -#define mtod(m,t) ((t)(m)->m_data) -/* #define dtom(x) ((struct SLIRPmbuf *)((int)(x) & ~(M_SIZE-1))) */ - -/* XXX About mbufs for slirp: - * Only one mbuf is ever used in a chain, for each "cell" of data. - * m_nextpkt points to the next packet, if fragmented. - * If the data is too large, the M_EXT is used, and a larger block - * is alloced. Therefore, m_free[m] must check for M_EXT and if set - * free the m_ext. This is inefficient memory-wise, but who cares. - */ - -/* XXX should union some of these! */ -/* header at beginning of each mbuf: */ -struct m_hdr { - struct SLIRPmbuf *mh_next; /* Linked list of mbufs */ - struct SLIRPmbuf *mh_prev; - struct SLIRPmbuf *mh_nextpkt; /* Next packet in queue/record */ - struct SLIRPmbuf *mh_prevpkt; /* Flags aren't used in the output queue */ - int mh_flags; /* Misc flags */ - - size_t mh_size; /* Size of data */ - struct SLIRPsocket *mh_so; - - SLIRPcaddr_t mh_data; /* Location of data */ - int32_t mh_len; /* Amount of data in this mbuf */ -}; - -/* - * How much room is in the mbuf, from m_data to the end of the mbuf - */ -#define M_ROOM(m) ((m->m_flags & M_EXT)? \ - (((m)->m_ext + (m)->m_size) - (m)->m_data) \ - : \ - (((m)->m_dat + (m)->m_size) - (m)->m_data)) - -/* - * How much free room there is - */ -#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len) -#define M_TRAILINGSPACE M_FREEROOM - -struct SLIRPmbuf { - struct m_hdr m_hdr; - union M_dat { - char m_dat_[1]; /* ANSI don't like 0 sized arrays */ - char *m_ext_; - } M_dat; -}; - -#define m_next m_hdr.mh_next -#define m_prev m_hdr.mh_prev -#define m_nextpkt m_hdr.mh_nextpkt -#define m_prevpkt m_hdr.mh_prevpkt -#define m_flags m_hdr.mh_flags -#define m_len m_hdr.mh_len -#define m_data m_hdr.mh_data -#define m_size m_hdr.mh_size -#define m_dat M_dat.m_dat_ -#define m_ext M_dat.m_ext_ -#define m_so m_hdr.mh_so - -#define ifq_prev m_prev -#define ifq_next m_next -#define ifs_prev m_prevpkt -#define ifs_next m_nextpkt -#define ifq_so m_so - -#define M_EXT 0x01 /* m_ext points to more (malloced) data */ -#define M_FREELIST 0x02 /* mbuf is on free list */ -#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */ -#define M_DOFREE 0x08 /* when m_free is called on the mbuf, free() - * it rather than putting it on the free list */ - -/* - * Mbuf statistics. XXX - */ - -struct mbstat { - int mbs_alloced; /* Number of mbufs allocated */ - -}; - -extern struct mbstat mbstat; -extern int mbuf_alloced; -extern struct SLIRPmbuf m_freelist, m_usedlist; -extern int mbuf_max; - -void m_init _P((void)); -void msize_init _P((void)); -struct SLIRPmbuf * m_get _P((void)); -void m_free _P((struct SLIRPmbuf *)); -void m_cat _P((register struct SLIRPmbuf *, register struct SLIRPmbuf *)); -void m_inc _P((struct SLIRPmbuf *, int)); -void m_adj _P((struct SLIRPmbuf *, int)); -int m_copy _P((struct SLIRPmbuf *, struct SLIRPmbuf *, int, int)); -struct SLIRPmbuf * dtom _P((void *)); - -#endif diff --git a/src - Cópia/network/slirp/misc.c b/src - Cópia/network/slirp/misc.c deleted file mode 100644 index ae86bb3be..000000000 --- a/src - Cópia/network/slirp/misc.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#ifndef _WIN32 -# include -#endif -#include "slirp.h" - -u_int curtime, time_fasttimo, last_slowtimo, detach_time; -u_int detach_wait = 600000; /* 10 minutes */ - -#if 0 -int x_port = -1; -int x_display = 0; -int x_screen = 0; - -int -show_x(buff, inso) - char *buff; - struct SLIRPsocket *inso; -{ - if (x_port < 0) { - lprint("X Redir: X not being redirected.\r\n"); - } else { - lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n", - inet_ntoa(our_addr), x_port, x_screen); - lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n", - inet_ntoa(our_addr), x_port, x_screen); - if (x_display) - lprint("X Redir: Redirecting to display %d\r\n", x_display); - } - - return CFG_OK; -} - - -/* - * XXX Allow more than one X redirection? - */ -void -redir_x(inaddr, start_port, display, screen) - u_int32_t inaddr; - int start_port; - int display; - int screen; -{ - int i; - - if (x_port >= 0) { - lprint("X Redir: X already being redirected.\r\n"); - show_x(0, 0); - } else { - for (i = 6001 + (start_port-1); i <= 6100; i++) { - if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { - /* Success */ - x_port = i - 6000; - x_display = display; - x_screen = screen; - show_x(0, 0); - return; - } - } - lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); - } -} -#endif - -#ifndef HAVE_INET_ATON -int -inet_aton(cp, ia) - const char *cp; - struct in_addr *ia; -{ - u_int32_t addr = inet_addr(cp); - if (addr == 0xffffffff) - return 0; - ia->s_addr = addr; - return 1; -} -#endif - - -extern void pclog(char *fmt, ...); - - -/* - * Get our IP address and put it in our_addr - */ -void -getouraddr() -{ - char buff[512]; - struct hostent *he = NULL; -#define ANCIENT -#ifdef ANCIENT - if (gethostname(buff,500) == 0) - he = gethostbyname(buff); - if (he) - our_addr = *(struct in_addr *)he->h_addr; - if (our_addr.s_addr == 0) - our_addr.s_addr = loopback_addr.s_addr; -#else - if (gethostname(buff,256) == 0) - { - struct addrinfo hints = { 0 }; - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET; - struct addrinfo* ai; - if (getaddrinfo(buff, NULL, &hints, &ai) == 0) - { - our_addr = *(struct in_addr *)ai->ai_addr->sa_data; - freeaddrinfo(ai); - } - } - if (our_addr.s_addr == 0) - our_addr.s_addr = loopback_addr.s_addr; -#endif -#undef ANCIENT - pclog(" Our IP address: %s (%s)\n", inet_ntoa(our_addr), buff); -} - -//#if SIZEOF_CHAR_P == 8 -//what?! - -struct quehead_32 { - uintptr_t qh_link; - uintptr_t qh_rlink; -}; - -inline void -insque_32(a, b) - void *a; - void *b; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (uintptr_t)element; - element->qh_rlink = (uintptr_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (uintptr_t)element; -} - -inline void -remque_32(a) - void *a; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -//#endif /* SIZEOF_CHAR_P == 8 */ -//Should be for 64bit - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -void -insque(a, b) - void *a, *b; -{ - register struct quehead *element = (struct quehead *) a; - register struct quehead *head = (struct quehead *) b; - element->qh_link = head->qh_link; - head->qh_link = (struct quehead *)element; - element->qh_rlink = (struct quehead *)head; - ((struct quehead *)(element->qh_link))->qh_rlink - = (struct quehead *)element; -} - -void -remque(a) - void *a; -{ - register struct quehead *element = (struct quehead *) a; - ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = NULL; - /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */ -} - -/* #endif */ - - -int -add_exec(ex_ptr, do_pty, exec, addr, port) - struct ex_list **ex_ptr; - int do_pty; - char *exec; - int addr; - int port; -{ - struct ex_list *tmp_ptr; - - /* First, check if the port is "bound" */ - for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { - if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) - return -1; - } - - tmp_ptr = *ex_ptr; - *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); - (*ex_ptr)->ex_fport = port; - (*ex_ptr)->ex_addr = addr; - (*ex_ptr)->ex_pty = do_pty; - (*ex_ptr)->ex_exec = strdup(exec); - (*ex_ptr)->ex_next = tmp_ptr; - return 0; -} - -#ifndef HAVE_STRERROR - -/* - * For systems with no strerror - */ -char * -SLIRPstrerror(error) - int error; -{ - if (error < sys_nerr) - return sys_errlist[error]; - else - return "Unknown error."; -} - -#endif - - -#ifdef _WIN32 - -int -fork_exec(so, ex, do_pty) - struct SLIRPsocket *so; - char *ex; - int do_pty; -{ - /* not implemented */ - return 0; -} - -#else - -int -slirp_openpty(amaster, aslave) - int *amaster, *aslave; -{ - register int master, slave; - -#ifdef HAVE_GRANTPT - char *ptr; - - if ((master = open("/dev/ptmx", O_RDWR)) < 0 || - grantpt(master) < 0 || - unlockpt(master) < 0 || - (ptr = ptsname(master)) == NULL) { - close(master); - return -1; - } - - if ((slave = open(ptr, O_RDWR)) < 0 || - ioctl(slave, I_PUSH, "ptem") < 0 || - ioctl(slave, I_PUSH, "ldterm") < 0 || - ioctl(slave, I_PUSH, "ttcompat") < 0) { - close(master); - close(slave); - return -1; - } - - *amaster = master; - *aslave = slave; - return 0; - -#else - - static char line[] = "/dev/ptyXX"; - register const char *cp1, *cp2; - - for (cp1 = "pqrsPQRS"; *cp1; cp1++) { - line[8] = *cp1; - for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { - line[9] = *cp2; - if ((master = open(line, O_RDWR, 0)) == -1) { - if (errno == ENOENT) - return (-1); /* out of ptys */ - } else { - line[5] = 't'; - /* These will fail */ - (void) chown(line, getuid(), 0); - (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); -#ifdef HAVE_REVOKE - (void) revoke(line); -#endif - if ((slave = open(line, O_RDWR, 0)) != -1) { - *amaster = master; - *aslave = slave; - return 0; - } - (void) close(master); - line[5] = 'p'; - } - } - } - errno = ENOENT; /* out of ptys */ - return (-1); -#endif -} - -/* - * XXX This is ugly - * We create and bind a socket, then fork off to another - * process, which connects to this socket, after which we - * exec the wanted program. If something (strange) happens, - * the accept() call could block us forever. - * - * do_pty = 0 Fork/exec inetd style - * do_pty = 1 Fork/exec using slirp.telnetd - * do_ptr = 2 Fork/exec using pty - */ -int -fork_exec(so, ex, do_pty) - struct SLIRPsocket *so; - char *ex; - int do_pty; -{ - int s; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - int opt; - int master; - char *argv[256]; -#if 0 - char buff[256]; -#endif - /* don't want to clobber the original */ - char *bptr; - char *curarg; - int c, i, ret; - - DEBUG_CALL("fork_exec"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("ex = %lx", (long)ex); - DEBUG_ARG("do_pty = %lx", (long)do_pty); - - if (do_pty == 2) { - if (slirp_openpty(&master, &s) == -1) { - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } - } else { - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = INADDR_ANY; - - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || - bind(s, (struct sockaddr *)&addr, addrlen) < 0 || - listen(s, 1) < 0) { - lprint("Error: inet socket: %s\n", strerror(errno)); - closesocket(s); - - return 0; - } - } - - switch(fork()) { - case -1: - lprint("Error: fork failed: %s\n", strerror(errno)); - close(s); - if (do_pty == 2) - close(master); - return 0; - - case 0: - /* Set the DISPLAY */ - if (do_pty == 2) { - (void) close(master); -#ifdef TIOCSCTTY /* XXXXX */ - (void) setsid(); - ioctl(s, TIOCSCTTY, (char *)NULL); -#endif - } else { - getsockname(s, (struct sockaddr *)&addr, &addrlen); - close(s); - /* - * Connect to the socket - * XXX If any of these fail, we're in trouble! - */ - s = socket(AF_INET, SOCK_STREAM, 0); - addr.sin_addr = loopback_addr; - do { - ret = connect(s, (struct sockaddr *)&addr, addrlen); - } while (ret < 0 && errno == EINTR); - } - -#if 0 - if (x_port >= 0) { -#ifdef HAVE_SETENV - sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - setenv("DISPLAY", buff, 1); -#else - sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - putenv(buff); -#endif - } -#endif - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - for (s = 3; s <= 255; s++) - close(s); - - i = 0; - bptr = strdup(ex); /* No need to free() this */ - if (do_pty == 1) { - /* Setup "slirp.telnetd -x" */ - argv[i++] = "slirp.telnetd"; - argv[i++] = "-x"; - argv[i++] = bptr; - } else - do { - /* Change the string into argv[] */ - curarg = bptr; - while (*bptr != ' ' && *bptr != (char)0) - bptr++; - c = *bptr; - *bptr++ = (char)0; - argv[i++] = strdup(curarg); - } while (c); - - argv[i] = 0; - execvp(argv[0], argv); - - /* Ooops, failed, let's tell the user why */ - { - char buff[256]; - - sprintf(buff, "Error: execvp of %s failed: %s\n", - argv[0], strerror(errno)); - write(2, buff, strlen(buff)+1); - } - close(0); close(1); close(2); /* XXX */ - exit(1); - - default: - if (do_pty == 2) { - close(s); - so->s = master; - } else { - /* - * XXX this could block us... - * XXX Should set a timer here, and if accept() doesn't - * return after X seconds, declare it a failure - * The only reason this will block forever is if socket() - * of connect() fail in the child process - */ - do { - so->s = accept(s, (struct sockaddr *)&addr, &addrlen); - } while (so->s < 0 && errno == EINTR); - closesocket(s); - opt = 1; - setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - } - fd_nonblock(so->s); - - /* Append the telnet options now */ - if (so->so_m != 0 && do_pty == 1) { - sbappend(so, so->so_m); - so->so_m = 0; - } - - return 1; - } -} -#endif - -#ifndef HAVE_STRDUP -char * strdup(char *str) -{ - char *bptr; - - bptr = (char *)malloc(strlen(str)+1); - strcpy(bptr, str); - - return bptr; -} -#endif - -#if 0 -void -snooze_hup(num) - int num; -{ - int s, ret; -#ifndef NO_UNIX_SOCKETS - struct sockaddr_un sock_un; -#endif - struct sockaddr_in sock_in; - char buff[256]; - - ret = -1; - if (slirp_socket_passwd) { - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - slirp_exit(1); - sock_in.sin_family = AF_INET; - sock_in.sin_addr.s_addr = slirp_socket_addr; - sock_in.sin_port = htons(slirp_socket_port); - if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0) - slirp_exit(1); /* just exit...*/ - sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit); - write(s, buff, strlen(buff)+1); - } -#ifndef NO_UNIX_SOCKETS - else { - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s < 0) - slirp_exit(1); - sock_un.sun_family = AF_UNIX; - strcpy(sock_un.sun_path, socket_path); - if (connect(s, (struct sockaddr *)&sock_un, - sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0) - slirp_exit(1); - sprintf(buff, "kill none:%d", slirp_socket_unit); - write(s, buff, strlen(buff)+1); - } -#endif - slirp_exit(0); -} - - -void -snooze() -{ - sigset_t s; - int i; - - /* Don't need our data anymore */ - /* XXX This makes SunOS barf */ -/* brk(0); */ - - /* Close all fd's */ - for (i = 255; i >= 0; i--) - close(i); - - signal(SIGQUIT, slirp_exit); - signal(SIGHUP, snooze_hup); - sigemptyset(&s); - - /* Wait for any signal */ - sigsuspend(&s); - - /* Just in case ... */ - exit(255); -} - -void -relay(s) - int s; -{ - char buf[8192]; - int n; - fd_set readfds; - struct ttys *ttyp; - - /* Don't need our data anymore */ - /* XXX This makes SunOS barf */ -/* brk(0); */ - - signal(SIGQUIT, slirp_exit); - signal(SIGHUP, slirp_exit); - signal(SIGINT, slirp_exit); - signal(SIGTERM, slirp_exit); - - /* Fudge to get term_raw and term_restore to work */ - if (NULL == (ttyp = tty_attach (0, slirp_tty))) { - lprint ("Error: tty_attach failed in misc.c:relay()\r\n"); - slirp_exit (1); - } - ttyp->fd = 0; - ttyp->flags |= TTY_CTTY; - term_raw(ttyp); - - while (1) { - FD_ZERO(&readfds); - - FD_SET(0, &readfds); - FD_SET(s, &readfds); - - n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); - - if (n <= 0) - slirp_exit(0); - - if (FD_ISSET(0, &readfds)) { - n = read(0, buf, 8192); - if (n <= 0) - slirp_exit(0); - n = writen(s, buf, n); - if (n <= 0) - slirp_exit(0); - } - - if (FD_ISSET(s, &readfds)) { - n = read(s, buf, 8192); - if (n <= 0) - slirp_exit(0); - n = writen(0, buf, n); - if (n <= 0) - slirp_exit(0); - } - } - - /* Just in case.... */ - exit(1); -} -#endif - -int (*lprint_print) _P((void *, const char *, va_list)); -char *lprint_ptr, *lprint_ptr2, **lprint_arg; - -#ifdef _MSC_VER //aren't we -#define __STDC__ -#endif - -void -#ifdef __STDC__ -lprint(const char *format, ...) -#else -lprint(va_alist) va_dcl -#endif -{ - va_list args; - -#ifdef __STDC__ - va_start(args, format); -#else - char *format; - va_start(args); - format = va_arg(args, char *); -#endif -#if 0 - /* If we're printing to an sbuf, make sure there's enough room */ - /* XXX +100? */ - if (lprint_sb) { - if ((lprint_ptr - lprint_sb->sb_wptr) >= - (lprint_sb->sb_datalen - (strlen(format) + 100))) { - int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data; - int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data; - int deltap = lprint_ptr - lprint_sb->sb_data; - - lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data, - lprint_sb->sb_datalen + TCP_SNDSPACE); - - /* Adjust all values */ - lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw; - lprint_sb->sb_rptr = lprint_sb->sb_data + deltar; - lprint_ptr = lprint_sb->sb_data + deltap; - - lprint_sb->sb_datalen += TCP_SNDSPACE; - } - } -#endif - if (lprint_print) - lprint_ptr += (*lprint_print)(*lprint_arg, format, args); - - /* Check if they want output to be logged to file as well */ - if (lfd) { - /* - * Remove \r's - * otherwise you'll get ^M all over the file - */ - int len = strlen(format); - char *bptr1, *bptr2; - - bptr1 = bptr2 = strdup(format); - - while (len--) { - if (*bptr1 == '\r') - memcpy(bptr1, bptr1+1, len+1); - else - bptr1++; - } - vfprintf(lfd, bptr2, args); - free(bptr2); - } - va_end(args); -} - -void -add_emu(buff) - char *buff; -{ - u_int lport, fport; - u_int8_t tos = 0, emu = 0; - char buff1[256], buff2[256], buff4[128]; - char *buff3 = buff4; - struct emu_t *emup; - struct SLIRPsocket *so; - - if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { - lprint("Error: Bad arguments\r\n"); - return; - } - - if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { - lport = 0; - if (sscanf(buff1, "%d", &fport) != 1) { - lprint("Error: Bad first argument\r\n"); - return; - } - } - - if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { - buff3 = 0; - if (sscanf(buff2, "%256s", buff1) != 1) { - lprint("Error: Bad second argument\r\n"); - return; - } - } - - if (buff3) { - if (strcmp(buff3, "lowdelay") == 0) - tos = IPTOS_LOWDELAY; - else if (strcmp(buff3, "throughput") == 0) - tos = IPTOS_THROUGHPUT; - else { - lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n"); - return; - } - } - - if (strcmp(buff1, "ftp") == 0) - emu = EMU_FTP; - else if (strcmp(buff1, "irc") == 0) - emu = EMU_IRC; - else if (strcmp(buff1, "none") == 0) - emu = EMU_NONE; /* ie: no emulation */ - else { - lprint("Error: Unknown service\r\n"); - return; - } - - /* First, check that it isn't already emulated */ - for (emup = tcpemu; emup; emup = emup->next) { - if (emup->lport == lport && emup->fport == fport) { - lprint("Error: port already emulated\r\n"); - return; - } - } - - /* link it */ - emup = (struct emu_t *)malloc(sizeof (struct emu_t)); - emup->lport = (u_int16_t)lport; - emup->fport = (u_int16_t)fport; - emup->tos = tos; - emup->emu = emu; - emup->next = tcpemu; - tcpemu = emup; - - /* And finally, mark all current sessions, if any, as being emulated */ - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - if ((lport && lport == ntohs(so->so_lport)) || - (fport && fport == ntohs(so->so_fport))) { - if (emu) - so->so_emu = emu; - if (tos) - so->so_iptos = tos; - } - } - - lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); -} - -#ifdef BAD_SPRINTF - -#undef vsprintf -#undef sprintf - -/* - * Some BSD-derived systems have a sprintf which returns char * - */ - -int -vsprintf_len(string, format, args) - char *string; - const char *format; - va_list args; -{ - vsprintf(string, format, args); - return strlen(string); -} - -int -#ifdef __STDC__ -sprintf_len(char *string, const char *format, ...) -#else -sprintf_len(va_alist) va_dcl -#endif -{ - va_list args; -#ifdef __STDC__ - va_start(args, format); -#else - char *string; - char *format; - va_start(args); - string = va_arg(args, char *); - format = va_arg(args, char *); -#endif - vsprintf(string, format, args); - return strlen(string); -} - -#endif - -void -u_sleep(usec) - int usec; -{ - struct timeval t; - fd_set fdset; - - FD_ZERO(&fdset); - - t.tv_sec = 0; - t.tv_usec = usec * 1000; - - select(0, &fdset, &fdset, &fdset, &t); -} - -/* - * Set fd blocking and non-blocking - */ - -void -fd_nonblock(fd) - int fd; -{ -#if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 1; - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt |= O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - -void -fd_block(fd) - int fd; -{ -#if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 0; - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt &= ~O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - - -#if 0 -/* - * invoke RSH - */ -int -rsh_exec(so,ns, user, host, args) - struct SLIRPsocket *so; - struct SLIRPsocket *ns; - char *user; - char *host; - char *args; -{ - int fd[2]; - int fd0[2]; - int s; - char buff[256]; - - DEBUG_CALL("rsh_exec"); - DEBUG_ARG("so = %lx", (long)so); - - if (pipe(fd)<0) { - lprint("Error: pipe failed: %s\n", strerror(errno)); - return 0; - } -/* #ifdef HAVE_SOCKETPAIR */ -#if 1 - if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) { - close(fd[0]); - close(fd[1]); - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } -#else - if (slirp_openpty(&fd0[0], &fd0[1]) == -1) { - close(fd[0]); - close(fd[1]); - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } -#endif - - switch(fork()) { - case -1: - lprint("Error: fork failed: %s\n", strerror(errno)); - close(fd[0]); - close(fd[1]); - close(fd0[0]); - close(fd0[1]); - return 0; - - case 0: - close(fd[0]); - close(fd0[0]); - - /* Set the DISPLAY */ - if (x_port >= 0) { -#ifdef HAVE_SETENV - sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - setenv("DISPLAY", buff, 1); -#else - sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - putenv(buff); -#endif - } - - dup2(fd0[1], 0); - dup2(fd0[1], 1); - dup2(fd[1], 2); - for (s = 3; s <= 255; s++) - close(s); - - execlp("rsh","rsh","-l", user, host, args, NULL); - - /* Ooops, failed, let's tell the user why */ - - sprintf(buff, "Error: execlp of %s failed: %s\n", - "rsh", strerror(errno)); - write(2, buff, strlen(buff)+1); - close(0); close(1); close(2); /* XXX */ - exit(1); - - default: - close(fd[1]); - close(fd0[1]); - ns->s=fd[0]; - so->s=fd0[0]; - - return 1; - } -} -#endif diff --git a/src - Cópia/network/slirp/misc.h b/src - Cópia/network/slirp/misc.h deleted file mode 100644 index c509deb92..000000000 --- a/src - Cópia/network/slirp/misc.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _MISC_H_ -#define _MISC_H_ - -struct ex_list { - int ex_pty; /* Do we want a pty? */ - int ex_addr; /* The last byte of the address */ - int ex_fport; /* Port to telnet to */ - char *ex_exec; /* Command line of what to exec */ - struct ex_list *ex_next; -}; - -extern struct ex_list *exec_list; -extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait; - -extern int (*lprint_print) _P((void *, const char *, va_list)); -extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; -extern struct sbuf *lprint_sb; - -#ifndef HAVE_STRDUP -char *strdup _P((const char *)); -#endif - -void do_wait _P((int)); - -#define EMU_NONE 0x0 - -/* TCP emulations */ -#define EMU_CTL 0x1 -#define EMU_FTP 0x2 -#define EMU_KSH 0x3 -#define EMU_IRC 0x4 -#define EMU_REALAUDIO 0x5 -#define EMU_RLOGIN 0x6 -#define EMU_IDENT 0x7 -#define EMU_RSH 0x8 - -#define EMU_NOCONNECT 0x10 /* Don't connect */ - -/* UDP emulations */ -#define EMU_TALK 0x1 -#define EMU_NTALK 0x2 -#define EMU_CUSEEME 0x3 - -struct tos_t { - u_int16_t lport; - u_int16_t fport; - u_int8_t tos; - u_int8_t emu; -}; - -struct emu_t { - u_int16_t lport; - u_int16_t fport; - u_int8_t tos; - u_int8_t emu; - struct emu_t *next; -}; - -extern struct emu_t *tcpemu; - -extern int x_port, x_server, x_display; - -int show_x _P((char *, struct SLIRPsocket *)); -void redir_x _P((u_int32_t, int, int, int)); -void getouraddr _P((void)); -void slirp_insque _P((void *, void *)); -void slirp_remque _P((void *)); -int add_exec _P((struct ex_list **, int, char *, int, int)); -int slirp_openpty _P((int *, int *)); -int fork_exec _P((struct SLIRPsocket *, char *, int)); -void snooze_hup _P((int)); -void snooze _P((void)); -void relay _P((int)); -void add_emu _P((char *)); -void u_sleep _P((int)); -void fd_nonblock _P((int)); -void fd_block _P((int)); -int rsh_exec _P((struct SLIRPsocket *, struct SLIRPsocket *, char *, char *, char *)); - -#endif diff --git a/src - Cópia/network/slirp/queue.c b/src - Cópia/network/slirp/queue.c deleted file mode 100644 index d91004ad4..000000000 --- a/src - Cópia/network/slirp/queue.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * File: queue.c - * Author: Robert I. Pitts - * Last Modified: March 9, 2000 - * Topic: Queue - Array Implementation - * ---------------------------------------------------------------- - */ - -#include -#include -#include "queue.h" - -/* - * Constants - * --------- - * MAX_QUEUE_SIZE = Largest number of items queue can hold. - */ - -#define MAX_QUEUE_SIZE 100 - -/* - * struct queueCDT gives the implementation of a queue. - * It holds the information that we need for each queue. - */ -typedef struct queueCDT { - queueElementT contents[MAX_QUEUE_SIZE]; - int front; - int count; -} queueCDT; - -queueADT QueueCreate(void) -{ - queueADT queue; - - queue = (queueADT)malloc(sizeof(queueCDT)); - - if (queue == NULL) { - fprintf(stderr, "Insufficient Memory for new Queue.\n"); - exit(ERROR_MEMORY); /* Exit program, returning error code. */ - } - - queue->front = 0; - queue->count = 0; - - return queue; -} - -void QueueDestroy(queueADT queue) -{ - free(queue); -} - -void QueueEnter(queueADT queue, queueElementT element) -{ - int newElementIndex; - - if (queue->count >= MAX_QUEUE_SIZE) { -// fprintf(stderr, "QueueEnter on Full Queue.\n"); -// exit(ERROR_QUEUE); /* Exit program, returning error code. */ - return; - } - - /* - * Calculate index at which to put - * next element. - */ - newElementIndex = (queue->front + queue->count) - % MAX_QUEUE_SIZE; - queue->contents[newElementIndex] = element; -//printf("element %d, pointer to %d, [%s]\n",newElementIndex,element,element); - - queue->count++; -} - -int QueuePeek(queueADT queue) -{ -return queue->count; -} - -queueElementT QueueDelete(queueADT queue) -{ - queueElementT oldElement; - - if (queue->count <= 0) { - //fprintf(stderr, "QueueDelete on Empty Queue.\n"); - //exit(ERROR_QUEUE); /* Exit program, returning error code. */ - return NULL; - } - - /* Save the element so we can return it. */ - oldElement = queue->contents[queue->front]; - - /* - * Advance the index of the front, - * making sure it wraps around the - * array properly. - */ - queue->front++; - queue->front %= MAX_QUEUE_SIZE; - -//printf("dequing @%d [%s]\n",oldElement,oldElement); - - queue->count--; - - return oldElement; -} - -int QueueIsEmpty(queueADT queue) -{ - return queue->count <= 0; -} - -int QueueIsFull(queueADT queue) -{ - return queue->count >= MAX_QUEUE_SIZE; -} diff --git a/src - Cópia/network/slirp/queue.h b/src - Cópia/network/slirp/queue.h deleted file mode 100644 index 786950ab7..000000000 --- a/src - Cópia/network/slirp/queue.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * File: queue.h - * Author: Robert I. Pitts - * Last Modified: March 9, 2000 - * Topic: Queue - Array Implementation - * ---------------------------------------------------------------- - */ - -#ifndef _QUEUE_H -#define _QUEUE_H - -/* - * Constants - * --------- - * ERROR_* These signal error conditions in queue functions - * and are used as exit codes for the program. - */ -#define ERROR_QUEUE 2 -#define ERROR_MEMORY 3 - -/* - * Type: queueElementT - * ------------------- - * This is the type of objects held in the queue. - */ - -/*typedef char queueElementT; -typedef unsigned char *queueElementT; -*/ - -struct queuepacket{ - int len; - unsigned char data[2000]; -}; -typedef struct queuepacket *queueElementT; - -/* - * Type: queueADT - * -------------- - * The actual implementation of a queue is completely - * hidden. Client will work with queueADT which is a - * pointer to underlying queueCDT. - */ - -/* - * NOTE: need word struct below so that the compiler - * knows at least that a queueCDT will be some sort - * of struct. - */ - -typedef struct queueCDT *queueADT; - -/* - * Function: QueueCreate - * Usage: queue = QueueCreate(); - * ------------------------- - * A new empty queue is created and returned. - */ - -queueADT QueueCreate(void); - -/* Function: QueueDestroy - * Usage: QueueDestroy(queue); - * ----------------------- - * This function frees all memory associated with - * the queue. "queue" may not be used again unless - * queue = QueueCreate() is called first. - */ - -void QueueDestroy(queueADT queue); - -/* - * Functions: QueueEnter, QueueDelete - * Usage: QueueEnter(queue, element); - * element = QueueDelete(queue); - * -------------------------------------------- - * These are the fundamental queue operations that enter - * elements in and delete elements from the queue. A call - * to QueueDelete() on an empty queue or to QueueEnter() - * on a full queue is an error. Make use of QueueIsFull() - * and QueueIsEmpty() (see below) to avoid these errors. - */ - -void QueueEnter(queueADT queue, queueElementT element); -queueElementT QueueDelete(queueADT queue); - - -/* - * Functions: QueueIsEmpty, QueueIsFull - * Usage: if (QueueIsEmpty(queue)) ... - * ----------------------------------- - * These return a true/false value based on whether - * the queue is empty or full, respectively. - */ - -int QueueIsEmpty(queueADT queue); -int QueueIsFull(queueADT queue); - -int QueuePeek(queueADT queue); - -#endif /* not defined _QUEUE_H */ diff --git a/src - Cópia/network/slirp/sbuf.c b/src - Cópia/network/slirp/sbuf.c deleted file mode 100644 index b9baa4181..000000000 --- a/src - Cópia/network/slirp/sbuf.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#include "slirp.h" - -/* Done as a macro in socket.h */ -/* int - * sbspace(struct sockbuff *sb) - * { - * return SB_DATALEN - sb->sb_cc; - * } - */ - -void -sbfree(sb) - struct sbuf *sb; -{ - free(sb->sb_data); -} - -void -sbdrop(sb, num) - struct sbuf *sb; - int num; -{ - /* - * We can only drop how much we have - * This should never succeed - */ - if(num > sb->sb_cc) - num = sb->sb_cc; - sb->sb_cc -= num; - sb->sb_rptr += num; - if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) - sb->sb_rptr -= sb->sb_datalen; - -} - -void -sbreserve(sb, size) - struct sbuf *sb; - int size; -{ - if (sb->sb_data) { - /* Already alloced, realloc if necessary */ - if (sb->sb_datalen != size) { - sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size); - sb->sb_cc = 0; - if (sb->sb_wptr) - sb->sb_datalen = size; - else - sb->sb_datalen = 0; - } - } else { - sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size); - sb->sb_cc = 0; - if (sb->sb_wptr) - sb->sb_datalen = size; - else - sb->sb_datalen = 0; - } -} - -/* - * Try and write() to the socket, whatever doesn't get written - * append to the buffer... for a host with a fast net connection, - * this prevents an unnecessary copy of the data - * (the socket is non-blocking, so we won't hang) - */ -void -sbappend(so, m) - struct SLIRPsocket *so; - struct SLIRPmbuf *m; -{ - int ret = 0; - - DEBUG_CALL("sbappend"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m->m_len = %d", m->m_len); - - /* Shouldn't happen, but... e.g. foreign host closes connection */ - if (m->m_len <= 0) { - m_free(m); - return; - } - - /* - * If there is urgent data, call sosendoob - * if not all was sent, sowrite will take care of the rest - * (The rest of this function is just an optimisation) - */ - if (so->so_urgc) { - sbappendsb(&so->so_rcv, m); - m_free(m); - sosendoob(so); - return; - } - - /* - * We only write if there's nothing in the buffer, - * ottherwise it'll arrive out of order, and hence corrupt - */ - if (!so->so_rcv.sb_cc) - ret = send(so->s, m->m_data, m->m_len, 0); - - if (ret <= 0) { - /* - * Nothing was written - * It's possible that the socket has closed, but - * we don't need to check because if it has closed, - * it will be detected in the normal way by soread() - */ - sbappendsb(&so->so_rcv, m); - } else if (ret != m->m_len) { - /* - * Something was written, but not everything.. - * sbappendsb the rest - */ - m->m_len -= ret; - m->m_data += ret; - sbappendsb(&so->so_rcv, m); - } /* else */ - /* Whatever happened, we free the SLIRPmbuf */ - m_free(m); -} - -/* - * Copy the data from m into sb - * The caller is responsible to make sure there's enough room - */ -void -sbappendsb(sb, m) - struct sbuf *sb; - struct SLIRPmbuf *m; -{ - int len, n, nn; - - len = m->m_len; - - if (sb->sb_wptr < sb->sb_rptr) { - n = sb->sb_rptr - sb->sb_wptr; - if (n > len) n = len; - memcpy(sb->sb_wptr, m->m_data, n); - } else { - /* Do the right edge first */ - n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; - if (n > len) n = len; - memcpy(sb->sb_wptr, m->m_data, n); - len -= n; - if (len) { - /* Now the left edge */ - nn = sb->sb_rptr - sb->sb_data; - if (nn > len) nn = len; - memcpy(sb->sb_data,m->m_data+n,nn); - n += nn; - } - } - - sb->sb_cc += n; - sb->sb_wptr += n; - if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) - sb->sb_wptr -= sb->sb_datalen; -} - -/* - * Copy data from sbuf to a normal, straight buffer - * Don't update the sbuf rptr, this will be - * done in sbdrop when the data is acked - */ -void -sbcopy(sb, off, len, to) - struct sbuf *sb; - int off; - int len; - char *to; -{ - char *from; - - from = sb->sb_rptr + off; - if (from >= sb->sb_data + sb->sb_datalen) - from -= sb->sb_datalen; - - if (from < sb->sb_wptr) { - if (len > sb->sb_cc) len = sb->sb_cc; - memcpy(to,from,len); - } else { - /* re-use off */ - off = (sb->sb_data + sb->sb_datalen) - from; - if (off > len) off = len; - memcpy(to,from,off); - len -= off; - if (len) - memcpy(to+off,sb->sb_data,len); - } -} - diff --git a/src - Cópia/network/slirp/sbuf.h b/src - Cópia/network/slirp/sbuf.h deleted file mode 100644 index aa4724df7..000000000 --- a/src - Cópia/network/slirp/sbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _SBUF_H_ -#define _SBUF_H_ - -#define sbflush(sb) sbdrop((sb),(sb)->sb_cc) -#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) - -struct sbuf { - u_int sb_cc; /* actual chars in buffer */ - u_int sb_datalen; /* Length of data */ - char *sb_wptr; /* write pointer. points to where the next - * bytes should be written in the sbuf */ - char *sb_rptr; /* read pointer. points to where the next - * byte should be read from the sbuf */ - char *sb_data; /* Actual data */ -}; - -void sbfree _P((struct sbuf *)); -void sbdrop _P((struct sbuf *, int)); -void sbreserve _P((struct sbuf *, int)); -void sbappend _P((struct SLIRPsocket *, struct SLIRPmbuf *)); -void sbappendsb _P((struct sbuf *, struct SLIRPmbuf *)); -void sbcopy _P((struct sbuf *, int, int, char *)); - -#endif diff --git a/src - Cópia/network/slirp/slirp.c b/src - Cópia/network/slirp/slirp.c deleted file mode 100644 index 7457f1340..000000000 --- a/src - Cópia/network/slirp/slirp.c +++ /dev/null @@ -1,710 +0,0 @@ -#include "slirp.h" - - -/* Our actual addresses. */ -char slirp_hostname[33]; -struct in_addr our_addr; /* host IP address */ -struct in_addr dns_addr; /* host DNS server */ -struct in_addr loopback_addr; /* host loopback address */ - -/* Our SLiRP virtual addresses. */ -struct in_addr special_addr; /* virtual IP address */ -struct in_addr alias_addr; /* virtual address alias for host */ -const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 /* virtual MAC address. */ -}; - -uint8_t client_ethaddr[6]; /* guest's MAC address */ - -int do_slowtimo; -int link_up; -struct timeval tt; -FILE *lfd; -struct ex_list *exec_list; - -/* XXX: suppress those select globals */ -fd_set *global_readfds, *global_writefds, *global_xfds; - - -extern void pclog(const char *, ...); -extern int config_get_int(char *, char *, int); - -#define printf pclog - - -#ifdef _WIN32 -static int get_dns_addr(struct in_addr *pdns_addr) -{ - FIXED_INFO *FixedInfo=NULL; - ULONG BufLen; - DWORD ret; - IP_ADDR_STRING *pIPAddr; - struct in_addr tmp_addr; - - FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); - BufLen = sizeof(FIXED_INFO); - - if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - FixedInfo = GlobalAlloc(GPTR, BufLen); - } - - if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { - printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret ); - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return -1; - } - - pIPAddr = &(FixedInfo->DnsServerList); - inet_aton(pIPAddr->IpAddress.String, &tmp_addr); - *pdns_addr = tmp_addr; - printf( " DNS Servers:\n" ); - while ( pIPAddr ) { - printf( " Address: %s\n", pIPAddr ->IpAddress.String ); - pIPAddr = pIPAddr ->Next; - } - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return 0; -} - -#else - -static int get_dns_addr(struct in_addr *pdns_addr) -{ - char buff[512]; - char buff2[256]; - FILE *f; - int found = 0; - struct in_addr tmp_addr; - - f = fopen("/etc/resolv.conf", "r"); - if (!f) - return -1; - - lprint("IP address of your DNS(s): "); - while (fgets(buff, 512, f) != NULL) { - if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { - if (!inet_aton(buff2, &tmp_addr)) - continue; - if (tmp_addr.s_addr == loopback_addr.s_addr) - tmp_addr = our_addr; - /* If it's the first one, set it to dns_addr */ - if (!found) - *pdns_addr = tmp_addr; - else - lprint(", "); - if (++found > 3) { - lprint("(more)"); - break; - } else - lprint("%s", inet_ntoa(tmp_addr)); - } - } - fclose(f); - if (!found) - return -1; - return 0; -} -#endif - - -#ifdef _WIN32 -void slirp_cleanup(void) -{ - WSACleanup(); -} -#endif - - -int -slirp_init(void) -{ - char* category = "SLiRP Port Forwarding"; - char key[32]; - struct in_addr myaddr; - int i = 0, udp, from, to; - int rc; - - pclog("%s initializing..\n", category); - -#ifdef SLIRP_DEBUG - // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); - // debug_init("slirplog.txt",DEBUG_DEFAULT); - //debug_init("slirplog.txt",DBG_CALL); -debug_init("slirplog.txt",DEBUG_DEFAULT); -#endif - -#ifdef _WIN32 - { - WSADATA Data; - WSAStartup(MAKEWORD(2,0), &Data); - atexit(slirp_cleanup); - } -#endif - - link_up = 1; - - if_init(); - ip_init(); - - /* Initialise mbufs *after* setting the MTU */ - m_init(); - - /* set default addresses */ - inet_aton("127.0.0.1", &loopback_addr); - - if (get_dns_addr(&dns_addr) < 0) - return -1; - - inet_aton(CTL_SPECIAL, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); - getouraddr(); - inet_aton(CTL_LOCAL, &myaddr); - - while (1) { - sprintf(key, "%d_udp", i); - udp = config_get_int(category, key, 0); - sprintf(key, "%d_from", i); - from = config_get_int(category, key, 0); - if (from < 1) - break; - sprintf(key, "%d_to", i); - to = config_get_int(category, key, from); - - rc = slirp_redir(udp, from, myaddr, to); - if (rc == 0) - pclog("slirp redir %d -> %d successful\n", from, to); - else - pclog("slirp redir %d -> %d failed (%d)\n", from, to, rc); - - i++; - } - - return 0; -} - -#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) -#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) -#define UPD_NFDS(x) if (nfds < (x)) nfds = (x) - -/* - * curtime kept to an accuracy of 1ms - */ -#ifdef _WIN32 -static void updtime(void) -{ - struct _timeb tb; - - _ftime(&tb); - curtime = (u_int)tb.time * (u_int)1000; - curtime += (u_int)tb.millitm; -} -#else -static void updtime(void) -{ - gettimeofday(&tt, 0); - - curtime = (u_int)tt.tv_sec * (u_int)1000; - curtime += (u_int)tt.tv_usec / (u_int)1000; - - if ((tt.tv_usec % 1000) >= 500) - curtime++; -} -#endif - -int slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds) -{ - struct SLIRPsocket *so, *so_next; - int nfds; - int timeout, tmp_time; - - /* fail safe */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; - - nfds = *pnfds; - /* - * First, TCP sockets - */ - do_slowtimo = 0; - if (link_up) { - /* - * *_slowtimo needs calling if there are IP fragments - * in the fragment queue, or there are TCP connections active - */ - do_slowtimo = ((tcb.so_next != &tcb) || - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); - - for (so = tcb.so_next; (so != &tcb); so = so_next) { - so_next = so->so_next; - - - /* - * See if we need a tcp_fasttimo - */ - if(so->so_tcpcb!=0x0){ //This is to prevent a common lockup. - if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) - time_fasttimo = curtime; } /* Flag when we want a fasttimo */ - - - /* - * NOFDREF can include still connecting to local-host, - * newly socreated() sockets etc. Don't want to select these. - */ - if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - - /* - * Set for reading sockets which are accepting - */ - if (so->so_state & SS_FACCEPTCONN) { - FD_SET(so->s, readfds); - UPD_NFDS(so->s); - continue; - } - - /* - * Set for writing sockets which are connecting - */ - if (so->so_state & SS_ISFCONNECTING) { - FD_SET(so->s, writefds); - UPD_NFDS(so->s); - continue; - } - - /* - * Set for writing if we are connected, can send more, and - * we have something to send - */ - if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) { - FD_SET(so->s, writefds); - UPD_NFDS(so->s); - } - - /* - * Set for reading (and urgent data) if we are connected, can - * receive more, and we have room for it XXX /2 ? - */ - if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) { - FD_SET(so->s, readfds); - FD_SET(so->s, xfds); - UPD_NFDS(so->s); - } - } - - /* - * UDP sockets - */ - for (so = udb.so_next; so != &udb; so = so_next) { - so_next = so->so_next; - - /* - * See if it's timed out - */ - if (so->so_expire) { - if (so->so_expire <= curtime) { - udp_detach(so); - continue; - } else - do_slowtimo = 1; /* Let socket expire */ - } - - /* - * When UDP packets are received from over the - * link, they're sendto()'d straight away, so - * no need for setting for writing - * Limit the number of packets queued by this session - * to 4. Note that even though we try and limit this - * to 4 packets, the session could have more queued - * if the packets needed to be fragmented - * (XXX <= 4 ?) - */ - if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { - FD_SET(so->s, readfds); - UPD_NFDS(so->s); - } - } - } - - /* - * Setup timeout to use minimum CPU usage, especially when idle - */ - - timeout = -1; - - /* - * If a slowtimo is needed, set timeout to 5ms from the last - * slow timeout. If a fast timeout is needed, set timeout within - * 2ms of when it was requested. - */ -# define SLOW_TIMO 5 -# define FAST_TIMO 2 - if (do_slowtimo) { - timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000; - if (timeout < 0) - timeout = 0; - else if (timeout > (SLOW_TIMO * 1000)) - timeout = SLOW_TIMO * 1000; - - /* Can only fasttimo if we also slowtimo */ - if (time_fasttimo) { - tmp_time = (FAST_TIMO - (curtime - time_fasttimo)) * 1000; - if (tmp_time < 0) - tmp_time = 0; - - /* Choose the smallest of the 2 */ - if (tmp_time < timeout) - timeout = tmp_time; - } - } - *pnfds = nfds; - - /* - * Adjust the timeout to make the minimum timeout - * 2ms (XXX?) to lessen the CPU load - */ - if (timeout < (FAST_TIMO * 1000)) - timeout = FAST_TIMO * 1000; - - return timeout; -} - -void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) -{ - struct SLIRPsocket *so, *so_next; - int ret; - - global_readfds = readfds; - global_writefds = writefds; - global_xfds = xfds; - - /* Update time */ - updtime(); - - /* - * See if anything has timed out - */ - if (link_up) { - if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) { - tcp_fasttimo(); - time_fasttimo = 0; - } - if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) { - ip_slowtimo(); - tcp_slowtimo(); - last_slowtimo = curtime; - } - } - - /* - * Check sockets - */ - if (link_up) { - /* - * Check TCP sockets - */ - for (so = tcb.so_next; so != &tcb; so = so_next) { - so_next = so->so_next; - - /* - * FD_ISSET is meaningless on these sockets - * (and they can crash the program) - */ - if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - - /* - * Check for URG data - * This will soread as well, so no need to - * test for readfds below if this succeeds - */ - if (FD_ISSET(so->s, xfds)) - sorecvoob(so); - /* - * Check sockets for reading - */ - else if (FD_ISSET(so->s, readfds)) { - /* - * Check for incoming connections - */ - if (so->so_state & SS_FACCEPTCONN) { - tcp_connect(so); - continue; - } /* else */ - ret = soread(so); - - /* Output it if we read something */ - if (ret > 0) - tcp_output(sototcpcb(so)); - } - - /* - * Check sockets for writing - */ - if (FD_ISSET(so->s, writefds)) { - /* - * Check for non-blocking, still-connecting sockets - */ - if (so->so_state & SS_ISFCONNECTING) { - /* Connected */ - so->so_state &= ~SS_ISFCONNECTING; - - //ret = send(so->s, &ret, 0, 0); - //winsock2.h:549:32: note: expected 'const char *' but argument is of type 'int *' - //WINSOCK_API_LINKAGE int PASCAL send(SOCKET,const char*,int,int); JASON - //ret = send(so->s, "a", 1, 0); WHY THE HELL WAS THIS HERE?! - ret = send(so->s, (char *)&ret, 0, 0); //This is what it should be. - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; - - /* else failed */ - so->so_state = SS_NOFDREF; - } - /* else so->so_state &= ~SS_ISFCONNECTING; */ - - /* - * Continue tcp_input - */ - tcp_input((struct SLIRPmbuf *)NULL, sizeof(struct ip), so); - /* continue; */ - } else - ret = sowrite(so); - /* - * XXXXX If we wrote something (a lot), there - * could be a need for a window update. - * In the worst case, the remote will send - * a window probe to get things going again - */ - } - - /* - * Probe a still-connecting, non-blocking socket - * to check if it's still alive - */ -#ifdef PROBE_CONN - if (so->so_state & SS_ISFCONNECTING) { - ret = recv(so->s, (char *)&ret, 0,0); - - if (ret < 0) { - /* XXX */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; /* Still connecting, continue */ - - /* else failed */ - so->so_state = SS_NOFDREF; - - /* tcp_input will take care of it */ - } else { - ret = send(so->s, (char *)&ret, 0,0); - if (ret < 0) { - /* XXX */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; - /* else failed */ - so->so_state = SS_NOFDREF; - } else - so->so_state &= ~SS_ISFCONNECTING; - - } - tcp_input((struct SLIRPmbuf *)NULL, sizeof(struct ip),so); - } /* SS_ISFCONNECTING */ -#endif - } - - /* - * Now UDP sockets. - * Incoming packets are sent straight away, they're not buffered. - * Incoming UDP data isn't buffered either. - */ - for (so = udb.so_next; so != &udb; so = so_next) { - so_next = so->so_next; - - if (so->s != -1 && FD_ISSET(so->s, readfds)) { - sorecvfrom(so); - } - } - } - - /* - * See if we can start outputting - */ - if (if_queued && link_up) - if_start(); - - /* clear global file descriptor sets. - * these reside on the stack in vl.c - * so they're unusable if we're not in - * slirp_select_fill or slirp_select_poll. - */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; -} - -#define ETH_ALEN 6 -#define ETH_HLEN 14 - -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ - -#define ARPOP_REQUEST 1 /* ARP request */ -#define ARPOP_REPLY 2 /* ARP reply */ - -struct ethhdr -{ - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -struct arphdr -{ - unsigned short ar_hrd; /* format of hardware address */ - unsigned short ar_pro; /* format of protocol address */ - unsigned char ar_hln; /* length of hardware address */ - unsigned char ar_pln; /* length of protocol address */ - unsigned short ar_op; /* ARP opcode (command) */ - - /* - * Ethernet looks like this : This bit is variable sized however... - */ - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -}; - -void arp_input(const uint8_t *pkt, int pkt_len) -{ - struct ethhdr *eh = (struct ethhdr *)pkt; - struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN); - uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)]; - struct ethhdr *reh = (struct ethhdr *)arp_reply; - struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN); - int ar_op; - struct ex_list *ex_ptr; - - ar_op = ntohs(ah->ar_op); - switch(ar_op) { - case ARPOP_REQUEST: - if (!memcmp(ah->ar_tip, &special_addr, 3)) { - if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) - goto arp_ok; - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_addr == ah->ar_tip[3]) - goto arp_ok; - } - return; - arp_ok: - /* XXX: make an ARP request to have the client address */ - memcpy(client_ethaddr, eh->h_source, ETH_ALEN); - - /* ARP request for alias/dns mac address */ - memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); - reh->h_source[5] = ah->ar_tip[3]; - reh->h_proto = htons(ETH_P_ARP); - - rah->ar_hrd = htons(1); - rah->ar_pro = htons(ETH_P_IP); - rah->ar_hln = ETH_ALEN; - rah->ar_pln = 4; - rah->ar_op = htons(ARPOP_REPLY); - memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); - memcpy(rah->ar_sip, ah->ar_tip, 4); - memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); - memcpy(rah->ar_tip, ah->ar_sip, 4); - slirp_output(arp_reply, sizeof(arp_reply)); - } - break; - default: - break; - } -} - -void slirp_input(const uint8_t *pkt, int pkt_len) -{ - struct SLIRPmbuf *m; - int proto; - - if (pkt_len < ETH_HLEN) - return; - - proto = (pkt[12] << 8) | pkt[13]; - switch(proto) { - case ETH_P_ARP: - arp_input(pkt, pkt_len); - break; - case ETH_P_IP: - m = m_get(); - if (!m) - return; - /* Note: we add to align the IP header */ - m->m_len = pkt_len + 2; - memcpy(m->m_data + 2, pkt, pkt_len); - - m->m_data += 2 + ETH_HLEN; - m->m_len -= 2 + ETH_HLEN; - - ip_input(m); - break; - default: - break; - } -} - -/* output the IP packet to the ethernet device */ -void if_encap(const uint8_t *ip_data, int ip_data_len) -{ - uint8_t buf[1600]; - struct ethhdr *eh = (struct ethhdr *)buf; - - if (ip_data_len + ETH_HLEN > sizeof(buf)) - return; - - memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); - memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1); - /* XXX: not correct */ - eh->h_source[5] = CTL_ALIAS; - eh->h_proto = htons(ETH_P_IP); - memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); - slirp_output(buf, ip_data_len + ETH_HLEN); -} - -int slirp_redir(int is_udp, int host_port, - struct in_addr guest_addr, int guest_port) -{ - if (is_udp) { - if (!udp_listen(htons(host_port), guest_addr.s_addr, - htons(guest_port), 0)) - return -1; - } else { - if (!solisten(htons(host_port), guest_addr.s_addr, - htons(guest_port), 0)) - return -1; - } - return 0; -} - -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, - int guest_port) -{ - return add_exec(&exec_list, do_pty, (char *)args, - addr_low_byte, htons(guest_port)); -} diff --git a/src - Cópia/network/slirp/slirp.h b/src - Cópia/network/slirp/slirp.h deleted file mode 100644 index b78dc93a8..000000000 --- a/src - Cópia/network/slirp/slirp.h +++ /dev/null @@ -1,441 +0,0 @@ -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#define SLIRP_VERSION "Cockatrice special" - -#define CONFIG_QEMU - -#ifndef CONFIG_QEMU -#include "version.h" -#endif -#include "config.h" -#include "slirp_config.h" - -#ifdef _WIN32 -#ifdef __GNUC__ /* MINGW? */ -# include -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; -typedef char *SLIRPcaddr_t; -typedef int socklen_t; -typedef unsigned long ioctlsockopt_t; -#else -typedef unsigned char u_int8_t; -typedef char int8_t; -typedef unsigned char uint8_t; -typedef unsigned short u_int16_t; -typedef unsigned short uint16_t; -typedef short int16_t; -typedef unsigned int u_int32_t; -typedef unsigned int uint32_t; -typedef int int32_t; - -typedef unsigned __int64 u_int64_t; -typedef char *SLIRPcaddr_t; -typedef int socklen_t; -typedef unsigned long ioctlsockopt_t; - -#endif - -# include /* needs to be on top otherwise, it'll pull in winsock1 */ -# include - -# include -# include - -# define USE_FIONBIO 1 -#ifndef EWOULDBLOCK -# define EWOULDBLOCK WSAEWOULDBLOCK -#endif -#ifndef EINPROGRESS -# define EINPROGRESS WSAEINPROGRESS -#endif -#ifndef ENOTCONN -# define ENOTCONN WSAENOTCONN -#endif -#ifndef EHOSTUNREACH -# define EHOSTUNREACH WSAEHOSTUNREACH -#endif -#ifndef ENETUNREACH -# define ENETUNREACH WSAENETUNREACH -#endif -#ifndef ECONNREFUSED -# define ECONNREFUSED WSAECONNREFUSED -#endif - -/* Basilisk II Router defines those */ -# define udp_read_completion slirp_udp_read_completion -# define write_udp slirp_write_udp -# define init_udp slirp_init_udp -# define final_udp slirp_final_udp -#else -# include -# define HAVE_STDINT_H -# define HAVE_STDLIB_H -# define HAVE_STRING_H -# define HAVE_UNISTD_H -# define HAVE_INET_ATON -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; -typedef char *SLIRPcaddr_t; -typedef int ioctlsockopt_t; -# define ioctlsocket ioctl -# define closesocket(s) close(s) -# define O_BINARY 0 -#endif - -#include -#ifdef HAVE_SYS_BITYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif - -#ifndef _MSC_VER -#include -#else -#include -#endif - -#ifdef NEED_TYPEDEFS -typedef char int8_t; -typedef unsigned char u_int8_t; - -# if SIZEOF_SHORT == 2 - typedef short int16_t; - typedef unsigned short u_int16_t; -# else -# if SIZEOF_INT == 2 - typedef int int16_t; - typedef unsigned int u_int16_t; -# else - #error Cannot find a type with sizeof() == 2 -# endif -# endif - -# if SIZEOF_SHORT == 4 - typedef short int32_t; - typedef unsigned short u_int32_t; -# else -# if SIZEOF_INT == 4 - typedef int int32_t; - typedef unsigned int u_int32_t; -# else - #error Cannot find a type with sizeof() == 4 -# endif -# endif -#endif /* NEED_TYPEDEFS */ - -/* Basilisk II types glue */ -typedef u_int8_t uint8; -typedef u_int16_t uint16; -typedef u_int32_t uint32; - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_STDLIB_H -# include -#endif - -#include -#include - -#ifndef HAVE_MEMMOVE -#define memmove(x, y, z) bcopy(y, x, z) -#endif - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#ifdef HAVE_STRING_H -# include -#else -#ifndef _MSC_VER -# include -#else -#include -#endif -#endif - -#ifndef _WIN32 -#include -#endif - -#ifndef _P -#ifndef NO_PROTOTYPES -# define _P(x) x -#else -# define _P(x) () -#endif -#endif - -#ifndef _WIN32 -#include -#include -#endif - -#ifdef GETTIMEOFDAY_ONE_ARG -#define gettimeofday(x, y) gettimeofday(x) -#endif - -/* Systems lacking strdup() definition in . */ -#if defined(ultrix) -char *strdup _P((const char *)); -#endif - -/* Systems lacking malloc() definition in . */ -#if defined(ultrix) || defined(hcx) -void *malloc _P((size_t arg)); -void free _P((void *ptr)); -#endif - -#ifndef HAVE_INET_ATON -int inet_aton _P((const char *cp, struct in_addr *ia)); -#endif - -#include -#ifndef NO_UNIX_SOCKETS -#include -#endif -#include -#ifdef HAVE_SYS_SIGNAL_H -# include -#endif -#ifndef _WIN32 -#include -#endif - -#if defined(HAVE_SYS_IOCTL_H) -# include -#endif - -#ifdef HAVE_SYS_SELECT_H -# include -#endif - -#ifdef HAVE_SYS_WAIT_H -# include -#endif - -#ifdef HAVE_SYS_FILIO_H -# include -#endif - -#ifdef USE_PPP -#include -#endif - -#ifdef __STDC__ -#include -#else -#include -#endif - -#include - -/* Avoid conflicting with the libc insque() and remque(), which - have different prototypes. */ -#define insque slirp_insque -#define remque slirp_remque - -#ifdef HAVE_SYS_STROPTS_H -#include -#endif - -#include "debug.h" - -#if defined __GNUC__ -#define PACKED__ __attribute__ ((packed)) -#elif defined __sgi -#define PRAGMA_PACK_SUPPORTED 1 -#define PACK_END 0 -#define PACKED__ -#elif _MSC_VER -#define PACKED__ -#else -#error "Packed attribute or pragma shall be supported" -#endif - -#if defined(_MSC_VER) -#pragma pack(push, 1) -#endif - -#include "ip.h" -#include "tcp.h" -#include "tcp_timer.h" -#include "tcp_var.h" -#include "tcpip.h" -#include "udp.h" -#include "icmp_var.h" -#include "mbuf.h" -#include "sbuf.h" -#include "socket.h" -#include "if.h" -#include "main.h" -#include "misc.h" -#include "ctl.h" -#ifdef USE_PPP -#include "ppp/pppd.h" -#include "ppp/ppp.h" -#endif - -#include "bootp.h" -#include "tftp.h" -#include "libslirp.h" - -extern struct ttys *ttys_unit[MAX_INTERFACES]; - -#ifndef NULL -#define NULL (void *)0 -#endif - -#ifndef FULL_BOLT -void if_start _P((void)); -#else -void if_start _P((struct ttys *)); -#endif - -#ifdef BAD_SPRINTF -# define vsprintf vsprintf_len -# define sprintf sprintf_len - extern int vsprintf_len _P((char *, const char *, va_list)); - extern int sprintf_len _P((char *, const char *, ...)); -#endif - -#ifdef DECLARE_SPRINTF -# ifndef BAD_SPRINTF - extern int vsprintf _P((char *, const char *, va_list)); -# endif - extern int vfprintf _P((FILE *, const char *, va_list)); -#endif - -#ifndef HAVE_STRERROR -#ifndef _MSC_VER - extern char *strerror _P((int error)); - #define HAVE_STRERROR -#endif -#endif - -#ifndef HAVE_INDEX - char *index _P((const char *, int)); -#endif - -#ifndef HAVE_GETHOSTID - long gethostid _P((void)); -#endif - -void lprint _P((const char *, ...)); - -extern int do_echo; - -#ifdef _MSC_VER -#define __inline -#endif - -#if SIZEOF_CHAR_P == 4 -# define insque_32 insque -# define remque_32 remque -#else -# ifdef NEED_QUE32_INLINE -extern __inline void insque_32 _P((void *, void *)); -extern __inline void remque_32 _P((void *)); -# else -extern void insque_32 _P((void *, void *)); -extern void remque_32 _P((void *)); -# endif -#endif - -#ifndef _WIN32 -#include -#endif - -#define DEFAULT_BAUD 115200 - -/* cksum.c */ -int cksum(struct SLIRPmbuf *m, int len); - -/* if.c */ -void if_init _P((void)); -void if_output _P((struct SLIRPsocket *, struct SLIRPmbuf *)); - -/* ip_input.c */ -void ip_init _P((void)); -void ip_input _P((struct SLIRPmbuf *)); -struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *)); -void ip_freef _P((struct ipq *)); -void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); -void ip_deq _P((register struct ipasfrag *)); -void ip_slowtimo _P((void)); -void ip_stripoptions _P((register struct SLIRPmbuf *, struct SLIRPmbuf *)); - -/* ip_output.c */ -int ip_output _P((struct SLIRPsocket *, struct SLIRPmbuf *)); - -/* tcp_input.c */ -int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, struct SLIRPmbuf *)); -void tcp_input _P((register struct SLIRPmbuf *, int, struct SLIRPsocket *)); -void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *)); -void tcp_xmit_timer _P((register struct tcpcb *, int)); -int tcp_mss _P((register struct tcpcb *, u_int)); - -/* tcp_output.c */ -int tcp_output _P((register struct tcpcb *)); -void tcp_setpersist _P((register struct tcpcb *)); - -/* tcp_subr.c */ -void tcp_init _P((void)); -void tcp_template _P((struct tcpcb *)); -void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct SLIRPmbuf *, tcp_seq, tcp_seq, int)); -struct tcpcb * tcp_newtcpcb _P((struct SLIRPsocket *)); -struct tcpcb * tcp_close _P((register struct tcpcb *)); -void tcp_drain _P((void)); -void tcp_sockclosed _P((struct tcpcb *)); -int tcp_fconnect _P((struct SLIRPsocket *)); -void tcp_connect _P((struct SLIRPsocket *)); -int tcp_attach _P((struct SLIRPsocket *)); -u_int8_t tcp_tos _P((struct SLIRPsocket *)); -int tcp_emu _P((struct SLIRPsocket *, struct SLIRPmbuf *)); -int tcp_ctl _P((struct SLIRPsocket *)); -struct tcpcb *tcp_drop(struct tcpcb *tp, int err); - - -#if defined(_MSC_VER) -#pragma pack(pop) -#endif - -#ifdef USE_PPP -#define MIN_MRU MINMRU -#define MAX_MRU MAXMRU -#else -#define MIN_MRU 128 -#define MAX_MRU 16384 -#endif - -#ifndef _WIN32 -#define min(x,y) ((x) < (y) ? (x) : (y)) -#define max(x,y) ((x) > (y) ? (x) : (y)) -#endif - -#ifdef _WIN32 -#undef errno -#define errno (WSAGetLastError()) -#endif - -#define PROBE_CONN - -#endif diff --git a/src - Cópia/network/slirp/slirp_config.h b/src - Cópia/network/slirp/slirp_config.h deleted file mode 100644 index e583dcc80..000000000 --- a/src - Cópia/network/slirp/slirp_config.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * User definable configuration options - */ - -/* Undefine if you don't want talk emulation */ -#undef EMULATE_TALK - -/* Define if you want the connection to be probed */ -/* XXX Not working yet, so ignore this for now */ -#undef PROBE_CONN - -/* Define to 1 if you want KEEPALIVE timers */ -#define DO_KEEPALIVE 0 - -/* Define to MAX interfaces you expect to use at once */ -/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */ -/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */ -#define MAX_INTERFACES 1 -#define MAX_PPP_INTERFACES 1 - -/* Define if you want slirp's socket in /tmp */ -/* XXXXXX Do this in ./configure */ -#undef USE_TMPSOCKET - -/* Define if you want slirp to use cfsetXspeed() on the terminal */ -#undef DO_CFSETSPEED - -/* Define this if you want slirp to write to the tty as fast as it can */ -/* This should only be set if you are using load-balancing, slirp does a */ -/* pretty good job on single modems already, and seting this will make */ -/* interactive sessions less responsive */ -/* XXXXX Talk about having fast modem as unit 0 */ -#undef FULL_BOLT - -/* - * Define if you want slirp to use less CPU - * You will notice a small lag in interactive sessions, but it's not that bad - * Things like Netscape/ftp/etc. are completely unaffected - * This is mainly for sysadmins who have many slirp users - */ -#undef USE_LOWCPU - -/* Define this if your compiler doesn't like prototypes */ -#ifndef __STDC__ -#define NO_PROTOTYPES -#endif - -/*********************************************************/ -/* - * Autoconf defined configuration options - * You shouldn't need to touch any of these - */ - -/* Ignore this */ -#undef DUMMY_PPP - -/* XXX: Define according to how time.h should be included */ -#undef TIME_WITH_SYS_TIME -#define TIME_WITH_SYS_TIME 0 -#undef HAVE_SYS_TIME_H - -/* Define if your sprintf returns char * instead of int */ -#undef BAD_SPRINTF - -/* Define if you have readv */ -#undef HAVE_READV - -/* Define if iovec needs to be declared */ -#undef DECLARE_IOVEC -#ifdef _WIN32 -#define DECLARE_IOVEC -#endif - -/* Define if a declaration of sprintf/fprintf is needed */ -#undef DECLARE_SPRINTF - -/* Define if you have sys/stropts.h */ -#undef HAVE_SYS_STROPTS_H - -/* Define if your compiler doesn't like prototypes */ -#undef NO_PROTOTYPES - -/* Define if you don't have u_int32_t etc. typedef'd */ -#undef NEED_TYPEDEFS -#ifdef __sun__ -#define NEED_TYPEDEFS -#endif - -/* Define to sizeof(char *) */ -#define SIZEOF_CHAR_P SIZEOF_VOID_P - -/* Define if you have random() */ -#undef HAVE_RANDOM - -/* Define if you have srandom() */ -#undef HAVE_SRANDOM - -/* Define if you have setenv */ -#undef HAVE_SETENV - -/* Define if you have index() */ -#undef HAVE_INDEX - -/* Define if you have bcmp() */ -#undef HAVE_BCMP - -/* Define if you have drand48 */ -#undef HAVE_DRAND48 - -/* Define if you have memmove */ -#define HAVE_MEMMOVE - -/* Define if you have gethostid */ -#undef HAVE_GETHOSTID - -/* Define if you DON'T have unix-domain sockets */ -#undef NO_UNIX_SOCKETS -#ifdef _WIN32 -#define NO_UNIX_SOCKETS -#endif - -/* Define if gettimeofday only takes one argument */ -#undef GETTIMEOFDAY_ONE_ARG - -/* Define if you have revoke() */ -#undef HAVE_REVOKE - -/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */ -#undef HAVE_GRANTPT - -/* Define if you have fchmod */ -#undef HAVE_FCHMOD - -/* Define if you have */ -#undef HAVE_SYS_TYPES32_H diff --git a/src - Cópia/network/slirp/socket.c b/src - Cópia/network/slirp/socket.c deleted file mode 100644 index a930c502d..000000000 --- a/src - Cópia/network/slirp/socket.c +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#ifndef _WIN32 -# include -#endif -#include "slirp.h" -#include "ip_icmp.h" -#include "main.h" -#ifdef __sun__ -#include -#endif - -#ifndef FIONREAD -#include -#endif - -void -so_init() -{ - /* Nothing yet */ -} - - -struct SLIRPsocket * -solookup(head, laddr, lport, faddr, fport) - struct SLIRPsocket *head; - struct in_addr laddr; - u_int lport; - struct in_addr faddr; - u_int fport; -{ - struct SLIRPsocket *so; - - for (so = head->so_next; so != head; so = so->so_next) { - if (so->so_lport == lport && - so->so_laddr.s_addr == laddr.s_addr && - so->so_faddr.s_addr == faddr.s_addr && - so->so_fport == fport) - break; - } - - if (so == head) - return (struct SLIRPsocket *)NULL; - return so; - -} - -/* - * Create a new socket, initialise the fields - * It is the responsibility of the caller to - * insque() it into the correct linked-list - */ -struct SLIRPsocket * -socreate() -{ - struct SLIRPsocket *so; - - so = (struct SLIRPsocket *)malloc(sizeof(struct SLIRPsocket)); - if(so) { - memset(so, 0, sizeof(struct SLIRPsocket)); - so->so_state = SS_NOFDREF; - so->s = -1; - } - return(so); -} - -/* - * remque and free a socket, clobber cache - */ -void -sofree(so) - struct SLIRPsocket *so; -{ - if (so->so_emu==EMU_RSH && so->extra) { - sofree(so->extra); - so->extra=NULL; - } - if (so == tcp_last_so) - tcp_last_so = &tcb; - else if (so == udp_last_so) - udp_last_so = &udb; - - if(so->so_m!=NULL) - m_free(so->so_m); - - if(so->so_next && so->so_prev) - remque(so); /* crashes if so is not in a queue */ - - free(so); -} - -/* - * Read from so's socket into sb_snd, updating all relevant sbuf fields - * NOTE: This will only be called if it is select()ed for reading, so - * a read() of 0 (or less) means it's disconnected - */ -int -soread(so) - struct SLIRPsocket *so; -{ - int n, nn, lss, total; - struct sbuf *sb = &so->so_snd; - int len = sb->sb_datalen - sb->sb_cc; - struct iovec iov[2]; - int mss; - if(!so->so_tcpcb) - return 0; - - mss = so->so_tcpcb->t_maxseg; - - DEBUG_CALL("soread"); - DEBUG_ARG("so = %lx", (long )so); - - /* - * No need to check if there's enough room to read. - * soread wouldn't have been called if there weren't - */ - - len = sb->sb_datalen - sb->sb_cc; - - iov[0].iov_base = sb->sb_wptr; - if (sb->sb_wptr < sb->sb_rptr) { - iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) - iov[0].iov_len = len; - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len%mss; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_rptr - sb->sb_data; - if(iov[1].iov_len > len) - iov[1].iov_len = len; - total = iov[0].iov_len + iov[1].iov_len; - if (total > mss) { - lss = total%mss; - if (iov[1].iov_len > lss) { - iov[1].iov_len -= lss; - n = 2; - } else { - lss -= iov[1].iov_len; - iov[0].iov_len -= lss; - n = 1; - } - } else - n = 2; - } else { - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len%mss; - n = 1; - } - } - -#ifdef HAVE_READV - nn = readv(so->s, (struct iovec *)iov, n); - DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); -#else - nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); -#endif - if (nn <= 0) { - if (nn < 0 && (errno == EINTR || errno == EAGAIN)) - return 0; - else { - DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); - sofcantrcvmore(so); - tcp_sockclosed(sototcpcb(so)); - return -1; - } - } - -#ifndef HAVE_READV - /* - * If there was no error, try and read the second time round - * We read again if n = 2 (ie, there's another part of the buffer) - * and we read as much as we could in the first read - * We don't test for <= 0 this time, because there legitimately - * might not be any more data (since the socket is non-blocking), - * a close will be detected on next iteration. - * A return of -1 wont (shouldn't) happen, since it didn't happen above - */ - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0); - if (ret > 0) - nn += ret; - } - - DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); -#endif - - /* Update fields */ - sb->sb_cc += nn; - sb->sb_wptr += nn; - if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_wptr -= sb->sb_datalen; - return nn; -} - -/* - * Get urgent data - * - * When the socket is created, we set it SO_OOBINLINE, - * so when OOB data arrives, we soread() it and everything - * in the send buffer is sent as urgent data - */ -void -sorecvoob(so) - struct SLIRPsocket *so; -{ - struct tcpcb *tp = sototcpcb(so); - - DEBUG_CALL("sorecvoob"); - DEBUG_ARG("so = %lx", (long)so); - - /* - * We take a guess at how much urgent data has arrived. - * In most situations, when urgent data arrives, the next - * read() should get all the urgent data. This guess will - * be wrong however if more data arrives just after the - * urgent data, or the read() doesn't return all the - * urgent data. - */ - soread(so); - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_force = 1; - tcp_output(tp); - tp->t_force = 0; -} - -/* - * Send urgent data - * There's a lot duplicated code here, but... - */ -int -sosendoob(so) - struct SLIRPsocket *so; -{ - struct sbuf *sb = &so->so_rcv; - char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ - - int n, len; - - DEBUG_CALL("sosendoob"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); - - if (so->so_urgc > 2048) - so->so_urgc = 2048; /* XXXX */ - - if (sb->sb_rptr < sb->sb_wptr) { - /* We can send it directly */ - n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */ - so->so_urgc -= n; - - DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); - } else { - /* - * Since there's no sendv or sendtov like writev, - * we must copy all data to a linear buffer then - * send it all - */ - len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (len > so->so_urgc) len = so->so_urgc; - memcpy(buff, sb->sb_rptr, len); - so->so_urgc -= len; - if (so->so_urgc) { - n = sb->sb_wptr - sb->sb_data; - if (n > so->so_urgc) n = so->so_urgc; - memcpy((buff + len), sb->sb_data, n); - so->so_urgc -= n; - len += n; - } - n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */ -#ifdef SLIRP_DEBUG - if (n != len) - DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n")); -#endif - DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); - } - - sb->sb_cc -= n; - sb->sb_rptr += n; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - return n; -} - -/* - * Write data from so_rcv to so's socket, - * updating all sbuf field as necessary - */ -int -sowrite(so) - struct SLIRPsocket *so; -{ - int n,nn; - struct sbuf *sb = &so->so_rcv; - int len = sb->sb_cc; - struct iovec iov[2]; - - DEBUG_CALL("sowrite"); - DEBUG_ARG("so = %lx", (long)so); - - if (so->so_urgc) { - sosendoob(so); - if (sb->sb_cc == 0) - return 0; - } - - /* - * No need to check if there's something to write, - * sowrite wouldn't have been called otherwise - */ - - len = sb->sb_cc; - - iov[0].iov_base = sb->sb_rptr; - if (sb->sb_rptr < sb->sb_wptr) { - iov[0].iov_len = sb->sb_wptr - sb->sb_rptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) iov[0].iov_len = len; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (iov[0].iov_len > len) iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_wptr - sb->sb_data; - if (iov[1].iov_len > len) iov[1].iov_len = len; - n = 2; - } else - n = 1; - } - /* Check if there's urgent data to send, and if so, send it */ - -#ifdef HAVE_READV - nn = writev(so->s, (const struct iovec *)iov, n); - - DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); -#else - nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); -#endif - /* This should never happen, but people tell me it does *shrug* */ - if (nn < 0 && (errno == EAGAIN || errno == EINTR)) - return 0; - - if (nn <= 0) { - DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", - so->so_state, errno)); - sofcantsendmore(so); - tcp_sockclosed(sototcpcb(so)); - return -1; - } - -#ifndef HAVE_READV - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0); - if (ret > 0) - nn += ret; - } - DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); -#endif - - /* Update sbuf */ - sb->sb_cc -= nn; - sb->sb_rptr += nn; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - /* - * If in DRAIN mode, and there's no more data, set - * it CANTSENDMORE - */ - if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) - sofcantsendmore(so); - - return nn; -} - -/* - * recvfrom() a UDP socket - */ -void -sorecvfrom(so) - struct SLIRPsocket *so; -{ - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - - DEBUG_CALL("sorecvfrom"); - DEBUG_ARG("so = %lx", (long)so); - - if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ - char buff[256]; - int len; - - len = recvfrom(so->s, buff, 256, 0, - (struct sockaddr *)&addr, &addrlen); - /* XXX Check if reply is "correct"? */ - - if(len == -1 || len == 0) { - u_char code=ICMP_UNREACH_PORT; - - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; - - DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", - errno,strerror(errno))); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); - } else { - icmp_reflect(so->so_m); - so->so_m = 0; /* Don't m_free() it again! */ - } - /* No need for this socket anymore, udp_detach it */ - udp_detach(so); - } else { /* A "normal" UDP packet */ - struct SLIRPmbuf *m; - int len; - ioctlsockopt_t n; - - if (!(m = m_get())) return; - m->m_data += if_maxlinkhdr; - - /* - * XXX Shouldn't FIONREAD packets destined for port 53, - * but I don't know the max packet size for DNS lookups - */ - len = M_FREEROOM(m); - /* if (so->so_fport != htons(53)) { */ - ioctlsocket(so->s, FIONREAD, &n); - - if (n > len) { - n = (m->m_data - m->m_dat) + m->m_len + n + 1; - m_inc(m, n); - len = M_FREEROOM(m); - } - /* } */ - - m->m_len = recvfrom(so->s, m->m_data, len, 0, - (struct sockaddr *)&addr, &addrlen); - DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", - m->m_len, errno,strerror(errno))); - if(m->m_len<0) { - u_char code=ICMP_UNREACH_PORT; - - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; - - DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); - m_free(m); - } else { - /* - * Hack: domain name lookup will be used the most for UDP, - * and since they'll only be used once there's no need - * for the 4 minute (or whatever) timeout... So we time them - * out much quicker (10 seconds for now...) - */ - if (so->so_expire) { - if (so->so_fport == htons(53)) - so->so_expire = curtime + SO_EXPIREFAST; - else - so->so_expire = curtime + SO_EXPIRE; - } - - /* if (m->m_len == len) { - * m_inc(m, MINCSIZE); - * m->m_len = 0; - * } - */ - - /* - * If this packet was destined for CTL_ADDR, - * make it look like that's where it came from, done by udp_output - */ - udp_output(so, m, &addr); - } /* rx error */ - } /* if ping packet */ -} - -/* - * sendto() a socket - */ -int -sosendto(so, m) - struct SLIRPsocket *so; - struct SLIRPmbuf *m; -{ - int ret; - struct sockaddr_in addr; - - DEBUG_CALL("sosendto"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else - addr.sin_addr = so->so_faddr; - addr.sin_port = so->so_fport; - - DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); - - /* Don't care what port we get */ - ret = sendto(so->s, m->m_data, m->m_len, 0, - (struct sockaddr *)&addr, sizeof (struct sockaddr)); - if (ret < 0) - return -1; - - /* - * Kill the socket if there's no reply in 4 minutes, - * but only if it's an expirable socket - */ - if (so->so_expire) - so->so_expire = curtime + SO_EXPIRE; - so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */ - return 0; -} - -/* - * XXX This should really be tcp_listen - */ -struct SLIRPsocket * -solisten(port, laddr, lport, flags) - u_int port; - u_int32_t laddr; - u_int lport; - int flags; -{ - struct sockaddr_in addr; - struct SLIRPsocket *so; - int s; - socklen_t addrlen = sizeof(addr); - int opt = 1; - - DEBUG_CALL("solisten"); - DEBUG_ARG("port = %d", port); - DEBUG_ARG("laddr = %x", laddr); - DEBUG_ARG("lport = %d", lport); - DEBUG_ARG("flags = %x", flags); - - if ((so = socreate()) == NULL) { - /* free(so); Not sofree() ??? free(NULL) == NOP */ - return NULL; - } - - /* Don't tcp_attach... we don't need so_snd nor so_rcv */ - if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { - free(so); - return NULL; - } - insque(so,&tcb); - - /* - * SS_FACCEPTONCE sockets must time out. - */ - if (flags & SS_FACCEPTONCE) - so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; - - so->so_state = (SS_FACCEPTCONN|flags); - so->so_lport = lport; /* Kept in network format */ - so->so_laddr.s_addr = laddr; /* Ditto */ - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; - - if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || - (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || - (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || - (listen(s,1) < 0)) { - int tmperrno = errno; /* Don't clobber the real reason we failed */ - - close(s); - sofree(so); - /* Restore the real errno */ -#ifdef _WIN32 - WSASetLastError(tmperrno); -#else - errno = tmperrno; -#endif - return NULL; - } - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - - getsockname(s,(struct sockaddr *)&addr,&addrlen); - so->so_fport = addr.sin_port; - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - else - so->so_faddr = addr.sin_addr; - - so->s = s; - return so; -} - -/* - * Data is available in so_rcv - * Just write() the data to the socket - * XXX not yet... - */ -void -sorwakeup(so) - struct SLIRPsocket *so; -{ -/* sowrite(so); */ -/* FD_CLR(so->s,&writefds); */ -} - -/* - * Data has been freed in so_snd - * We have room for a read() if we want to - * For now, don't read, it'll be done in the main loop - */ -void -sowwakeup(so) - struct SLIRPsocket *so; -{ - /* Nothing, yet */ -} - -/* - * Various session state calls - * XXX Should be #define's - * The socket state stuff needs work, these often get call 2 or 3 - * times each when only 1 was needed - */ -void -soisfconnecting(so) - register struct SLIRPsocket *so; -{ - so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE| - SS_FCANTSENDMORE|SS_FWDRAIN); - so->so_state |= SS_ISFCONNECTING; /* Clobber other states */ -} - -void -soisfconnected(so) - register struct SLIRPsocket *so; -{ - so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF); - so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ -} - -void -sofcantrcvmore(so) - struct SLIRPsocket *so; -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s,0); - if(global_writefds) { - FD_CLR(so->s,global_writefds); - } - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTSENDMORE) - so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */ - else - so->so_state |= SS_FCANTRCVMORE; -} - -void -sofcantsendmore(so) - struct SLIRPsocket *so; -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s,1); /* send FIN to fhost */ - if (global_readfds) { - FD_CLR(so->s,global_readfds); - } - if (global_xfds) { - FD_CLR(so->s,global_xfds); - } - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTRCVMORE) - so->so_state = SS_NOFDREF; /* as above */ - else - so->so_state |= SS_FCANTSENDMORE; -} - -void -soisfdisconnected(so) - struct SLIRPsocket *so; -{ -/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */ -/* close(so->s); */ -/* so->so_state = SS_ISFDISCONNECTED; */ - /* - * XXX Do nothing ... ? - */ -} - -/* - * Set write drain mode - * Set CANTSENDMORE once all data has been write()n - */ -void -sofwdrain(so) - struct SLIRPsocket *so; -{ - if (so->so_rcv.sb_cc) - so->so_state |= SS_FWDRAIN; - else - sofcantsendmore(so); -} - diff --git a/src - Cópia/network/slirp/socket.h b/src - Cópia/network/slirp/socket.h deleted file mode 100644 index 3a777934a..000000000 --- a/src - Cópia/network/slirp/socket.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -/* MINE */ - -#ifndef _SLIRP_SOCKET_H_ -#define _SLIRP_SOCKET_H_ - -#define SO_EXPIRE 240000 -#define SO_EXPIREFAST 10000 - -/* - * Our socket structure - */ - -struct SLIRPsocket { - struct SLIRPsocket *so_next,*so_prev; /* For a linked list of sockets */ - - int s; /* The actual socket */ - - /* XXX union these with not-yet-used sbuf params */ - struct SLIRPmbuf *so_m; /* Pointer to the original SYN packet, - * for non-blocking connect()'s, and - * PING reply's */ - struct tcpiphdr *so_ti; /* Pointer to the original ti within - * so_mconn, for non-blocking connections */ - int so_urgc; - struct in_addr so_faddr; /* foreign host table entry */ - struct in_addr so_laddr; /* local host table entry */ - u_int16_t so_fport; /* foreign port */ - u_int16_t so_lport; /* local port */ - - u_int8_t so_iptos; /* Type of service */ - u_int8_t so_emu; /* Is the socket emulated? */ - - u_char so_type; /* Type of socket, UDP or TCP */ - int so_state; /* internal state flags SS_*, below */ - - struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ - u_int so_expire; /* When the socket will expire */ - - int so_queued; /* Number of packets queued from this socket */ - int so_nqueued; /* Number of packets queued in a row - * Used to determine when to "downgrade" a session - * from fastq to batchq */ - - struct sbuf so_rcv; /* Receive buffer */ - struct sbuf so_snd; /* Send buffer */ - void * extra; /* Extra pointer */ -}; - - -/* - * Socket state bits. (peer means the host on the Internet, - * local host means the host on the other end of the modem) - */ -#define SS_NOFDREF 0x001 /* No fd reference */ - -#define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */ -#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */ -#define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */ -#define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */ -/* #define SS_ISFDISCONNECTED 0x020*/ /* Socket has disconnected from peer, in 2MSL state */ -#define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ - -#define SS_CTL 0x080 -#define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ -#define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ - -extern struct SLIRPsocket tcb; - - -#if defined(DECLARE_IOVEC) && !defined(HAVE_READV) -struct iovec { - char *iov_base; - size_t iov_len; -}; -#endif - -void so_init _P((void)); -struct SLIRPsocket * solookup _P((struct SLIRPsocket *, struct in_addr, u_int, struct in_addr, u_int)); -struct SLIRPsocket * socreate _P((void)); -void sofree _P((struct SLIRPsocket *)); -int soread _P((struct SLIRPsocket *)); -void sorecvoob _P((struct SLIRPsocket *)); -int sosendoob _P((struct SLIRPsocket *)); -int sowrite _P((struct SLIRPsocket *)); -void sorecvfrom _P((struct SLIRPsocket *)); -int sosendto _P((struct SLIRPsocket *, struct SLIRPmbuf *)); -struct SLIRPsocket * solisten _P((u_int, u_int32_t, u_int, int)); -void sorwakeup _P((struct SLIRPsocket *)); -void sowwakeup _P((struct SLIRPsocket *)); -void soisfconnecting _P((register struct SLIRPsocket *)); -void soisfconnected _P((register struct SLIRPsocket *)); -void sofcantrcvmore _P((struct SLIRPsocket *)); -void sofcantsendmore _P((struct SLIRPsocket *)); -void soisfdisconnected _P((struct SLIRPsocket *)); -void sofwdrain _P((struct SLIRPsocket *)); - -#endif /* _SOCKET_H_ */ diff --git a/src - Cópia/network/slirp/tcp.h b/src - Cópia/network/slirp/tcp.h deleted file mode 100644 index d9a8ccf72..000000000 --- a/src - Cópia/network/slirp/tcp.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp.h 8.1 (Berkeley) 6/10/93 - * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp - */ - -#ifndef _TCP_H_ -#define _TCP_H_ - -#ifdef __amd64__ -typedef uintptr_t tcp_seq; -#else -typedef u_int32_t tcp_seq; -#endif - -#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ -#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ - -extern int tcp_rcvspace; -extern int tcp_sndspace; -extern struct SLIRPsocket *tcp_last_so; - -#define TCP_SNDSPACE 8192 -#define TCP_RCVSPACE 8192 - -/* - * TCP header. - * Per RFC 793, September, 1981. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct tcphdr { - u_int16_t th_sport; /* source port */ - u_int16_t th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ -#ifdef WORDS_BIGENDIAN - u_char th_off:4, /* data offset */ - th_x2:4; /* (unused) */ -#else - u_char th_x2:4, /* (unused) */ - th_off:4; /* data offset */ -#endif - u_int8_t th_flags; -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 - u_int16_t th_win; /* window */ - u_int16_t th_sum; /* checksum */ - u_int16_t th_urp; /* urgent pointer */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -#include "tcp_var.h" - -#define TCPOPT_EOL 0 -#define TCPOPT_NOP 1 -#define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 -#define TCPOPT_WINDOW 3 -#define TCPOLEN_WINDOW 3 -#define TCPOPT_SACK_PERMITTED 4 /* Experimental */ -#define TCPOLEN_SACK_PERMITTED 2 -#define TCPOPT_SACK 5 /* Experimental */ -#define TCPOPT_TIMESTAMP 8 -#define TCPOLEN_TIMESTAMP 10 -#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ - -#define TCPOPT_TSTAMP_HDR \ - (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) - -/* - * Default maximum segment size for TCP. - * With an IP MSS of 576, this is 536, - * but 512 is probably more convenient. - * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). - * - * We make this 1460 because we only care about Ethernet in the qemu context. - */ -#define TCP_MSS 1460 - -#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ - -#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ - -/* - * User-settable options (used with setsockopt). - * - * We don't use the system headers on unix because we have conflicting - * local structures. We can't avoid the system definitions on Windows, - * so we undefine them. - */ -#undef TCP_NODELAY -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#undef TCP_MAXSEG -/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */ - -/* - * TCP FSM state definitions. - * Per RFC793, September, 1981. - */ - -#define TCP_NSTATES 11 - -#define TCPS_CLOSED 0 /* closed */ -#define TCPS_LISTEN 1 /* listening for connection */ -#define TCPS_SYN_SENT 2 /* active, have sent syn */ -#define TCPS_SYN_RECEIVED 3 /* have send and received syn */ -/* states < TCPS_ESTABLISHED are those where connections not established */ -#define TCPS_ESTABLISHED 4 /* established */ -#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ -/* states > TCPS_CLOSE_WAIT are those where user has closed */ -#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ -#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ -#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ -/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ -#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ -#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ - -#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) -#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) -#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) - -/* - * TCP sequence numbers are 32 bit integers operated - * on with modular arithmetic. These macros can be - * used to compare such integers. - */ -#define SEQ_LT(a,b) ((int)((a)-(b)) < 0) -#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) -#define SEQ_GT(a,b) ((int)((a)-(b)) > 0) -#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) - -/* - * Macros to initialize tcp sequence numbers for - * send and receive from initial send and receive - * sequence numbers. - */ -#define tcp_rcvseqinit(tp) \ - (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1 - -#define tcp_sendseqinit(tp) \ - (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss - -#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */ - -extern tcp_seq tcp_iss; /* tcp initial send seq # */ - -extern char *tcpstates[]; - -#endif diff --git a/src - Cópia/network/slirp/tcp_input.c b/src - Cópia/network/slirp/tcp_input.c deleted file mode 100644 index 97187788d..000000000 --- a/src - Cópia/network/slirp/tcp_input.c +++ /dev/null @@ -1,1721 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 - * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ -#include -#include "slirp.h" -#include "ip_icmp.h" - -struct SLIRPsocket tcb; - -int tcprexmtthresh = 3; -struct SLIRPsocket *tcp_last_so = &tcb; - -tcp_seq tcp_iss; /* tcp initial send seq # */ - -#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) - -/* for modulo comparisons of timestamps */ -#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) -#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) - -/* - * Insert segment ti into reassembly queue of tcp with - * control block tp. Return TH_FIN if reassembly now includes - * a segment with FIN. The macro form does the common case inline - * (segment is the next to be received on an established connection, - * and the queue is empty), avoiding linkage into and removal - * from the queue and repetition of various conversions. - * Set DELACK for segments received in order, but ack immediately - * when segments are out of order (so fast retransmit can work). - */ -#ifdef TCP_ACK_HACK -#define TCP_REASS(tp, ti, m, so, flags) {\ - if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ - (tp)->t_state == TCPS_ESTABLISHED) {\ - if (ti->ti_flags & TH_PUSH) \ - tp->t_flags |= TF_ACKNOW; \ - else \ - tp->t_flags |= TF_DELACK; \ - (tp)->rcv_nxt += (ti)->ti_len; \ - flags = (ti)->ti_flags & TH_FIN; \ - tcpstat.tcps_rcvpack++;\ - tcpstat.tcps_rcvbyte += (ti)->ti_len;\ - if (so->so_emu) { \ - if (tcp_emu((so),(m))) sbappend((so), (m)); \ - } else \ - sbappend((so), (m)); \ -/* sorwakeup(so); */ \ - } else {\ - (flags) = tcp_reass((tp), (ti), (m)); \ - tp->t_flags |= TF_ACKNOW; \ - } \ -} -#else -#define TCP_REASS(tp, ti, m, so, flags) { \ - if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ - (tp)->t_state == TCPS_ESTABLISHED) { \ - tp->t_flags |= TF_DELACK; \ - (tp)->rcv_nxt += (ti)->ti_len; \ - flags = (ti)->ti_flags & TH_FIN; \ - tcpstat.tcps_rcvpack++;\ - tcpstat.tcps_rcvbyte += (ti)->ti_len;\ - if (so->so_emu) { \ - if (tcp_emu((so),(m))) sbappend(so, (m)); \ - } else \ - sbappend((so), (m)); \ -/* sorwakeup(so); */ \ - } else { \ - (flags) = tcp_reass((tp), (ti), (m)); \ - tp->t_flags |= TF_ACKNOW; \ - } \ -} -#endif - -int -tcp_reass(tp, ti, m) - struct tcpcb *tp; - struct tcpiphdr *ti; - struct SLIRPmbuf *m; -{ - struct tcpiphdr *q; - struct SLIRPsocket *so = tp->t_socket; - int flags; - - /* - * Call with ti==0 after become established to - * force pre-ESTABLISHED data up to user socket. - */ - if (ti == 0) - goto present; - - /* - * Find a segment which begins after this one does. - */ - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) - if (SEQ_GT(q->ti_seq, ti->ti_seq)) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { - int i; - q = (struct tcpiphdr *)q->ti_prev; - /* conversion to int (in i) handles seq wraparound */ - i = q->ti_seq + q->ti_len - ti->ti_seq; - if (i > 0) { - if (i >= ti->ti_len) { - tcpstat.tcps_rcvduppack++; - tcpstat.tcps_rcvdupbyte += ti->ti_len; - m_freem(m); - /* - * Try to present any queued data - * at the left window edge to the user. - * This is needed after the 3-WHS - * completes. - */ - goto present; /* ??? */ - } - m_adj(m, i); - ti->ti_len -= i; - ti->ti_seq += i; - } - q = (struct tcpiphdr *)(q->ti_next); - } - tcpstat.tcps_rcvoopack++; - tcpstat.tcps_rcvoobyte += ti->ti_len; - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (q != (struct tcpiphdr *)tp) { - int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; - if (i <= 0) - break; - if (i < q->ti_len) { - q->ti_seq += i; - q->ti_len -= i; - m_adj((struct SLIRPmbuf *) REASS_MBUF(q), i); - break; - } - q = (struct tcpiphdr *)q->ti_next; - m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev); - remque_32((void *)(q->ti_prev)); - m_freem(m); - } - - /* - * Stick new segment in its place. - */ - insque_32(ti, (void *)(q->ti_prev)); - -present: - /* - * Present data to user, advancing rcv_nxt through - * completed sequence space. - */ - if (!TCPS_HAVEESTABLISHED(tp->t_state)) - return (0); - ti = (struct tcpiphdr *) tp->seg_next; - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) - return (0); - if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) - return (0); - do { - tp->rcv_nxt += ti->ti_len; - flags = ti->ti_flags & TH_FIN; - remque_32(ti); - m = (struct SLIRPmbuf *) REASS_MBUF(ti); /* XXX */ - ti = (struct tcpiphdr *)ti->ti_next; -/* if (so->so_state & SS_FCANTRCVMORE) */ - if (so->so_state & SS_FCANTSENDMORE) - m_freem(m); - else { - if (so->so_emu) { - if (tcp_emu(so,m)) sbappend(so, m); - } else - sbappend(so, m); - } - } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); -/* sorwakeup(so); */ - return (flags); -} - -/* - * TCP input routine, follows pages 65-76 of the - * protocol specification dated September, 1981 very closely. - */ -void -tcp_input(m, iphlen, inso) - struct SLIRPmbuf *m; - int iphlen; - struct SLIRPsocket *inso; -{ - struct ip save_ip, *ip; - struct tcpiphdr *ti; - SLIRPcaddr_t optp = NULL; - int optlen = 0; - int len, tlen, off; - struct tcpcb *tp = 0; - int tiflags; - struct SLIRPsocket *so = 0; - int todrop, acked, ourfinisacked, needoutput = 0; -/* int dropsocket = 0; */ - int iss = 0; - u_long tiwin; - int ret; -/* int ts_present = 0; */ - - DEBUG_CALL("tcp_input"); - DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", - (long )m, iphlen, (long )inso )); - - /* - * If called with m == 0, then we're continuing the connect - */ - if (m == NULL) { - so = inso; - - /* Re-set a few variables */ - tp = sototcpcb(so); - m = so->so_m; - so->so_m = 0; - ti = so->so_ti; - tiwin = ti->ti_win; - tiflags = ti->ti_flags; - - goto cont_conn; - } - - - tcpstat.tcps_rcvtotal++; - /* - * Get IP and TCP header together in first SLIRPmbuf. - * Note: IP leaves IP header in first SLIRPmbuf. - */ - ti = mtod(m, struct tcpiphdr *); - if (iphlen > sizeof(struct ip )) { - ip_stripoptions(m, (struct SLIRPmbuf *)0); - iphlen=sizeof(struct ip ); - } - /* XXX Check if too short */ - - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - ip=mtod(m, struct ip *); - save_ip = *ip; - save_ip.ip_len+= iphlen; - - /* - * Checksum extended TCP header and data. - */ - tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; - ti->ti_x1 = 0; - ti->ti_len = htons((u_int16_t)tlen); - len = sizeof(struct ip ) + tlen; - /* keep checksum for ICMP reply - * ti->ti_sum = cksum(m, len); - * if (ti->ti_sum) { */ - if(cksum(m, len)) { - tcpstat.tcps_rcvbadsum++; - goto drop; - } - - /* - * Check that TCP offset makes sense, - * pull out TCP options and adjust length. XXX - */ - off = ti->ti_off << 2; - if (off < sizeof (struct tcphdr) || off > tlen) { - tcpstat.tcps_rcvbadoff++; - goto drop; - } - tlen -= off; - ti->ti_len = tlen; - if (off > sizeof (struct tcphdr)) { - optlen = off - sizeof (struct tcphdr); - optp = mtod(m, SLIRPcaddr_t) + sizeof (struct tcpiphdr); - - /* - * Do quick retrieval of timestamp options ("options - * prediction?"). If timestamp is the only option and it's - * formatted as recommended in RFC 1323 appendix A, we - * quickly get the values now and not bother calling - * tcp_dooptions(), etc. - */ -/* if ((optlen == TCPOLEN_TSTAMP_APPA || - * (optlen > TCPOLEN_TSTAMP_APPA && - * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && - * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && - * (ti->ti_flags & TH_SYN) == 0) { - * ts_present = 1; - * ts_val = ntohl(*(u_int32_t *)(optp + 4)); - * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); - * optp = NULL; / * we've parsed the options * / - * } - */ - } - tiflags = ti->ti_flags; - - /* - * Convert TCP protocol specific fields to host format. - */ - NTOHL(ti->ti_seq); - NTOHL(ti->ti_ack); - NTOHS(ti->ti_win); - NTOHS(ti->ti_urp); - - /* - * Drop TCP, IP headers and TCP options. - */ - m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - - /* - * Locate pcb for segment. - */ -findso: - so = tcp_last_so; - if (so->so_fport != ti->ti_dport || - so->so_lport != ti->ti_sport || - so->so_laddr.s_addr != ti->ti_src.s_addr || - so->so_faddr.s_addr != ti->ti_dst.s_addr) { - so = solookup(&tcb, ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); - if (so) - tcp_last_so = so; - ++tcpstat.tcps_socachemiss; - } - - /* - * If the state is CLOSED (i.e., TCB does not exist) then - * all data in the incoming segment is discarded. - * If the TCB exists but is in CLOSED state, it is embryonic, - * but should either do a listen or a connect soon. - * - * state == CLOSED means we've done socreate() but haven't - * attached it to a protocol yet... - * - * XXX If a TCB does not exist, and the TH_SYN flag is - * the only flag set, then create a session, mark it - * as if it was LISTENING, and continue... - */ - if (so == 0) { - if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) - goto dropwithreset; - - if ((so = socreate()) == NULL) - goto dropwithreset; - if (tcp_attach(so) < 0) { - free(so); /* Not sofree (if it failed, it's not insqued) */ - goto dropwithreset; - } - - sbreserve(&so->so_snd, tcp_sndspace); - sbreserve(&so->so_rcv, tcp_rcvspace); - - /* tcp_last_so = so; */ /* XXX ? */ - /* tp = sototcpcb(so); */ - - so->so_laddr = ti->ti_src; - so->so_lport = ti->ti_sport; - so->so_faddr = ti->ti_dst; - so->so_fport = ti->ti_dport; - - if ((so->so_iptos = tcp_tos(so)) == 0) - so->so_iptos = ((struct ip *)ti)->ip_tos; - - tp = sototcpcb(so); - tp->t_state = TCPS_LISTEN; - } - - /* - * If this is a still-connecting socket, this probably - * a retransmit of the SYN. Whether it's a retransmit SYN - * or something else, we nuke it. - */ - if (so->so_state & SS_ISFCONNECTING) - goto drop; - - tp = sototcpcb(so); - - /* XXX Should never fail */ - if (tp == 0) - goto dropwithreset; - if (tp->t_state == TCPS_CLOSED) - goto drop; - - /* Unscale the window into a 32-bit value. */ -/* if ((tiflags & TH_SYN) == 0) - * tiwin = ti->ti_win << tp->snd_scale; - * else - */ - tiwin = ti->ti_win; - - /* - * Segment received on connection. - * Reset idle time and keep-alive timer. - */ - tp->t_idle = 0; - if (so_options) - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; - else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; - - /* - * Process options if not in LISTEN state, - * else do it below (after getting remote address). - */ - if (optp && tp->t_state != TCPS_LISTEN) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); -/* , */ -/* &ts_present, &ts_val, &ts_ecr); */ - - /* - * Header prediction: check for the two common cases - * of a uni-directional data xfer. If the packet has - * no control flags, is in-sequence, the window didn't - * change and we're not retransmitting, it's a - * candidate. If the length is zero and the ack moved - * forward, we're the sender side of the xfer. Just - * free the data acked & wake any higher level process - * that was blocked waiting for space. If the length - * is non-zero and the ack didn't move, we're the - * receiver side. If we're getting packets in-order - * (the reassembly queue is empty), add the data to - * the socket buffer and note that we need a delayed ack. - * - * XXX Some of these tests are not needed - * eg: the tiwin == tp->snd_wnd prevents many more - * predictions.. with no *real* advantage.. - */ - if (tp->t_state == TCPS_ESTABLISHED && - (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && -/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ - ti->ti_seq == tp->rcv_nxt && - tiwin && tiwin == tp->snd_wnd && - tp->snd_nxt == tp->snd_max) { - /* - * If last ACK falls within this segment's sequence numbers, - * record the timestamp. - */ -/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ - if (ti->ti_len == 0) { - if (SEQ_GT(ti->ti_ack, tp->snd_una) && - SEQ_LEQ(ti->ti_ack, tp->snd_max) && - tp->snd_cwnd >= tp->snd_wnd) { - /* - * this is a pure ack for outstanding data. - */ - ++tcpstat.tcps_predack; -/* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ if (tp->t_rtt && - SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); - acked = ti->ti_ack - tp->snd_una; - tcpstat.tcps_rcvackpack++; - tcpstat.tcps_rcvackbyte += acked; - sbdrop(&so->so_snd, acked); - tp->snd_una = ti->ti_ack; - m_freem(m); - - /* - * If all outstanding data are acked, stop - * retransmit timer, otherwise restart timer - * using current (possibly backed-off) value. - * If process is waiting for space, - * wakeup/selwakeup/signal. If data - * are ready to send, let tcp_output - * decide between more output or persist. - */ - if (tp->snd_una == tp->snd_max) - tp->t_timer[TCPT_REXMT] = 0; - else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - - /* - * There's room in so_snd, sowwakup will read() - * from the socket if we can - */ -/* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - /* - * This is called because sowwakeup might have - * put data into so_snd. Since we don't so sowwakeup, - * we don't need this.. XXX??? - */ - if (so->so_snd.sb_cc) - (void) tcp_output(tp); - - return; - } - } else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && - ti->ti_len <= sbspace(&so->so_rcv)) { - /* - * this is a pure, in-sequence data packet - * with nothing on the reassembly queue and - * we have enough buffer space to take it. - */ - ++tcpstat.tcps_preddat; - tp->rcv_nxt += ti->ti_len; - tcpstat.tcps_rcvpack++; - tcpstat.tcps_rcvbyte += ti->ti_len; - /* - * Add data to socket buffer. - */ - if (so->so_emu) { - if (tcp_emu(so,m)) sbappend(so, m); - } else - sbappend(so, m); - - /* - * XXX This is called when data arrives. Later, check - * if we can actually write() to the socket - * XXX Need to check? It's be NON_BLOCKING - */ -/* sorwakeup(so); */ - - /* - * If this is a short packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * It is better to not delay acks at all to maximize - * TCP throughput. See RFC 2581. - */ - tp->t_flags |= TF_ACKNOW; - tcp_output(tp); - return; - } - } /* header prediction */ - /* - * Calculate amount of space in receive window, - * and then do TCP input processing. - * Receive window is amount of space in rcv queue, - * but not less than advertised window. - */ - { int win; - win = sbspace(&so->so_rcv); - if (win < 0) - win = 0; - tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); - } - - switch (tp->t_state) { - - /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial - * tp->iss, and send a segment: - * - * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. - * Fill in remote peer address fields if not previously specified. - * Enter SYN_RECEIVED state, and process any other fields of this - * segment in this state. - */ - case TCPS_LISTEN: { - - if (tiflags & TH_RST) - goto drop; - if (tiflags & TH_ACK) - goto dropwithreset; - if ((tiflags & TH_SYN) == 0) - goto drop; - - /* - * This has way too many gotos... - * But a bit of spaghetti code never hurt anybody :) - */ - - /* - * If this is destined for the control address, then flag to - * tcp_ctl once connected, otherwise connect - */ - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { - int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff; - if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { -#if 0 - if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { - /* Command or exec adress */ - so->so_state |= SS_CTL; - } else -#endif - { - /* May be an add exec */ - struct ex_list *ex_ptr; - for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if(ex_ptr->ex_fport == so->so_fport && - lastbyte == ex_ptr->ex_addr) { - so->so_state |= SS_CTL; - break; - } - } - } - if(so->so_state & SS_CTL) goto cont_input; - } - /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ - } - - if (so->so_emu & EMU_NOCONNECT) { - so->so_emu &= ~EMU_NOCONNECT; - goto cont_input; - } - - if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { - u_char code=ICMP_UNREACH_NET; - DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", - errno,strerror(errno))); - if(errno == ECONNREFUSED) { - /* ACK the SYN, send RST to refuse the connection */ - tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0, - TH_RST|TH_ACK); - } else { - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - HTONL(ti->ti_seq); /* restore tcp header */ - HTONL(ti->ti_ack); - HTONS(ti->ti_win); - HTONS(ti->ti_urp); - m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - *ip=save_ip; - icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno)); - } - tp = tcp_close(tp); - m_free(m); - } else { - /* - * Haven't connected yet, save the current SLIRPmbuf - * and ti, and return - * XXX Some OS's don't tell us whether the connect() - * succeeded or not. So we must time it out. - */ - so->so_m = m; - so->so_ti = ti; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->t_state = TCPS_SYN_RECEIVED; - } - return; - - cont_conn: - /* m==NULL - * Check if the connect succeeded - */ - if (so->so_state & SS_NOFDREF) { - tp = tcp_close(tp); - goto dropwithreset; - } - cont_input: - tcp_template(tp); - - if (optp) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ - - if (iss) - tp->iss = iss; - else - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tp->irs = ti->ti_seq; - tcp_sendseqinit(tp); - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tcpstat.tcps_accepts++; - goto trimthenstep6; - } /* case TCPS_LISTEN */ - - /* - * If the state is SYN_SENT: - * if seg contains an ACK, but not for our SYN, drop the input. - * if seg contains a RST, then drop the connection. - * if seg does not contain SYN, then drop it. - * Otherwise this is an acceptable SYN segment - * initialize tp->rcv_nxt and tp->irs - * if seg contains ack then advance tp->snd_una - * if SYN has been acked change to ESTABLISHED else SYN_RCVD state - * arrange for segment to be acked (eventually) - * continue processing rest of data/controls, beginning with URG - */ - case TCPS_SYN_SENT: - if ((tiflags & TH_ACK) && - (SEQ_LEQ(ti->ti_ack, tp->iss) || - SEQ_GT(ti->ti_ack, tp->snd_max))) - goto dropwithreset; - - if (tiflags & TH_RST) { - if (tiflags & TH_ACK) - tp = tcp_drop(tp,0); /* XXX Check t_softerror! */ - goto drop; - } - - if ((tiflags & TH_SYN) == 0) - goto drop; - if (tiflags & TH_ACK) { - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - } - - tp->t_timer[TCPT_REXMT] = 0; - tp->irs = ti->ti_seq; - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { - tcpstat.tcps_connects++; - soisfconnected(so); - tp->t_state = TCPS_ESTABLISHED; - - /* Do window scaling on this connection? */ -/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - * (TF_RCVD_SCALE|TF_REQ_SCALE)) { - * tp->snd_scale = tp->requested_s_scale; - * tp->rcv_scale = tp->request_r_scale; - * } - */ - (void) tcp_reass(tp, (struct tcpiphdr *)0, - (struct SLIRPmbuf *)0); - /* - * if we didn't have to retransmit the SYN, - * use its rtt as our initial srtt & rtt var. - */ - if (tp->t_rtt) - tcp_xmit_timer(tp, tp->t_rtt); - } else - tp->t_state = TCPS_SYN_RECEIVED; - -trimthenstep6: - /* - * Advance ti->ti_seq to correspond to first data byte. - * If data, trim to stay within window, - * dropping FIN if necessary. - */ - ti->ti_seq++; - if (ti->ti_len > tp->rcv_wnd) { - todrop = ti->ti_len - tp->rcv_wnd; - m_adj(m, -todrop); - ti->ti_len = tp->rcv_wnd; - tiflags &= ~TH_FIN; - tcpstat.tcps_rcvpackafterwin++; - tcpstat.tcps_rcvbyteafterwin += todrop; - } - tp->snd_wl1 = ti->ti_seq - 1; - tp->rcv_up = ti->ti_seq; - goto step6; - } /* switch tp->t_state */ - /* - * States other than LISTEN or SYN_SENT. - * First check timestamp, if present. - * Then check that at least some bytes of segment are within - * receive window. If segment begins before rcv_nxt, - * drop leading data (and SYN); if nothing left, just ack. - * - * RFC 1323 PAWS: If we have a timestamp reply on this segment - * and it's less than ts_recent, drop it. - */ -/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && - * TSTMP_LT(ts_val, tp->ts_recent)) { - * - */ /* Check to see if ts_recent is over 24 days old. */ -/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { - */ /* - * * Invalidate ts_recent. If this segment updates - * * ts_recent, the age will be reset later and ts_recent - * * will get a valid value. If it does not, setting - * * ts_recent to zero will at least satisfy the - * * requirement that zero be placed in the timestamp - * * echo reply when ts_recent isn't valid. The - * * age isn't reset until we get a valid ts_recent - * * because we don't want out-of-order segments to be - * * dropped when ts_recent is old. - * */ -/* tp->ts_recent = 0; - * } else { - * tcpstat.tcps_rcvduppack++; - * tcpstat.tcps_rcvdupbyte += ti->ti_len; - * tcpstat.tcps_pawsdrop++; - * goto dropafterack; - * } - * } - */ - - todrop = tp->rcv_nxt - ti->ti_seq; - if (todrop > 0) { - if (tiflags & TH_SYN) { - tiflags &= ~TH_SYN; - ti->ti_seq++; - if (ti->ti_urp > 1) - ti->ti_urp--; - else - tiflags &= ~TH_URG; - todrop--; - } - /* - * Following if statement from Stevens, vol. 2, p. 960. - */ - if (todrop > ti->ti_len - || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { - /* - * Any valid FIN must be to the left of the window. - * At this point the FIN must be a duplicate or out - * of sequence; drop it. - */ - tiflags &= ~TH_FIN; - - /* - * Send an ACK to resynchronize and drop any data. - * But keep on processing for RST or ACK. - */ - tp->t_flags |= TF_ACKNOW; - todrop = ti->ti_len; - tcpstat.tcps_rcvduppack++; - tcpstat.tcps_rcvdupbyte += todrop; - } else { - tcpstat.tcps_rcvpartduppack++; - tcpstat.tcps_rcvpartdupbyte += todrop; - } - m_adj(m, todrop); - ti->ti_seq += todrop; - ti->ti_len -= todrop; - if (ti->ti_urp > todrop) - ti->ti_urp -= todrop; - else { - tiflags &= ~TH_URG; - ti->ti_urp = 0; - } - } - /* - * If new data are received on a connection after the - * user processes are gone, then RST the other end. - */ - if ((so->so_state & SS_NOFDREF) && - tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { - tp = tcp_close(tp); - tcpstat.tcps_rcvafterclose++; - goto dropwithreset; - } - - /* - * If segment ends after window, drop trailing data - * (and PUSH and FIN); if nothing left, just ACK. - */ - todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); - if (todrop > 0) { - tcpstat.tcps_rcvpackafterwin++; - if (todrop >= ti->ti_len) { - tcpstat.tcps_rcvbyteafterwin += ti->ti_len; - /* - * If a new connection request is received - * while in TIME_WAIT, drop the old connection - * and start over if the sequence numbers - * are above the previous ones. - */ - if (tiflags & TH_SYN && - tp->t_state == TCPS_TIME_WAIT && - SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { - iss = tp->rcv_nxt + TCP_ISSINCR; - tp = tcp_close(tp); - goto findso; - } - /* - * If window is closed can only take segments at - * window edge, and have to drop data and PUSH from - * incoming segments. Continue processing, but - * remember to ack. Otherwise, drop segment - * and ack. - */ - if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { - tp->t_flags |= TF_ACKNOW; - tcpstat.tcps_rcvwinprobe++; - } else - goto dropafterack; - } else - tcpstat.tcps_rcvbyteafterwin += todrop; - m_adj(m, -todrop); - ti->ti_len -= todrop; - tiflags &= ~(TH_PUSH|TH_FIN); - } - - /* - * If last ACK falls within this segment's sequence numbers, - * record its timestamp. - */ -/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + - * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ - - /* - * If the RST bit is set examine the state: - * SYN_RECEIVED STATE: - * If passive open, return to LISTEN state. - * If active open, inform user that connection was refused. - * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: - * Inform user that connection was reset, and close tcb. - * CLOSING, LAST_ACK, TIME_WAIT STATES - * Close the tcb. - */ - if (tiflags&TH_RST) switch (tp->t_state) { - - case TCPS_SYN_RECEIVED: -/* so->so_error = ECONNREFUSED; */ - goto close; - - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: -/* so->so_error = ECONNRESET; */ - close: - tp->t_state = TCPS_CLOSED; - tcpstat.tcps_drops++; - tp = tcp_close(tp); - goto drop; - - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - tp = tcp_close(tp); - goto drop; - } - - /* - * If a SYN is in the window, then this is an - * error and we send an RST and drop the connection. - */ - if (tiflags & TH_SYN) { - tp = tcp_drop(tp,0); - goto dropwithreset; - } - - /* - * If the ACK bit is off we drop the segment and return. - */ - if ((tiflags & TH_ACK) == 0) goto drop; - - /* - * Ack processing. - */ - switch (tp->t_state) { - /* - * In SYN_RECEIVED state if the ack ACKs our SYN then enter - * ESTABLISHED state and continue processing, otherwise - * send an RST. una<=ack<=max - */ - case TCPS_SYN_RECEIVED: - - if (SEQ_GT(tp->snd_una, ti->ti_ack) || - SEQ_GT(ti->ti_ack, tp->snd_max)) - goto dropwithreset; - tcpstat.tcps_connects++; - tp->t_state = TCPS_ESTABLISHED; - /* - * The sent SYN is ack'ed with our sequence number +1 - * The first data byte already in the buffer will get - * lost if no correction is made. This is only needed for - * SS_CTL since the buffer is empty otherwise. - * tp->snd_una++; or: - */ - tp->snd_una=ti->ti_ack; - if (so->so_state & SS_CTL) { - /* So tcp_ctl reports the right state */ - ret = tcp_ctl(so); - if (ret == 1) { - soisfconnected(so); - so->so_state &= ~SS_CTL; /* success XXX */ - } else if (ret == 2) { - so->so_state = SS_NOFDREF; /* CTL_CMD */ - } else { - needoutput = 1; - tp->t_state = TCPS_FIN_WAIT_1; - } - } else { - soisfconnected(so); - } - - /* Do window scaling? */ -/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - * (TF_RCVD_SCALE|TF_REQ_SCALE)) { - * tp->snd_scale = tp->requested_s_scale; - * tp->rcv_scale = tp->request_r_scale; - * } - */ - (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct SLIRPmbuf *)0); - tp->snd_wl1 = ti->ti_seq - 1; - /* Avoid ack processing; snd_una==ti_ack => dup ack */ - goto synrx_to_est; - /* fall into ... */ - - /* - * In ESTABLISHED state: drop duplicate ACKs; ACK out of range - * ACKs. If the ack is in the range - * tp->snd_una < ti->ti_ack <= tp->snd_max - * then advance tp->snd_una to ti->ti_ack and drop - * data from the retransmission queue. If this ACK reflects - * more up to date window information we update our window information. - */ - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - - if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { - if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - tcpstat.tcps_rcvdupack++; - DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", - (long )m, (long )so)); - /* - * If we have outstanding data (other than - * a window probe), this is a completely - * duplicate ack (ie, window info didn't - * change), the ack is the biggest we've - * seen and we've seen exactly our rexmt - * threshold of them, assume a packet - * has been dropped and retransmit it. - * Kludge snd_nxt & the congestion - * window so we send only this one - * packet. - * - * We know we're losing at the current - * window size so do congestion avoidance - * (set ssthresh to half the current window - * and pull our congestion window back to - * the new ssthresh). - * - * Dup acks mean that packets have left the - * network (they're now cached at the receiver) - * so bump cwnd by the amount in the receiver - * to keep a constant cwnd packets in the - * network. - */ - if (tp->t_timer[TCPT_REXMT] == 0 || - ti->ti_ack != tp->snd_una) - tp->t_dupacks = 0; - else if (++tp->t_dupacks == tcprexmtthresh) { - tcp_seq onxt = tp->snd_nxt; - u_int win = - min(tp->snd_wnd, tp->snd_cwnd) / 2 / - tp->t_maxseg; - - if (win < 2) - win = 2; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_timer[TCPT_REXMT] = 0; - tp->t_rtt = 0; - tp->snd_nxt = ti->ti_ack; - tp->snd_cwnd = tp->t_maxseg; - (void) tcp_output(tp); - tp->snd_cwnd = tp->snd_ssthresh + - tp->t_maxseg * tp->t_dupacks; - if (SEQ_GT(onxt, tp->snd_nxt)) - tp->snd_nxt = onxt; - goto drop; - } else if (tp->t_dupacks > tcprexmtthresh) { - tp->snd_cwnd += tp->t_maxseg; - (void) tcp_output(tp); - goto drop; - } - } else - tp->t_dupacks = 0; - break; - } - synrx_to_est: - /* - * If the congestion window was inflated to account - * for the other side's cached packets, retract it. - */ - if (tp->t_dupacks > tcprexmtthresh && - tp->snd_cwnd > tp->snd_ssthresh) - tp->snd_cwnd = tp->snd_ssthresh; - tp->t_dupacks = 0; - if (SEQ_GT(ti->ti_ack, tp->snd_max)) { - tcpstat.tcps_rcvacktoomuch++; - goto dropafterack; - } - acked = ti->ti_ack - tp->snd_una; - tcpstat.tcps_rcvackpack++; - tcpstat.tcps_rcvackbyte += acked; - - /* - * If we have a timestamp reply, update smoothed - * round trip time. If no timestamp is present but - * transmit timer is running and timed sequence - * number was acked, update smoothed round trip time. - * Since we now have an rtt measurement, cancel the - * timer backoff (cf., Phil Karn's retransmit alg.). - * Recompute the initial retransmit timer. - */ -/* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp,tp->t_rtt); - - /* - * If all outstanding data is acked, stop retransmit - * timer and remember to restart (more output or persist). - * If there is more data to be acked, restart retransmit - * timer, using current (possibly backed-off) value. - */ - if (ti->ti_ack == tp->snd_max) { - tp->t_timer[TCPT_REXMT] = 0; - needoutput = 1; - } else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * When new data is acked, open the congestion window. - * If the window gives us less than ssthresh packets - * in flight, open exponentially (maxseg per packet). - * Otherwise open linearly: maxseg per window - * (maxseg^2 / cwnd per packet). - */ - { - u_int cw = tp->snd_cwnd; - u_int incr = tp->t_maxseg; - - if (cw > tp->snd_ssthresh) - incr = incr * incr / cw; - tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<snd_scale); - } - if (acked > so->so_snd.sb_cc) { - tp->snd_wnd -= so->so_snd.sb_cc; - sbdrop(&so->so_snd, (int )so->so_snd.sb_cc); - ourfinisacked = 1; - } else { - sbdrop(&so->so_snd, acked); - tp->snd_wnd -= acked; - ourfinisacked = 0; - } - /* - * XXX sowwakup is called when data is acked and there's room for - * for more data... it should read() the socket - */ -/* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - - switch (tp->t_state) { - - /* - * In FIN_WAIT_1 STATE in addition to the processing - * for the ESTABLISHED state if our FIN is now acknowledged - * then enter FIN_WAIT_2. - */ - case TCPS_FIN_WAIT_1: - if (ourfinisacked) { - /* - * If we can't receive any more - * data, then closing user can proceed. - * Starting the timer is contrary to the - * specification, but if we don't get a FIN - * we'll hang forever. - */ - if (so->so_state & SS_FCANTRCVMORE) { - soisfdisconnected(so); - tp->t_timer[TCPT_2MSL] = tcp_maxidle; - } - tp->t_state = TCPS_FIN_WAIT_2; - } - break; - - /* - * In CLOSING STATE in addition to the processing for - * the ESTABLISHED state if the ACK acknowledges our FIN - * then enter the TIME-WAIT state, otherwise ignore - * the segment. - */ - case TCPS_CLOSING: - if (ourfinisacked) { - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - soisfdisconnected(so); - } - break; - - /* - * In LAST_ACK, we may still be waiting for data to drain - * and/or to be acked, as well as for the ack of our FIN. - * If our FIN is now acknowledged, delete the TCB, - * enter the closed state and return. - */ - case TCPS_LAST_ACK: - if (ourfinisacked) { - tp = tcp_close(tp); - goto drop; - } - break; - - /* - * In TIME_WAIT state the only thing that should arrive - * is a retransmission of the remote FIN. Acknowledge - * it and restart the finack timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - goto dropafterack; - } - } /* switch(tp->t_state) */ - -step6: - /* - * Update window information. - * Don't look at window if no ACK: TAC's send garbage on first SYN. - */ - if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || - (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { - /* keep track of pure window updates */ - if (ti->ti_len == 0 && - tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) - tcpstat.tcps_rcvwinupd++; - tp->snd_wnd = tiwin; - tp->snd_wl1 = ti->ti_seq; - tp->snd_wl2 = ti->ti_ack; - if (tp->snd_wnd > tp->max_sndwnd) - tp->max_sndwnd = tp->snd_wnd; - needoutput = 1; - } - - /* - * Process segments with URG. - */ - if ((tiflags & TH_URG) && ti->ti_urp && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * This is a kludge, but if we receive and accept - * random urgent pointers, we'll crash in - * soreceive. It's hard to imagine someone - * actually wanting to send this much urgent data. - */ - if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) { - ti->ti_urp = 0; - tiflags &= ~TH_URG; - goto dodata; - } - /* - * If this segment advances the known urgent pointer, - * then mark the data stream. This should not happen - * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since - * a FIN has been received from the remote side. - * In these states we ignore the URG. - * - * According to RFC961 (Assigned Protocols), - * the urgent pointer points to the last octet - * of urgent data. We continue, however, - * to consider it to indicate the first octet - * of data past the urgent section as the original - * spec states (in one of two places). - */ - if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { - tp->rcv_up = ti->ti_seq + ti->ti_urp; - so->so_urgc = so->so_rcv.sb_cc + - (tp->rcv_up - tp->rcv_nxt); /* -1; */ - tp->rcv_up = ti->ti_seq + ti->ti_urp; - - } - } else - /* - * If no out of band data is expected, - * pull receive urgent pointer along - * with the receive window. - */ - if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) - tp->rcv_up = tp->rcv_nxt; -dodata: - - /* - * Process the segment text, merging it into the TCP sequencing queue, - * and arranging for acknowledgment of receipt if necessary. - * This process logically involves adjusting tp->rcv_wnd as data - * is presented to the user (this happens in tcp_usrreq.c, - * case PRU_RCVD). If a FIN has already been received on this - * connection then we just ignore the text. - */ - if ((ti->ti_len || (tiflags&TH_FIN)) && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - TCP_REASS(tp, ti, m, so, tiflags); - /* - * Note the amount of data that peer has sent into - * our window, in order to estimate the sender's - * buffer size. - */ - len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); - } else { - m_free(m); - tiflags &= ~TH_FIN; - } - - /* - * If FIN is received ACK the FIN and let the user know - * that the connection is closing. - */ - if (tiflags & TH_FIN) { - if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * If we receive a FIN we can't send more data, - * set it SS_FDRAIN - * Shutdown the socket if there is no rx data in the - * buffer. - * soread() is called on completion of shutdown() and - * will got to TCPS_LAST_ACK, and use tcp_output() - * to send the FIN. - */ -/* sofcantrcvmore(so); */ - sofwdrain(so); - - tp->t_flags |= TF_ACKNOW; - tp->rcv_nxt++; - } - switch (tp->t_state) { - - /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. - */ - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - if(so->so_emu == EMU_CTL) /* no shutdown on socket */ - tp->t_state = TCPS_LAST_ACK; - else - tp->t_state = TCPS_CLOSE_WAIT; - break; - - /* - * If still in FIN_WAIT_1 STATE FIN has not been acked so - * enter the CLOSING state. - */ - case TCPS_FIN_WAIT_1: - tp->t_state = TCPS_CLOSING; - break; - - /* - * In FIN_WAIT_2 state enter the TIME_WAIT state, - * starting the time-wait timer, turning off the other - * standard timers. - */ - case TCPS_FIN_WAIT_2: - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - soisfdisconnected(so); - break; - - /* - * In TIME_WAIT state restart the 2 MSL time_wait timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - break; - } - } - - /* - * If this is a small packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * See above. - */ -/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { - */ -/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && - * (so->so_iptos & IPTOS_LOWDELAY) == 0) || - * ((so->so_iptos & IPTOS_LOWDELAY) && - * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { - */ - if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { - tp->t_flags |= TF_ACKNOW; - } - - /* - * Return any desired output. - */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) { - (void) tcp_output(tp); - } - return; - -dropafterack: - /* - * Generate an ACK dropping incoming segment if it occupies - * sequence space, where the ACK reflects our state. - */ - if (tiflags & TH_RST) - goto drop; - m_freem(m); - tp->t_flags |= TF_ACKNOW; - (void) tcp_output(tp); - return; - -dropwithreset: - /* reuses m if m!=NULL, m_free() unnecessary */ - if (tiflags & TH_ACK) - tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); - else { - if (tiflags & TH_SYN) ti->ti_len++; - tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, - TH_RST|TH_ACK); - } - - return; - -drop: - /* - * Drop space held by incoming segment and return. - */ - m_free(m); - - return; -} - - /* , ts_present, ts_val, ts_ecr) */ -/* int *ts_present; - * u_int32_t *ts_val, *ts_ecr; - */ -void -tcp_dooptions(tp, cp, cnt, ti) - struct tcpcb *tp; - u_char *cp; - int cnt; - struct tcpiphdr *ti; -{ - u_int16_t mss; - int opt, optlen; - - DEBUG_CALL("tcp_dooptions"); - DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt)); - - for (; cnt > 0; cnt -= optlen, cp += optlen) { - opt = cp[0]; - if (opt == TCPOPT_EOL) - break; - if (opt == TCPOPT_NOP) - optlen = 1; - else { - optlen = cp[1]; - if (optlen <= 0) - break; - } - switch (opt) { - - default: - continue; - - case TCPOPT_MAXSEG: - if (optlen != TCPOLEN_MAXSEG) - continue; - if (!(ti->ti_flags & TH_SYN)) - continue; - memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); - NTOHS(mss); - (void) tcp_mss(tp, mss); /* sets t_maxseg */ - break; - -/* case TCPOPT_WINDOW: - * if (optlen != TCPOLEN_WINDOW) - * continue; - * if (!(ti->ti_flags & TH_SYN)) - * continue; - * tp->t_flags |= TF_RCVD_SCALE; - * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); - * break; - */ -/* case TCPOPT_TIMESTAMP: - * if (optlen != TCPOLEN_TIMESTAMP) - * continue; - * *ts_present = 1; - * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val)); - * NTOHL(*ts_val); - * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); - * NTOHL(*ts_ecr); - * - */ /* - * * A timestamp received in a SYN makes - * * it ok to send timestamp requests and replies. - * */ -/* if (ti->ti_flags & TH_SYN) { - * tp->t_flags |= TF_RCVD_TSTMP; - * tp->ts_recent = *ts_val; - * tp->ts_recent_age = tcp_now; - * } - */ break; - } - } -} - - -/* - * Pull out of band byte out of a segment so - * it doesn't appear in the user's data queue. - * It is still reflected in the segment length for - * sequencing purposes. - */ - -#ifdef notdef - -void -tcp_pulloutofband(so, ti, m) - struct SLIRPsocket *so; - struct tcpiphdr *ti; - struct SLIRPmbuf *m; -{ - int cnt = ti->ti_urp - 1; - - while (cnt >= 0) { - if (m->m_len > cnt) { - char *cp = mtod(m, SLIRPcaddr_t) + cnt; - struct tcpcb *tp = sototcpcb(so); - - tp->t_iobc = *cp; - tp->t_oobflags |= TCPOOB_HAVEDATA; - memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1)); - m->m_len--; - return; - } - cnt -= m->m_len; - m = m->m_next; /* XXX WRONG! Fix it! */ - if (m == 0) - break; - } - panic("tcp_pulloutofband"); -} - -#endif /* notdef */ - -/* - * Collect new round-trip time estimate - * and update averages and current timeout. - */ - -void -tcp_xmit_timer(tp, rtt) - struct tcpcb *tp; - int rtt; -{ - short delta; - - DEBUG_CALL("tcp_xmit_timer"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("rtt = %d", rtt); - - tcpstat.tcps_rttupdated++; - if (tp->t_srtt != 0) { - /* - * srtt is stored as fixed point with 3 bits after the - * binary point (i.e., scaled by 8). The following magic - * is equivalent to the smoothing algorithm in rfc793 with - * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed - * point). Adjust rtt to origin 0. - */ - delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); - if ((tp->t_srtt += delta) <= 0) - tp->t_srtt = 1; - /* - * We accumulate a smoothed rtt variance (actually, a - * smoothed mean difference), then set the retransmit - * timer to smoothed rtt + 4 times the smoothed variance. - * rttvar is stored as fixed point with 2 bits after the - * binary point (scaled by 4). The following is - * equivalent to rfc793 smoothing with an alpha of .75 - * (rttvar = rttvar*3/4 + |delta| / 4). This replaces - * rfc793's wired-in beta. - */ - if (delta < 0) - delta = -delta; - delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); - if ((tp->t_rttvar += delta) <= 0) - tp->t_rttvar = 1; - } else { - /* - * No rtt measurement yet - use the unsmoothed rtt. - * Set the variance to half the rtt (so our first - * retransmit happens at 3*rtt). - */ - tp->t_srtt = rtt << TCP_RTT_SHIFT; - tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); - } - tp->t_rtt = 0; - tp->t_rxtshift = 0; - - /* - * the retransmit should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - */ - TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), - (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ - - /* - * We received an ack for a packet that wasn't retransmitted; - * it is probably safe to discard any error indications we've - * received recently. This isn't quite right, but close enough - * for now (a route might have failed after we sent a segment, - * and the return path might not be symmetrical). - */ - tp->t_softerror = 0; -} - -/* - * Determine a reasonable value for maxseg size. - * If the route is known, check route for mtu. - * If none, use an mss that can be handled on the outgoing - * interface without forcing IP to fragment; if bigger than - * an SLIRPmbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES - * to utilize large SLIRPmbufs. If no route is found, route has no mtu, - * or the destination isn't local, use a default, hopefully conservative - * size (usually 512 or the default IP max size, but no more than the mtu - * of the interface), as we can't discover anything about intervening - * gateways or networks. We also initialize the congestion/slow start - * window to be a single segment if the destination isn't local. - * While looking at the routing entry, we also initialize other path-dependent - * parameters from pre-set or cached values in the routing entry. - */ - -int -tcp_mss(tp, offer) - struct tcpcb *tp; - u_int offer; -{ - struct SLIRPsocket *so = tp->t_socket; - int mss; - - DEBUG_CALL("tcp_mss"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("offer = %d", offer); - - mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr); - if (offer) - mss = min(mss, offer); - mss = max(mss, 32); - if (mss < tp->t_maxseg || offer != 0) - tp->t_maxseg = mss; - - tp->snd_cwnd = mss; - - sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0)); - sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0)); - - DEBUG_MISC((dfd, " returning mss = %d\n", mss)); - - return mss; -} diff --git a/src - Cópia/network/slirp/tcp_output.c b/src - Cópia/network/slirp/tcp_output.c deleted file mode 100644 index 7d75b64b2..000000000 --- a/src - Cópia/network/slirp/tcp_output.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93 - * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include "slirp.h" - -/* - * Since this is only used in "stats socket", we give meaning - * names instead of the REAL names - */ -char *tcpstates[] = { -/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ - "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", - "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", - "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", -}; - -u_char tcp_outflags[TCP_NSTATES] = { - TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, - TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, - TH_FIN|TH_ACK, TH_ACK, TH_ACK, -}; - - -#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */ - -/* - * Tcp output routine: figure out what should be sent and send it. - */ -int -tcp_output(tp) - struct tcpcb *tp; -{ - struct SLIRPsocket *so = tp->t_socket; - register long len, win; - int off, flags, error; - struct SLIRPmbuf *m; - struct tcpiphdr *ti; - u_char opt[MAX_TCPOPTLEN]; - unsigned optlen, hdrlen; - int idle, sendalot; - - DEBUG_CALL("tcp_output"); - DEBUG_ARG("tp = %lx", (long )tp); - - /* - * Determine length of data that should be transmitted, - * and flags that will be used. - * If there is some data or critical controls (SYN, RST) - * to send, then transmit; otherwise, investigate further. - */ - idle = (tp->snd_max == tp->snd_una); - if (idle && tp->t_idle >= tp->t_rxtcur) - /* - * We have been idle for "a while" and no acks are - * expected to clock out any data we send -- - * slow start to get ack "clock" running again. - */ - tp->snd_cwnd = tp->t_maxseg; -again: - sendalot = 0; - off = tp->snd_nxt - tp->snd_una; - win = min(tp->snd_wnd, tp->snd_cwnd); - - flags = tcp_outflags[tp->t_state]; - - DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); - - /* - * If in persist timeout with window of 0, send 1 byte. - * Otherwise, if window is small but nonzero - * and timer expired, we will send what we can - * and go to transmit state. - */ - if (tp->t_force) { - if (win == 0) { - /* - * If we still have some data to send, then - * clear the FIN bit. Usually this would - * happen below when it realizes that we - * aren't sending all the data. However, - * if we have exactly 1 byte of unset data, - * then it won't clear the FIN bit below, - * and if we are in persist state, we wind - * up sending the packet without recording - * that we sent the FIN bit. - * - * We can't just blindly clear the FIN bit, - * because if we don't have any more data - * to send then the probe will be the FIN - * itself. - */ - if (off < so->so_snd.sb_cc) - flags &= ~TH_FIN; - win = 1; - } else { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - - len = min(so->so_snd.sb_cc, win) - off; - - if (len < 0) { - /* - * If FIN has been sent but not acked, - * but we haven't been called to retransmit, - * len will be -1. Otherwise, window shrank - * after we sent into it. If window shrank to 0, - * cancel pending retransmit and pull snd_nxt - * back to (closed) window. We will enter persist - * state below. If the window didn't close completely, - * just wait for an ACK. - */ - len = 0; - if (win == 0) { - tp->t_timer[TCPT_REXMT] = 0; - tp->snd_nxt = tp->snd_una; - } - } - - if (len > tp->t_maxseg) { - len = tp->t_maxseg; - sendalot = 1; - } - if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) - flags &= ~TH_FIN; - - win = sbspace(&so->so_rcv); - - /* - * Sender silly window avoidance. If connection is idle - * and can send all data, a maximum segment, - * at least a maximum default-size segment do it, - * or are forced, do it; otherwise don't bother. - * If peer's buffer is tiny, then send - * when window is at least half open. - * If retransmitting (possibly after persist timer forced us - * to send into a small window), then must resend. - */ - if (len) { - if (len == tp->t_maxseg) - goto send; - if ((1 || idle || tp->t_flags & TF_NODELAY) && - len + off >= so->so_snd.sb_cc) - goto send; - if (tp->t_force) - goto send; - if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) - goto send; - if (SEQ_LT(tp->snd_nxt, tp->snd_max)) - goto send; - } - - /* - * Compare available window to amount of window - * known to peer (as advertised window less - * next expected input). If the difference is at least two - * max size segments, or at least 50% of the maximum possible - * window, then want to send a window update to peer. - */ - if (win > 0) { - /* - * "adv" is the amount we can increase the window, - * taking into account that we are limited by - * TCP_MAXWIN << tp->rcv_scale. - */ - long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - - (tp->rcv_adv - tp->rcv_nxt); - - if (adv >= (long) (2 * tp->t_maxseg)) - goto send; - if (2 * adv >= (long) so->so_rcv.sb_datalen) - goto send; - } - - /* - * Send if we owe peer an ACK. - */ - if (tp->t_flags & TF_ACKNOW) - goto send; - if (flags & (TH_SYN|TH_RST)) - goto send; - if (SEQ_GT(tp->snd_up, tp->snd_una)) - goto send; - /* - * If our state indicates that FIN should be sent - * and we have not yet done so, or we're retransmitting the FIN, - * then we need to send. - */ - if (flags & TH_FIN && - ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) - goto send; - - /* - * TCP window updates are not reliable, rather a polling protocol - * using ``persist'' packets is used to insure receipt of window - * updates. The three ``states'' for the output side are: - * idle not doing retransmits or persists - * persisting to move a small or zero window - * (re)transmitting and thereby not persisting - * - * tp->t_timer[TCPT_PERSIST] - * is set when we are in persist state. - * tp->t_force - * is set when we are called to send a persist packet. - * tp->t_timer[TCPT_REXMT] - * is set when we are retransmitting - * The output side is idle when both timers are zero. - * - * If send window is too small, there is data to transmit, and no - * retransmit or persist is pending, then go to persist state. - * If nothing happens soon, send when timer expires: - * if window is nonzero, transmit what we can, - * otherwise force out a byte. - */ - if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && - tp->t_timer[TCPT_PERSIST] == 0) { - tp->t_rxtshift = 0; - tcp_setpersist(tp); - } - - /* - * No reason to send a segment, just return. - */ - tcpstat.tcps_didnuttin++; - - return (0); - -send: - /* - * Before ESTABLISHED, force sending of initial options - * unless TCP set not to do any options. - * NOTE: we assume that the IP/TCP header plus TCP options - * always fit in a single SLIRPmbuf, leaving room for a maximum - * link header, i.e. - * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN - */ - optlen = 0; - hdrlen = sizeof (struct tcpiphdr); - if (flags & TH_SYN) { - tp->snd_nxt = tp->iss; - if ((tp->t_flags & TF_NOOPT) == 0) { - u_int16_t mss; - - opt[0] = TCPOPT_MAXSEG; - opt[1] = 4; - mss = htons((u_int16_t) tcp_mss(tp, 0)); - memcpy((SLIRPcaddr_t)(opt + 2), (SLIRPcaddr_t)&mss, sizeof(mss)); - optlen = 4; - -/* if ((tp->t_flags & TF_REQ_SCALE) && - * ((flags & TH_ACK) == 0 || - * (tp->t_flags & TF_RCVD_SCALE))) { - * *((u_int32_t *) (opt + optlen)) = htonl( - * TCPOPT_NOP << 24 | - * TCPOPT_WINDOW << 16 | - * TCPOLEN_WINDOW << 8 | - * tp->request_r_scale); - * optlen += 4; - * } - */ - } - } - - /* - * Send a timestamp and echo-reply if this is a SYN and our side - * wants to use timestamps (TF_REQ_TSTMP is set) or both our side - * and our peer have sent timestamps in our SYN's. - */ -/* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && - * (flags & TH_RST) == 0 && - * ((flags & (TH_SYN|TH_ACK)) == TH_SYN || - * (tp->t_flags & TF_RCVD_TSTMP))) { - * u_int32_t *lp = (u_int32_t *)(opt + optlen); - * - * / * Form timestamp option as shown in appendix A of RFC 1323. * / - * *lp++ = htonl(TCPOPT_TSTAMP_HDR); - * *lp++ = htonl(tcp_now); - * *lp = htonl(tp->ts_recent); - * optlen += TCPOLEN_TSTAMP_APPA; - * } - */ - hdrlen += optlen; - - /* - * Adjust data length if insertion of options will - * bump the packet length beyond the t_maxseg length. - */ - if (len > tp->t_maxseg - optlen) { - len = tp->t_maxseg - optlen; - sendalot = 1; - } - - /* - * Grab a header SLIRPmbuf, attaching a copy of data to - * be transmitted, and initialize the header from - * the template for sends on this connection. - */ - if (len) { - if (tp->t_force && len == 1) - tcpstat.tcps_sndprobe++; - else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { - tcpstat.tcps_sndrexmitpack++; - tcpstat.tcps_sndrexmitbyte += len; - } else { - tcpstat.tcps_sndpack++; - tcpstat.tcps_sndbyte += len; - } - - m = m_get(); - if (m == NULL) { -/* error = ENOBUFS; */ - error = 1; - goto out; - } - m->m_data += if_maxlinkhdr; - m->m_len = hdrlen; - - /* - * This will always succeed, since we make sure our SLIRPmbufs - * are big enough to hold one MSS packet + header + ... etc. - */ -/* if (len <= MHLEN - hdrlen - max_linkhdr) { */ - - sbcopy(&so->so_snd, off, (int) len, mtod(m, SLIRPcaddr_t) + hdrlen); - m->m_len += len; - -/* } else { - * m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); - * if (m->m_next == 0) - * len = 0; - * } - */ - /* - * If we're sending everything we've got, set PUSH. - * (This will keep happy those implementations which only - * give data to the user when a buffer fills or - * a PUSH comes in.) - */ - if (off + len == so->so_snd.sb_cc) - flags |= TH_PUSH; - } else { - if (tp->t_flags & TF_ACKNOW) - tcpstat.tcps_sndacks++; - else if (flags & (TH_SYN|TH_FIN|TH_RST)) - tcpstat.tcps_sndctrl++; - else if (SEQ_GT(tp->snd_up, tp->snd_una)) - tcpstat.tcps_sndurg++; - else - tcpstat.tcps_sndwinup++; - - m = m_get(); - if (m == NULL) { -/* error = ENOBUFS; */ - error = 1; - goto out; - } - m->m_data += if_maxlinkhdr; - m->m_len = hdrlen; - } - - ti = mtod(m, struct tcpiphdr *); - - memcpy((SLIRPcaddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); - - /* - * Fill in fields, remembering maximum advertised - * window for use in delaying messages about window sizes. - * If resending a FIN, be sure not to use a new sequence number. - */ - if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && - tp->snd_nxt == tp->snd_max) - tp->snd_nxt--; - /* - * If we are doing retransmissions, then snd_nxt will - * not reflect the first unsent octet. For ACK only - * packets, we do not want the sequence number of the - * retransmitted packet, we want the sequence number - * of the next unsent octet. So, if there is no data - * (and no SYN or FIN), use snd_max instead of snd_nxt - * when filling in ti_seq. But if we are in persist - * state, snd_max might reflect one byte beyond the - * right edge of the window, so use snd_nxt in that - * case, since we know we aren't doing a retransmission. - * (retransmit and persist are mutually exclusive...) - */ - if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) - ti->ti_seq = htonl(tp->snd_nxt); - else - ti->ti_seq = htonl(tp->snd_max); - ti->ti_ack = htonl(tp->rcv_nxt); - if (optlen) { - memcpy((SLIRPcaddr_t)(ti + 1), (SLIRPcaddr_t)opt, optlen); - ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; - } - ti->ti_flags = flags; - /* - * Calculate receive window. Don't shrink window, - * but avoid silly window syndrome. - */ - if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) - win = 0; - if (win > (long)TCP_MAXWIN << tp->rcv_scale) - win = (long)TCP_MAXWIN << tp->rcv_scale; - if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) - win = (long)(tp->rcv_adv - tp->rcv_nxt); - ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); - - if (SEQ_GT(tp->snd_up, tp->snd_una)) { - ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); -#ifdef notdef - if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { - ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); -#endif - ti->ti_flags |= TH_URG; - } else - /* - * If no urgent pointer to send, then we pull - * the urgent pointer to the left edge of the send window - * so that it doesn't drift into the send window on sequence - * number wraparound. - */ - tp->snd_up = tp->snd_una; /* drag it along */ - - /* - * Put TCP length in extended header, and then - * checksum extended header and data. - */ - if (len + optlen) - ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + - optlen + len)); - ti->ti_sum = cksum(m, (int)(hdrlen + len)); - - /* - * In transmit state, time the transmission and arrange for - * the retransmit. In persist state, just set snd_max. - */ - if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { - tcp_seq startseq = tp->snd_nxt; - - /* - * Advance snd_nxt over sequence space of this segment. - */ - if (flags & (TH_SYN|TH_FIN)) { - if (flags & TH_SYN) - tp->snd_nxt++; - if (flags & TH_FIN) { - tp->snd_nxt++; - tp->t_flags |= TF_SENTFIN; - } - } - tp->snd_nxt += len; - if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { - tp->snd_max = tp->snd_nxt; - /* - * Time this transmission if not a retransmission and - * not currently timing anything. - */ - if (tp->t_rtt == 0) { - tp->t_rtt = 1; - tp->t_rtseq = startseq; - tcpstat.tcps_segstimed++; - } - } - - /* - * Set retransmit timer if not currently set, - * and not doing an ack or a keep-alive probe. - * Initial value for retransmit timer is smoothed - * round-trip time + 2 * round-trip time variance. - * Initialize shift counter which is used for backoff - * of retransmit time. - */ - if (tp->t_timer[TCPT_REXMT] == 0 && - tp->snd_nxt != tp->snd_una) { - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - if (tp->t_timer[TCPT_PERSIST]) { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - } else - if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) - tp->snd_max = tp->snd_nxt + len; - - /* - * Fill in IP length and desired time to live and - * send to IP level. There should be a better way - * to handle ttl and tos; we could keep them in - * the template, but need a way to checksum without them. - */ - m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ - - { - - ((struct ip *)ti)->ip_len = m->m_len; - - ((struct ip *)ti)->ip_ttl = ip_defttl; - ((struct ip *)ti)->ip_tos = so->so_iptos; - -/* #if BSD >= 43 */ - /* Don't do IP options... */ -/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, - * so->so_options & SO_DONTROUTE, 0); - */ - error = ip_output(so, m); - -/* #else - * error = ip_output(m, (struct SLIRPmbuf *)0, &tp->t_inpcb->inp_route, - * so->so_options & SO_DONTROUTE); - * #endif - */ - } - if (error) { -out: -/* if (error == ENOBUFS) { - * tcp_quench(tp->t_inpcb, 0); - * return (0); - * } - */ -/* if ((error == EHOSTUNREACH || error == ENETDOWN) - * && TCPS_HAVERCVDSYN(tp->t_state)) { - * tp->t_softerror = error; - * return (0); - * } - */ - return (error); - } - tcpstat.tcps_sndtotal++; - - /* - * Data sent (as far as we can tell). - * If this advertises a larger window than any other segment, - * then remember the size of the advertised window. - * Any pending ACK has now been sent. - */ - if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) - tp->rcv_adv = tp->rcv_nxt + win; - tp->last_ack_sent = tp->rcv_nxt; - tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); - if (sendalot) - goto again; - - return (0); -} - -void -tcp_setpersist(tp) - struct tcpcb *tp; -{ - int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; - -/* if (tp->t_timer[TCPT_REXMT]) - * panic("tcp_output REXMT"); - */ - /* - * Start/restart persistence timer. - */ - TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], - t * tcp_backoff[tp->t_rxtshift], - TCPTV_PERSMIN, TCPTV_PERSMAX); - if (tp->t_rxtshift < TCP_MAXRXTSHIFT) - tp->t_rxtshift++; -} diff --git a/src - Cópia/network/slirp/tcp_subr.c b/src - Cópia/network/slirp/tcp_subr.c deleted file mode 100644 index 5f04b0730..000000000 --- a/src - Cópia/network/slirp/tcp_subr.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 - * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#ifndef _WIN32 -# include -#endif -#include "slirp.h" - -/* patchable/settable parameters for tcp */ -int tcp_mssdflt = TCP_MSS; -int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; -int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ -int tcp_rcvspace; /* You may want to change this */ -int tcp_sndspace; /* Keep small if you have an error prone link */ - -/* - * Tcp initialization - */ -void -tcp_init() -{ - tcp_iss = 1; /* wrong */ - tcb.so_next = tcb.so_prev = &tcb; - - /* tcp_rcvspace = our Window we advertise to the remote */ - tcp_rcvspace = TCP_RCVSPACE; - tcp_sndspace = TCP_SNDSPACE; - - /* Make sure tcp_sndspace is at least 2*MSS */ - if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr))) - tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); -} - -/* - * Create template to be used to send tcp packets on a connection. - * Call after host entry created, fills - * in a skeletal tcp/ip header, minimizing the amount of work - * necessary when the connection is used. - */ -/* struct tcpiphdr * */ -void -tcp_template(tp) - struct tcpcb *tp; -{ - struct SLIRPsocket *so = tp->t_socket; - struct tcpiphdr *n = &tp->t_template; - - n->ti_next = n->ti_prev = 0; - n->ti_x1 = 0; - n->ti_pr = IPPROTO_TCP; - n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); - n->ti_src = so->so_faddr; - n->ti_dst = so->so_laddr; - n->ti_sport = so->so_fport; - n->ti_dport = so->so_lport; - - n->ti_seq = 0; - n->ti_ack = 0; - n->ti_x2 = 0; - n->ti_off = 5; - n->ti_flags = 0; - n->ti_win = 0; - n->ti_sum = 0; - n->ti_urp = 0; -} - -/* - * Send a single message to the TCP at address specified by - * the given TCP/IP header. If m == 0, then we make a copy - * of the tcpiphdr at ti and send directly to the addressed host. - * This is used to force keep alive messages out using the TCP - * template for a connection tp->t_template. If flags are given - * then we send a message back to the TCP which originated the - * segment ti, and discard the SLIRPmbuf containing it and any other - * attached SLIRPmbufs. - * - * In any case the ack and sequence number of the transmitted - * segment are as specified by the parameters. - */ -void -tcp_respond(tp, ti, m, ack, seq, flags) - struct tcpcb *tp; - struct tcpiphdr *ti; - struct SLIRPmbuf *m; - tcp_seq ack, seq; - int flags; -{ - register int tlen; - int win = 0; - - DEBUG_CALL("tcp_respond"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("ti = %lx", (long)ti); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("ack = %u", ack); - DEBUG_ARG("seq = %u", seq); - DEBUG_ARG("flags = %x", flags); - - if (tp) - win = sbspace(&tp->t_socket->so_rcv); - if (m == 0) { - if ((m = m_get()) == NULL) - return; -#ifdef TCP_COMPAT_42 - tlen = 1; -#else - tlen = 0; -#endif - m->m_data += if_maxlinkhdr; - *mtod(m, struct tcpiphdr *) = *ti; - ti = mtod(m, struct tcpiphdr *); - flags = TH_ACK; - } else { - /* - * ti points into m so the next line is just making - * the SLIRPmbuf point to ti - */ - m->m_data = (SLIRPcaddr_t)ti; - - m->m_len = sizeof (struct tcpiphdr); - tlen = 0; -#define xchg(a,b,type) { type t; t=a; a=b; b=t; } - xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); - xchg(ti->ti_dport, ti->ti_sport, u_int16_t); -#undef xchg - } - ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); - tlen += sizeof (struct tcpiphdr); - m->m_len = tlen; - - ti->ti_next = ti->ti_prev = 0; - ti->ti_x1 = 0; - ti->ti_seq = htonl(seq); - ti->ti_ack = htonl(ack); - ti->ti_x2 = 0; - ti->ti_off = sizeof (struct tcphdr) >> 2; - ti->ti_flags = flags; - if (tp) - ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); - else - ti->ti_win = htons((u_int16_t)win); - ti->ti_urp = 0; - ti->ti_sum = 0; - ti->ti_sum = cksum(m, tlen); - ((struct ip *)ti)->ip_len = tlen; - - if(flags & TH_RST) - ((struct ip *)ti)->ip_ttl = MAXTTL; - else - ((struct ip *)ti)->ip_ttl = ip_defttl; - - (void) ip_output((struct SLIRPsocket *)0, m); -} - -/* - * Create a new TCP control block, making an - * empty reassembly queue and hooking it to the argument - * protocol control block. - */ -struct tcpcb * -tcp_newtcpcb(so) - struct SLIRPsocket *so; -{ - struct tcpcb *tp; - - tp = (struct tcpcb *)malloc(sizeof(*tp)); - if (tp == NULL) - return ((struct tcpcb *)0); - - memset((char *) tp, 0, sizeof(struct tcpcb)); - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; - tp->t_maxseg = tcp_mssdflt; - - tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; - tp->t_socket = so; - - /* - * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no - * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives - * reasonable initial retransmit time. - */ - tp->t_srtt = TCPTV_SRTTBASE; - tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; - tp->t_rttmin = TCPTV_MIN; - - TCPT_RANGESET(tp->t_rxtcur, - ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, - TCPTV_MIN, TCPTV_REXMTMAX); - - tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->t_state = TCPS_CLOSED; - - so->so_tcpcb = tp; - - return (tp); -} - -/* - * Drop a TCP connection, reporting - * the specified error. If connection is synchronized, - * then send a RST to peer. - */ -struct tcpcb *tcp_drop(struct tcpcb *tp, int err) -{ -/* tcp_drop(tp, errno) - struct tcpcb *tp; - int errno; -{ -*/ - - DEBUG_CALL("tcp_drop"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("errno = %d", errno); - - if (TCPS_HAVERCVDSYN(tp->t_state)) { - tp->t_state = TCPS_CLOSED; - (void) tcp_output(tp); - tcpstat.tcps_drops++; - } else - tcpstat.tcps_conndrops++; -/* if (errno == ETIMEDOUT && tp->t_softerror) - * errno = tp->t_softerror; - */ -/* so->so_error = errno; */ - return (tcp_close(tp)); -} - -/* - * Close a TCP control block: - * discard all space held by the tcp - * discard internet protocol block - * wake up any sleepers - */ -struct tcpcb * -tcp_close(tp) - struct tcpcb *tp; -{ - struct tcpiphdr *t; - struct SLIRPsocket *so = tp->t_socket; - struct SLIRPmbuf *m; - - DEBUG_CALL("tcp_close"); - DEBUG_ARG("tp = %lx", (long )tp); - - /* free the reassembly queue, if any */ - t = (struct tcpiphdr *) tp->seg_next; - while (t != (struct tcpiphdr *)tp) { - t = (struct tcpiphdr *)t->ti_next; - m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev); - remque_32((struct tcpiphdr *) t->ti_prev); - m_freem(m); - } - /* It's static */ -/* if (tp->t_template) - * (void) m_free(dtom(tp->t_template)); - */ -/* free(tp, M_PCB); */ - free(tp); - so->so_tcpcb = 0; - soisfdisconnected(so); - /* clobber input socket cache if we're closing the cached connection */ - if (so == tcp_last_so) - tcp_last_so = &tcb; - closesocket(so->s); - sbfree(&so->so_rcv); - sbfree(&so->so_snd); - sofree(so); - tcpstat.tcps_closed++; - return ((struct tcpcb *)0); -} - -void -tcp_drain() -{ - /* XXX */ -} - -/* - * When a source quench is received, close congestion window - * to one segment. We will gradually open it again as we proceed. - */ - -#ifdef notdef - -void -tcp_quench(i, errno) - - int errno; -{ - struct tcpcb *tp = intotcpcb(inp); - - if (tp) - tp->snd_cwnd = tp->t_maxseg; -} - -#endif /* notdef */ - -/* - * TCP protocol interface to socket abstraction. - */ - -/* - * User issued close, and wish to trail through shutdown states: - * if never received SYN, just forget it. If got a SYN from peer, - * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. - * If already got a FIN from peer, then almost done; go to LAST_ACK - * state. In all other cases, have already sent FIN to peer (e.g. - * after PRU_SHUTDOWN), and just have to play tedious game waiting - * for peer to send FIN or not respond to keep-alives, etc. - * We can let the user exit from the close as soon as the FIN is acked. - */ -void -tcp_sockclosed(tp) - struct tcpcb *tp; -{ - - DEBUG_CALL("tcp_sockclosed"); - DEBUG_ARG("tp = %lx", (long)tp); - - switch (tp->t_state) { - - case TCPS_CLOSED: - case TCPS_LISTEN: - case TCPS_SYN_SENT: - tp->t_state = TCPS_CLOSED; - tp = tcp_close(tp); - break; - - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - tp->t_state = TCPS_FIN_WAIT_1; - break; - - case TCPS_CLOSE_WAIT: - tp->t_state = TCPS_LAST_ACK; - break; - } -/* soisfdisconnecting(tp->t_socket); */ - if (tp && tp->t_state >= TCPS_FIN_WAIT_2) - soisfdisconnected(tp->t_socket); - if (tp) - tcp_output(tp); -} - -/* - * Connect to a host on the Internet - * Called by tcp_input - * Only do a connect, the tcp fields will be set in tcp_input - * return 0 if there's a result of the connect, - * else return -1 means we're still connecting - * The return value is almost always -1 since the socket is - * nonblocking. Connect returns after the SYN is sent, and does - * not wait for ACK+SYN. - */ -int tcp_fconnect(so) - struct SLIRPsocket *so; -{ - int ret=0; - - DEBUG_CALL("tcp_fconnect"); - DEBUG_ARG("so = %lx", (long )so); - - if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { - int opt, s=so->s; - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - fd_nonblock(s); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); - - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else - addr.sin_addr = so->so_faddr; - addr.sin_port = so->so_fport; - - DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " - "addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); - /* We don't care what port we get */ - ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); - - /* - * If it's not in progress, it failed, so we just return 0, - * without clearing SS_NOFDREF - */ - soisfconnecting(so); - } - - return(ret); -} - -/* - * Accept the socket and connect to the local-host - * - * We have a problem. The correct thing to do would be - * to first connect to the local-host, and only if the - * connection is accepted, then do an accept() here. - * But, a) we need to know who's trying to connect - * to the socket to be able to SYN the local-host, and - * b) we are already connected to the foreign host by - * the time it gets to accept(), so... We simply accept - * here and SYN the local-host. - */ -void -tcp_connect(inso) - struct SLIRPsocket *inso; -{ - struct SLIRPsocket *so; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - struct tcpcb *tp; - int s, opt; - - DEBUG_CALL("tcp_connect"); - DEBUG_ARG("inso = %lx", (long)inso); - - /* - * If it's an SS_ACCEPTONCE socket, no need to socreate() - * another socket, just use the accept() socket. - */ - if (inso->so_state & SS_FACCEPTONCE) { - /* FACCEPTONCE already have a tcpcb */ - so = inso; - } else { - if ((so = socreate()) == NULL) { - /* If it failed, get rid of the pending connection */ - closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); - return; - } - if (tcp_attach(so) < 0) { - free(so); /* NOT sofree */ - return; - } - so->so_laddr = inso->so_laddr; - so->so_lport = inso->so_lport; - } - - (void) tcp_mss(sototcpcb(so), 0); - - if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { - tcp_close(sototcpcb(so)); /* This will sofree() as well */ - return; - } - fd_nonblock(s); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); - - so->so_fport = addr.sin_port; - so->so_faddr = addr.sin_addr; - /* Translate connections from localhost to the real hostname */ - if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - - /* Close the accept() socket, set right state */ - if (inso->so_state & SS_FACCEPTONCE) { - closesocket(so->s); /* If we only accept once, close the accept() socket */ - so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ - /* if it's not FACCEPTONCE, it's already NOFDREF */ - } - so->s = s; - - so->so_iptos = tcp_tos(so); - tp = sototcpcb(so); - - tcp_template(tp); - - /* Compute window scaling to request. */ -/* while (tp->request_r_scale < TCP_MAX_WINSHIFT && - * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) - * tp->request_r_scale++; - */ - -/* soisconnecting(so); */ /* NOFDREF used instead */ - tcpstat.tcps_connattempt++; - - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tcp_sendseqinit(tp); - tcp_output(tp); -} - -/* - * Attach a TCPCB to a socket. - */ -int -tcp_attach(so) - struct SLIRPsocket *so; -{ - if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) - return -1; - - insque(so, &tcb); - - return 0; -} - -/* - * Set the socket's type of service field - */ -struct tos_t tcptos[] = { - {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ - {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ - {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ - {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ - {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ - {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ - {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ - {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ - {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ - {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ - {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ - {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ - {0, 0, 0, 0} -}; - -struct emu_t *tcpemu = 0; - -/* - * Return TOS according to the above table - */ -u_int8_t -tcp_tos(so) - struct SLIRPsocket *so; -{ - int i = 0; - struct emu_t *emup; - - while(tcptos[i].tos) { - if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || - (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { - so->so_emu = tcptos[i].emu; - return tcptos[i].tos; - } - i++; - } - - /* Nope, lets see if there's a user-added one */ - for (emup = tcpemu; emup; emup = emup->next) { - if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || - (emup->lport && (ntohs(so->so_lport) == emup->lport))) { - so->so_emu = emup->emu; - return emup->tos; - } - } - - return 0; -} - -int do_echo = -1; - -/* - * Emulate programs that try and connect to us - * This includes ftp (the data connection is - * initiated by the server) and IRC (DCC CHAT and - * DCC SEND) for now - * - * NOTE: It's possible to crash SLiRP by sending it - * unstandard strings to emulate... if this is a problem, - * more checks are needed here - * - * XXX Assumes the whole command came in one packet - * - * XXX Some ftp clients will have their TOS set to - * LOWDELAY and so Nagel will kick in. Because of this, - * we'll get the first letter, followed by the rest, so - * we simply scan for ORT instead of PORT... - * DCC doesn't have this problem because there's other stuff - * in the packet before the DCC command. - * - * Return 1 if the SLIRPmbuf m is still valid and should be - * sbappend()ed - * - * NOTE: if you return 0 you MUST m_free() the SLIRPmbuf! - */ -int -tcp_emu(so, m) - struct SLIRPsocket *so; - struct SLIRPmbuf *m; -{ - u_int n1, n2, n3, n4, n5, n6; - char buff[256]; - u_int32_t laddr; - u_int lport; - char *bptr; - - DEBUG_CALL("tcp_emu"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - - switch(so->so_emu) { - int x, i; - - case EMU_IDENT: - /* - * Identification protocol as per rfc-1413 - */ - - { - struct SLIRPsocket *tmpso; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - struct sbuf *so_rcv = &so->so_rcv; - - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m->m_data[m->m_len] = 0; /* NULL terminate */ - if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { - if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) { - HTONS(n1); - HTONS(n2); - /* n2 is the one on our host */ - for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { - if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && - tmpso->so_lport == n2 && - tmpso->so_faddr.s_addr == so->so_faddr.s_addr && - tmpso->so_fport == n1) { - if (getsockname(tmpso->s, - (struct sockaddr *)&addr, &addrlen) == 0) - n2 = ntohs(addr.sin_port); - break; - } - } - } - so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); - so_rcv->sb_rptr = so_rcv->sb_data; - so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; - } - m_free(m); - return 0; - } - -#if 0 - case EMU_RLOGIN: - /* - * Rlogin emulation - * First we accumulate all the initial option negotiation, - * then fork_exec() rlogin according to the options - */ - { - int i, i2, n; - char *ptr; - char args[100]; - char term[100]; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* First check if they have a priveladged port, or too much data has arrived */ - if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || - (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - m_free(m); - return 0; - } - - /* Append the current data */ - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m_free(m); - - /* - * Check if we have all the initial options, - * and build argument list to rlogin while we're here - */ - n = 0; - ptr = so_rcv->sb_data; - args[0] = 0; - term[0] = 0; - while (ptr < so_rcv->sb_wptr) { - if (*ptr++ == 0) { - n++; - if (n == 2) { - sprintf(args, "rlogin -l %s %s", - ptr, inet_ntoa(so->so_faddr)); - } else if (n == 3) { - i2 = so_rcv->sb_wptr - ptr; - for (i = 0; i < i2; i++) { - if (ptr[i] == '/') { - ptr[i] = 0; -#ifdef HAVE_SETENV - sprintf(term, "%s", ptr); -#else - sprintf(term, "TERM=%s", ptr); -#endif - ptr[i] = '/'; - break; - } - } - } - } - } - - if (n != 4) - return 0; - - /* We have it, set our term variable and fork_exec() */ -#ifdef HAVE_SETENV - setenv("TERM", term, 1); -#else - putenv(term); -#endif - fork_exec(so, args, 2); - term[0] = 0; - so->so_emu = 0; - - /* And finally, send the client a 0 character */ - so_snd->sb_wptr[0] = 0; - so_snd->sb_wptr++; - so_snd->sb_cc++; - - return 0; - } - - case EMU_RSH: - /* - * rsh emulation - * First we accumulate all the initial option negotiation, - * then rsh_exec() rsh according to the options - */ - { - int n; - char *ptr; - char *user; - char *args; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* First check if they have a priveladged port, or too much data has arrived */ - if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || - (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - m_free(m); - return 0; - } - - /* Append the current data */ - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m_free(m); - - /* - * Check if we have all the initial options, - * and build argument list to rlogin while we're here - */ - n = 0; - ptr = so_rcv->sb_data; - user=""; - args=""; - if (so->extra==NULL) { - struct SLIRPsocket *ns; - struct tcpcb* tp; - int port=atoi(ptr); - if (port <= 0) return 0; - if (port > 1023 || port < 512) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - return 0; - } - if ((ns=socreate()) == NULL) - return 0; - if (tcp_attach(ns)<0) { - free(ns); - return 0; - } - - ns->so_laddr=so->so_laddr; - ns->so_lport=htons(port); - - (void) tcp_mss(sototcpcb(ns), 0); - - ns->so_faddr=so->so_faddr; - ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ - - if (ns->so_faddr.s_addr == 0 || - ns->so_faddr.s_addr == loopback_addr.s_addr) - ns->so_faddr = alias_addr; - - ns->so_iptos = tcp_tos(ns); - tp = sototcpcb(ns); - - tcp_template(tp); - - /* Compute window scaling to request. */ - /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && - * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) - * tp->request_r_scale++; - */ - - /*soisfconnecting(ns);*/ - - tcpstat.tcps_connattempt++; - - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tcp_sendseqinit(tp); - tcp_output(tp); - so->extra=ns; - } - while (ptr < so_rcv->sb_wptr) { - if (*ptr++ == 0) { - n++; - if (n == 2) { - user=ptr; - } else if (n == 3) { - args=ptr; - } - } - } - - if (n != 4) - return 0; - - rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); - so->so_emu = 0; - so->extra=NULL; - - /* And finally, send the client a 0 character */ - so_snd->sb_wptr[0] = 0; - so_snd->sb_wptr++; - so_snd->sb_cc++; - - return 0; - } - - case EMU_CTL: - { - int num; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* - * If there is binary data here, we save it in so->so_m - */ - if (!so->so_m) { - int rxlen; - char *rxdata; - rxdata=mtod(m, char *); - for (rxlen=m->m_len; rxlen; rxlen--) { - if (*rxdata++ & 0x80) { - so->so_m = m; - return 0; - } - } - } /* if(so->so_m==NULL) */ - - /* - * Append the line - */ - sbappendsb(so_rcv, m); - - /* To avoid going over the edge of the buffer, we reset it */ - if (so_snd->sb_cc == 0) - so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; - - /* - * A bit of a hack: - * If the first packet we get here is 1 byte long, then it - * was done in telnet character mode, therefore we must echo - * the characters as they come. Otherwise, we echo nothing, - * because in linemode, the line is already echoed - * XXX two or more control connections won't work - */ - if (do_echo == -1) { - if (m->m_len == 1) do_echo = 1; - else do_echo = 0; - } - if (do_echo) { - sbappendsb(so_snd, m); - m_free(m); - tcp_output(sototcpcb(so)); /* XXX */ - } else - m_free(m); - - num = 0; - while (num < so->so_rcv.sb_cc) { - if (*(so->so_rcv.sb_rptr + num) == '\n' || - *(so->so_rcv.sb_rptr + num) == '\r') { - int n; - - *(so_rcv->sb_rptr + num) = 0; - if (ctl_password && !ctl_password_ok) { - /* Need a password */ - if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) { - if (strcmp(buff, ctl_password) == 0) { - ctl_password_ok = 1; - n = sprintf(so_snd->sb_wptr, - "Password OK.\r\n"); - goto do_prompt; - } - } - n = sprintf(so_snd->sb_wptr, - "Error: Password required, log on with \"pass PASSWORD\"\r\n"); - goto do_prompt; - } - cfg_quitting = 0; - n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF); - if (!cfg_quitting) { - /* Register the printed data */ -do_prompt: - so_snd->sb_cc += n; - so_snd->sb_wptr += n; - /* Add prompt */ - n = sprintf(so_snd->sb_wptr, "Slirp> "); - so_snd->sb_cc += n; - so_snd->sb_wptr += n; - } - /* Drop so_rcv data */ - so_rcv->sb_cc = 0; - so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data; - tcp_output(sototcpcb(so)); /* Send the reply */ - } - num++; - } - return 0; - } -#endif - case EMU_FTP: /* ftp */ - *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ - if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { - /* - * Need to emulate the PORT command - */ - x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", - &n1, &n2, &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) - return 1; - - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", - n1, n2, n3, n4, n5, n6, x==7?buff:""); - return 1; - } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { - /* - * Need to emulate the PASV response - */ - x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]", - &n1, &n2, &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) - return 1; - - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", - n1, n2, n3, n4, n5, n6, x==7?buff:""); - - return 1; - } - - return 1; - - case EMU_KSH: - /* - * The kshell (Kerberos rsh) and shell services both pass - * a local port port number to carry signals to the server - * and stderr to the client. It is passed at the beginning - * of the connection as a NUL-terminated decimal ASCII string. - */ - so->so_emu = 0; - for (lport = 0, i = 0; i < m->m_len-1; ++i) { - if (m->m_data[i] < '0' || m->m_data[i] > '9') - return 1; /* invalid number */ - lport *= 10; - lport += m->m_data[i] - '0'; - } - if (m->m_data[m->m_len-1] == '\0' && lport != 0 && - (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) - m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; - return 1; - - case EMU_IRC: - /* - * Need to emulate DCC CHAT, DCC SEND and DCC MOVE - */ - *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ - if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) - return 1; - - /* The %256s is for the broken mIRC */ - if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), 1); - } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", - buff, (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", - buff, (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } - return 1; - - case EMU_REALAUDIO: - /* - * RealAudio emulation - JP. We must try to parse the incoming - * data and try to find the two characters that contain the - * port number. Then we redirect an udp port and replace the - * number with the real port we got. - * - * The 1.0 beta versions of the player are not supported - * any more. - * - * A typical packet for player version 1.0 (release version): - * - * 0000:50 4E 41 00 05 - * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P - * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH - * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v - * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB - * - * Now the port number 0x1BD7 is found at offset 0x04 of the - * Now the port number 0x1BD7 is found at offset 0x04 of the - * second packet. This time we received five bytes first and - * then the rest. You never know how many bytes you get. - * - * A typical packet for player version 2.0 (beta): - * - * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. - * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 - * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ - * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas - * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B - * - * Port number 0x1BC1 is found at offset 0x0d. - * - * This is just a horrible switch statement. Variable ra tells - * us where we're going. - */ - - bptr = m->m_data; - while (bptr < m->m_data + m->m_len) { - u_short p; - static int ra = 0; - char ra_tbl[4]; - - ra_tbl[0] = 0x50; - ra_tbl[1] = 0x4e; - ra_tbl[2] = 0x41; - ra_tbl[3] = 0; - - switch (ra) { - case 0: - case 2: - case 3: - if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 1: - /* - * We may get 0x50 several times, ignore them - */ - if (*bptr == 0x50) { - ra = 1; - bptr++; - continue; - } else if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 4: - /* - * skip version number - */ - bptr++; - break; - - case 5: - /* - * The difference between versions 1.0 and - * 2.0 is here. For future versions of - * the player this may need to be modified. - */ - if (*(bptr + 1) == 0x02) - bptr += 8; - else - bptr += 4; - break; - - case 6: - /* This is the field containing the port - * number that RA-player is listening to. - */ - lport = (((u_char*)bptr)[0] << 8) - + ((u_char *)bptr)[1]; - if (lport < 6970) - lport += 256; /* don't know why */ - if (lport < 6970 || lport > 7170) - return 1; /* failed */ - - /* try to get udp port between 6970 - 7170 */ - for (p = 6970; p < 7071; p++) { - if (udp_listen( htons(p), - so->so_laddr.s_addr, - htons(lport), - SS_FACCEPTONCE)) { - break; - } - } - if (p == 7071) - p = 0; - *(u_char *)bptr++ = (p >> 8) & 0xff; - *(u_char *)bptr++ = p & 0xff; - ra = 0; - return 1; /* port redirected, we're done */ - break; - - default: - ra = 0; - } - ra++; - } - return 1; - - default: - /* Ooops, not emulated, won't call tcp_emu again */ - so->so_emu = 0; - return 1; - } -} - -/* - * Do misc. config of SLiRP while its running. - * Return 0 if this connections is to be closed, 1 otherwise, - * return 2 if this is a command-line connection - */ -int -tcp_ctl(so) - struct SLIRPsocket *so; -{ - struct sbuf *sb = &so->so_snd; - int command; - struct ex_list *ex_ptr; - int do_pty; - // struct SLIRPsocket *tmpso; - - DEBUG_CALL("tcp_ctl"); - DEBUG_ARG("so = %lx", (long )so); - -#if 0 - /* - * Check if they're authorised - */ - if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) { - sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); - sb->sb_wptr += sb->sb_cc; - return 0; - } -#endif - command = (ntohl(so->so_faddr.s_addr) & 0xff); - - switch(command) { - default: /* Check for exec's */ - - /* - * Check if it's pty_exec - */ - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - command == ex_ptr->ex_addr) { - do_pty = ex_ptr->ex_pty; - goto do_exec; - } - } - - /* - * Nothing bound.. - */ - /* tcp_fconnect(so); */ - - /* FALLTHROUGH */ - case CTL_ALIAS: - sb->sb_cc = sprintf(sb->sb_wptr, - "Error: No application configured.\r\n"); - sb->sb_wptr += sb->sb_cc; - return(0); - - do_exec: - DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); - return(fork_exec(so, ex_ptr->ex_exec, do_pty)); - -#if 0 - case CTL_CMD: - for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { - if (tmpso->so_emu == EMU_CTL && - !(tmpso->so_tcpcb? - (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) - :0)) { - /* Ooops, control connection already active */ - sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); - sb->sb_wptr += sb->sb_cc; - return 0; - } - } - so->so_emu = EMU_CTL; - ctl_password_ok = 0; - sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); - sb->sb_wptr += sb->sb_cc; - do_echo=-1; - return(2); -#endif - } -} diff --git a/src - Cópia/network/slirp/tcp_timer.c b/src - Cópia/network/slirp/tcp_timer.c deleted file mode 100644 index 892b222c7..000000000 --- a/src - Cópia/network/slirp/tcp_timer.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93 - * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp - */ - -#include "slirp.h" - -int tcp_keepidle = TCPTV_KEEP_IDLE; -int tcp_keepintvl = TCPTV_KEEPINTVL; -int tcp_maxidle; -int so_options = DO_KEEPALIVE; - -struct tcpstat tcpstat; /* tcp statistics */ -u_int32_t tcp_now; /* for RFC 1323 timestamps */ - -/* - * Fast timeout routine for processing delayed acks - */ -void -tcp_fasttimo() -{ - register struct SLIRPsocket *so; - register struct tcpcb *tp; - - DEBUG_CALL("tcp_fasttimo"); - - so = tcb.so_next; - if (so) - for (; so != &tcb; so = so->so_next) - if ((tp = (struct tcpcb *)so->so_tcpcb) && - (tp->t_flags & TF_DELACK)) { - tp->t_flags &= ~TF_DELACK; - tp->t_flags |= TF_ACKNOW; - tcpstat.tcps_delack++; - (void) tcp_output(tp); - } -} - -/* - * Tcp protocol timeout routine called every 500 ms. - * Updates the timers in all active tcb's and - * causes finite state machine actions if timers expire. - */ -void -tcp_slowtimo() -{ - register struct SLIRPsocket *ip, *ipnxt; - register struct tcpcb *tp; - register int i; - - DEBUG_CALL("tcp_slowtimo"); - - tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl; - /* - * Search through tcb's and update active timers. - */ - ip = tcb.so_next; - if (ip == 0) - return; - for (; ip != &tcb; ip = ipnxt) { - ipnxt = ip->so_next; - tp = sototcpcb(ip); - if (tp == 0) - continue; - for (i = 0; i < TCPT_NTIMERS; i++) { - if (tp->t_timer[i] && --tp->t_timer[i] == 0) { - tcp_timers(tp,i); - if (ipnxt->so_prev != ip) - goto tpgone; - } - } - tp->t_idle++; - if (tp->t_rtt) - tp->t_rtt++; -tpgone: - ; - } - tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ -#ifdef TCP_COMPAT_42 - if ((int)tcp_iss < 0) - tcp_iss = 0; /* XXX */ -#endif - tcp_now++; /* for timestamps */ -} - -/* - * Cancel all timers for TCP tp. - */ -void -tcp_canceltimers(tp) - struct tcpcb *tp; -{ - register int i; - - for (i = 0; i < TCPT_NTIMERS; i++) - tp->t_timer[i] = 0; -} - -int tcp_backoff[TCP_MAXRXTSHIFT + 1] = - { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; - -/* - * TCP timer processing. - */ -struct tcpcb * -tcp_timers(tp, timer) - struct tcpcb *tp; - int timer; -{ - int rexmt; - - DEBUG_CALL("tcp_timers"); - - switch (timer) { - - /* - * 2 MSL timeout in shutdown went off. If we're closed but - * still waiting for peer to close and connection has been idle - * too long, or if 2MSL time is up from TIME_WAIT, delete connection - * control block. Otherwise, check again in a bit. - */ - case TCPT_2MSL: - if (tp->t_state != TCPS_TIME_WAIT && - tp->t_idle <= tcp_maxidle) - tp->t_timer[TCPT_2MSL] = tcp_keepintvl; - else - tp = tcp_close(tp); - break; - - /* - * Retransmission timer went off. Message has not - * been acked within retransmit interval. Back off - * to a longer retransmit interval and retransmit one segment. - */ - case TCPT_REXMT: - - /* - * XXXXX If a packet has timed out, then remove all the queued - * packets for that session. - */ - - if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { - /* - * This is a hack to suit our terminal server here at the uni of canberra - * since they have trouble with zeroes... It usually lets them through - * unharmed, but under some conditions, it'll eat the zeros. If we - * keep retransmitting it, it'll keep eating the zeroes, so we keep - * retransmitting, and eventually the connection dies... - * (this only happens on incoming data) - * - * So, if we were gonna drop the connection from too many retransmits, - * don't... instead halve the t_maxseg, which might break up the NULLs and - * let them through - * - * *sigh* - */ - - tp->t_maxseg >>= 1; - if (tp->t_maxseg < 32) { - /* - * We tried our best, now the connection must die! - */ - tp->t_rxtshift = TCP_MAXRXTSHIFT; - tcpstat.tcps_timeoutdrop++; - tp = tcp_drop(tp, tp->t_softerror); - /* tp->t_softerror : ETIMEDOUT); */ /* XXX */ - return (tp); /* XXX */ - } - - /* - * Set rxtshift to 6, which is still at the maximum - * backoff time - */ - tp->t_rxtshift = 6; - } - tcpstat.tcps_rexmttimeo++; - rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; - TCPT_RANGESET(tp->t_rxtcur, rexmt, - (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * If losing, let the lower level know and try for - * a better route. Also, if we backed off this far, - * our srtt estimate is probably bogus. Clobber it - * so we'll take the next rtt measurement as our srtt; - * move the current srtt into rttvar to keep the current - * retransmit times until then. - */ - if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { -/* in_losing(tp->t_inpcb); */ - tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); - tp->t_srtt = 0; - } - tp->snd_nxt = tp->snd_una; - /* - * If timing a segment in this window, stop the timer. - */ - tp->t_rtt = 0; - /* - * Close the congestion window down to one segment - * (we'll open it by one segment for each ack we get). - * Since we probably have a window's worth of unacked - * data accumulated, this "slow start" keeps us from - * dumping all that data as back-to-back packets (which - * might overwhelm an intermediate gateway). - * - * There are two phases to the opening: Initially we - * open by one mss on each ack. This makes the window - * size increase exponentially with time. If the - * window is larger than the path can handle, this - * exponential growth results in dropped packet(s) - * almost immediately. To get more time between - * drops but still "push" the network to take advantage - * of improving conditions, we switch from exponential - * to linear window opening at some threshold size. - * For a threshold, we use half the current window - * size, truncated to a multiple of the mss. - * - * (the minimum cwnd that will give us exponential - * growth is 2 mss. We don't allow the threshold - * to go below this.) - */ - { - u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; - if (win < 2) - win = 2; - tp->snd_cwnd = tp->t_maxseg; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_dupacks = 0; - } - (void) tcp_output(tp); - break; - - /* - * Persistence timer into zero window. - * Force a byte to be output, if possible. - */ - case TCPT_PERSIST: - tcpstat.tcps_persisttimeo++; - tcp_setpersist(tp); - tp->t_force = 1; - (void) tcp_output(tp); - tp->t_force = 0; - break; - - /* - * Keep-alive timer went off; send something - * or drop connection if idle for too long. - */ - case TCPT_KEEP: - tcpstat.tcps_keeptimeo++; - if (tp->t_state < TCPS_ESTABLISHED) - goto dropit; - -/* if (tp->t_socket->so_options & SO_KEEPALIVE && */ - if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) { - if (tp->t_idle >= tcp_keepidle + tcp_maxidle) - goto dropit; - /* - * Send a packet designed to force a response - * if the peer is up and reachable: - * either an ACK if the connection is still alive, - * or an RST if the peer has closed the connection - * due to timeout or reboot. - * Using sequence number tp->snd_una-1 - * causes the transmitted zero-length segment - * to lie outside the receive window; - * by the protocol spec, this requires the - * correspondent TCP to respond. - */ - tcpstat.tcps_keepprobe++; -#ifdef TCP_COMPAT_42 - /* - * The keepalive packet must have nonzero length - * to get a 4.2 host to respond. - */ - tcp_respond(tp, &tp->t_template, (struct SLIRPmbuf *)NULL, - tp->rcv_nxt - 1, tp->snd_una - 1, 0); -#else - tcp_respond(tp, &tp->t_template, (struct SLIRPmbuf *)NULL, - tp->rcv_nxt, tp->snd_una - 1, 0); -#endif - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; - } else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; - break; - - dropit: - tcpstat.tcps_keepdrops++; - tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ - break; - } - - return (tp); -} diff --git a/src - Cópia/network/slirp/tcp_timer.h b/src - Cópia/network/slirp/tcp_timer.h deleted file mode 100644 index 0bc438c76..000000000 --- a/src - Cópia/network/slirp/tcp_timer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93 - * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp - */ - -#ifndef _TCP_TIMER_H_ -#define _TCP_TIMER_H_ - -/* - * Definitions of the TCP timers. These timers are counted - * down PR_SLOWHZ times a second. - */ -#define TCPT_NTIMERS 4 - -#define TCPT_REXMT 0 /* retransmit */ -#define TCPT_PERSIST 1 /* retransmit persistence */ -#define TCPT_KEEP 2 /* keep alive */ -#define TCPT_2MSL 3 /* 2*msl quiet time timer */ - -/* - * The TCPT_REXMT timer is used to force retransmissions. - * The TCP has the TCPT_REXMT timer set whenever segments - * have been sent for which ACKs are expected but not yet - * received. If an ACK is received which advances tp->snd_una, - * then the retransmit timer is cleared (if there are no more - * outstanding segments) or reset to the base value (if there - * are more ACKs expected). Whenever the retransmit timer goes off, - * we retransmit one unacknowledged segment, and do a backoff - * on the retransmit timer. - * - * The TCPT_PERSIST timer is used to keep window size information - * flowing even if the window goes shut. If all previous transmissions - * have been acknowledged (so that there are no retransmissions in progress), - * and the window is too small to bother sending anything, then we start - * the TCPT_PERSIST timer. When it expires, if the window is nonzero, - * we go to transmit state. Otherwise, at intervals send a single byte - * into the peer's window to force him to update our window information. - * We do this at most as often as TCPT_PERSMIN time intervals, - * but no more frequently than the current estimate of round-trip - * packet time. The TCPT_PERSIST timer is cleared whenever we receive - * a window update from the peer. - * - * The TCPT_KEEP timer is used to keep connections alive. If an - * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time, - * but not yet established, then we drop the connection. Once the connection - * is established, if the connection is idle for TCPTV_KEEP_IDLE time - * (and keepalives have been enabled on the socket), we begin to probe - * the connection. We force the peer to send us a segment by sending: - * - * This segment is (deliberately) outside the window, and should elicit - * an ack segment in response from the peer. If, despite the TCPT_KEEP - * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE - * amount of time probing, then we drop the connection. - */ - -/* - * Time constants. - */ -#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */ - -#define TCPTV_SRTTBASE 0 /* base roundtrip time; - if 0, no idea yet */ -#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */ - -#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */ -#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */ - -#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */ -#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */ -#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */ -#define TCPTV_KEEPCNT 8 /* max probes before drop */ - -#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */ -/* #define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) */ /* max allowable REXMT value */ -#define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */ - -#define TCP_LINGERTIME 120 /* linger at most 2 minutes */ - -#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ - - -#ifdef TCPTIMERS -char *tcptimers[] = - { "REXMT", "PERSIST", "KEEP", "2MSL" }; -#endif - -/* - * Force a time value to be in a certain range. - */ -#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \ - (tv) = (value); \ - if ((tv) < (tvmin)) \ - (tv) = (tvmin); \ - else if ((tv) > (tvmax)) \ - (tv) = (tvmax); \ -} - -extern int tcp_keepidle; /* time before keepalive probes begin */ -extern int tcp_keepintvl; /* time between keepalive probes */ -extern int tcp_maxidle; /* time to drop after starting probes */ -extern int tcp_ttl; /* time to live for TCP segs */ -extern int tcp_backoff[]; - -struct tcpcb; - -void tcp_fasttimo _P((void)); -void tcp_slowtimo _P((void)); -void tcp_canceltimers _P((struct tcpcb *)); -struct tcpcb * tcp_timers _P((register struct tcpcb *, int)); - -#endif diff --git a/src - Cópia/network/slirp/tcp_var.h b/src - Cópia/network/slirp/tcp_var.h deleted file mode 100644 index e6fbd3abb..000000000 --- a/src - Cópia/network/slirp/tcp_var.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94 - * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp - */ - -#ifndef _TCP_VAR_H_ -#define _TCP_VAR_H_ - -#include "tcpip.h" -#include "tcp_timer.h" - -#ifdef __amd64__ -typedef uintptr_t tcpiphdrp_32; -#else -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif -#endif - -/* - * Tcp control block, one per tcp; fields: - */ -struct tcpcb { - tcpiphdrp_32 seg_next; /* sequencing queue */ - tcpiphdrp_32 seg_prev; - short t_state; /* state of this connection */ - short t_timer[TCPT_NTIMERS]; /* tcp timers */ - short t_rxtshift; /* log(2) of rexmt exp. backoff */ - short t_rxtcur; /* current retransmit value */ - short t_dupacks; /* consecutive dup acks recd */ - u_short t_maxseg; /* maximum segment size */ - char t_force; /* 1 if forcing out a byte */ - u_short t_flags; -#define TF_ACKNOW 0x0001 /* ack peer immediately */ -#define TF_DELACK 0x0002 /* ack, but try to delay it */ -#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ -#define TF_NOOPT 0x0008 /* don't use tcp options */ -#define TF_SENTFIN 0x0010 /* have sent FIN */ -#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ -#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ -#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ -#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ -#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ - - /* Make it static for now */ -/* struct tcpiphdr *t_template; / * skeletal packet for transmit */ - struct tcpiphdr t_template; - - struct SLIRPsocket *t_socket; /* back pointer to socket */ -/* - * The following fields are used as in the protocol specification. - * See RFC783, Dec. 1981, page 21. - */ -/* send sequence variables */ - tcp_seq snd_una; /* send unacknowledged */ - tcp_seq snd_nxt; /* send next */ - tcp_seq snd_up; /* send urgent pointer */ - tcp_seq snd_wl1; /* window update seg seq number */ - tcp_seq snd_wl2; /* window update seg ack number */ - tcp_seq iss; /* initial send sequence number */ - u_int32_t snd_wnd; /* send window */ -/* receive sequence variables */ - u_int32_t rcv_wnd; /* receive window */ - tcp_seq rcv_nxt; /* receive next */ - tcp_seq rcv_up; /* receive urgent pointer */ - tcp_seq irs; /* initial receive sequence number */ -/* - * Additional variables for this implementation. - */ -/* receive variables */ - tcp_seq rcv_adv; /* advertised window */ -/* retransmit variables */ - tcp_seq snd_max; /* highest sequence number sent; - * used to recognize retransmits - */ -/* congestion control (for slow start, source quench, retransmit after loss) */ - u_int32_t snd_cwnd; /* congestion-controlled window */ - u_int32_t snd_ssthresh; /* snd_cwnd size threshold for - * for slow start exponential to - * linear switch - */ -/* - * transmit timing stuff. See below for scale of srtt and rttvar. - * "Variance" is actually smoothed difference. - */ - short t_idle; /* inactivity time */ - short t_rtt; /* round trip time */ - tcp_seq t_rtseq; /* sequence number being timed */ - short t_srtt; /* smoothed round-trip time */ - short t_rttvar; /* variance in round-trip time */ - u_short t_rttmin; /* minimum rtt allowed */ - u_int32_t max_sndwnd; /* largest window peer has offered */ - -/* out-of-band data */ - char t_oobflags; /* have some */ - char t_iobc; /* input character */ -#define TCPOOB_HAVEDATA 0x01 -#define TCPOOB_HADDATA 0x02 - short t_softerror; /* possible error not yet reported */ - -/* RFC 1323 variables */ - u_char snd_scale; /* window scaling for send window */ - u_char rcv_scale; /* window scaling for recv window */ - u_char request_r_scale; /* pending window scaling */ - u_char requested_s_scale; - u_int32_t ts_recent; /* timestamp echo data */ - u_int32_t ts_recent_age; /* when last updated */ - tcp_seq last_ack_sent; - -}; - -#define sototcpcb(so) ((so)->so_tcpcb) - -/* - * The smoothed round-trip time and estimated variance - * are stored as fixed point numbers scaled by the values below. - * For convenience, these scales are also used in smoothing the average - * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). - * With these scales, srtt has 3 bits to the right of the binary point, - * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the - * binary point, and is smoothed with an ALPHA of 0.75. - */ -#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ -#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ -#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ -#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ - -/* - * The initial retransmission should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - * This macro assumes that the value of TCP_RTTVAR_SCALE - * is the same as the multiplier for rttvar. - */ -#define TCP_REXMTVAL(tp) \ - (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) - -/* XXX - * We want to avoid doing m_pullup on incoming packets but that - * means avoiding dtom on the tcp reassembly code. That in turn means - * keeping an mbuf pointer in the reassembly queue (since we might - * have a cluster). As a quick hack, the source & destination - * port numbers (which are no longer needed once we've located the - * tcpcb) are overlayed with an mbuf pointer. - */ -#ifdef __amd64__ -typedef uintptr_t mbufp_32; -#else -#if SIZEOF_CHAR_P == 4 -typedef struct SLIRPmbuf *mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif -#endif -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - -/* - * TCP statistics. - * Many of these should be kept per connection, - * but that's inconvenient at the moment. - */ -struct tcpstat { - u_long tcps_connattempt; /* connections initiated */ - u_long tcps_accepts; /* connections accepted */ - u_long tcps_connects; /* connections established */ - u_long tcps_drops; /* connections dropped */ - u_long tcps_conndrops; /* embryonic connections dropped */ - u_long tcps_closed; /* conn. closed (includes drops) */ - u_long tcps_segstimed; /* segs where we tried to get rtt */ - u_long tcps_rttupdated; /* times we succeeded */ - u_long tcps_delack; /* delayed acks sent */ - u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */ - u_long tcps_rexmttimeo; /* retransmit timeouts */ - u_long tcps_persisttimeo; /* persist timeouts */ - u_long tcps_keeptimeo; /* keepalive timeouts */ - u_long tcps_keepprobe; /* keepalive probes sent */ - u_long tcps_keepdrops; /* connections dropped in keepalive */ - - u_long tcps_sndtotal; /* total packets sent */ - u_long tcps_sndpack; /* data packets sent */ - u_long tcps_sndbyte; /* data bytes sent */ - u_long tcps_sndrexmitpack; /* data packets retransmitted */ - u_long tcps_sndrexmitbyte; /* data bytes retransmitted */ - u_long tcps_sndacks; /* ack-only packets sent */ - u_long tcps_sndprobe; /* window probes sent */ - u_long tcps_sndurg; /* packets sent with URG only */ - u_long tcps_sndwinup; /* window update-only packets sent */ - u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */ - - u_long tcps_rcvtotal; /* total packets received */ - u_long tcps_rcvpack; /* packets received in sequence */ - u_long tcps_rcvbyte; /* bytes received in sequence */ - u_long tcps_rcvbadsum; /* packets received with ccksum errs */ - u_long tcps_rcvbadoff; /* packets received with bad offset */ -/* u_long tcps_rcvshort; */ /* packets received too short */ - u_long tcps_rcvduppack; /* duplicate-only packets received */ - u_long tcps_rcvdupbyte; /* duplicate-only bytes received */ - u_long tcps_rcvpartduppack; /* packets with some duplicate data */ - u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */ - u_long tcps_rcvoopack; /* out-of-order packets received */ - u_long tcps_rcvoobyte; /* out-of-order bytes received */ - u_long tcps_rcvpackafterwin; /* packets with data after window */ - u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */ - u_long tcps_rcvafterclose; /* packets rcvd after "close" */ - u_long tcps_rcvwinprobe; /* rcvd window probe packets */ - u_long tcps_rcvdupack; /* rcvd duplicate acks */ - u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */ - u_long tcps_rcvackpack; /* rcvd ack packets */ - u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */ - u_long tcps_rcvwinupd; /* rcvd window update packets */ -/* u_long tcps_pawsdrop; */ /* segments dropped due to PAWS */ - u_long tcps_predack; /* times hdr predict ok for acks */ - u_long tcps_preddat; /* times hdr predict ok for data pkts */ - u_long tcps_socachemiss; /* tcp_last_so misses */ - u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */ -}; - -extern struct tcpstat tcpstat; /* tcp statistics */ -extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ - -#endif diff --git a/src - Cópia/network/slirp/tcpip.h b/src - Cópia/network/slirp/tcpip.h deleted file mode 100644 index dff5a3c96..000000000 --- a/src - Cópia/network/slirp/tcpip.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 - * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp - */ - -#ifndef _TCPIP_H_ -#define _TCPIP_H_ - -/* - * Tcp+ip header, after ip options removed. - */ -struct tcpiphdr { - struct ipovly ti_i; /* overlaid ip structure */ - struct tcphdr ti_t; /* tcp header */ -}; -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev -#define ti_x1 ti_i.ih_x1 -#define ti_pr ti_i.ih_pr -#define ti_len ti_i.ih_len -#define ti_src ti_i.ih_src -#define ti_dst ti_i.ih_dst -#define ti_sport ti_t.th_sport -#define ti_dport ti_t.th_dport -#define ti_seq ti_t.th_seq -#define ti_ack ti_t.th_ack -#define ti_x2 ti_t.th_x2 -#define ti_off ti_t.th_off -#define ti_flags ti_t.th_flags -#define ti_win ti_t.th_win -#define ti_sum ti_t.th_sum -#define ti_urp ti_t.th_urp - -/* - * Just a clean way to get to the first byte - * of the packet - */ -struct tcpiphdr_2 { - struct tcpiphdr dummy; - char first_char; -}; - -#endif diff --git a/src - Cópia/network/slirp/tftp.c b/src - Cópia/network/slirp/tftp.c deleted file mode 100644 index b7b1ffb0a..000000000 --- a/src - Cópia/network/slirp/tftp.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * tftp.c - a simple, read-only tftp server for qemu - * - * Copyright (c) 2004 Magnus Damm - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "slirp.h" -#include "../ibm.h" - -struct tftp_session { - int in_use; - char filename[TFTP_FILENAME_MAX]; - - struct in_addr client_ip; - u_int16_t client_port; - - int timestamp; -}; - -struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; - -const char *tftp_prefix; - -static void tftp_session_update(struct tftp_session *spt) -{ - spt->timestamp = curtime; - spt->in_use = 1; -} - -static void tftp_session_terminate(struct tftp_session *spt) -{ - spt->in_use = 0; -} - -static int tftp_session_allocate(struct tftp_t *tp) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[k]; - - if (!spt->in_use) - goto found; - - /* sessions time out after 5 inactive seconds */ - if ((int)(curtime - spt->timestamp) > 5000) - goto found; - } - - return -1; - - found: - memset(spt, 0, sizeof(*spt)); - memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip)); - spt->client_port = tp->udp.uh_sport; - - tftp_session_update(spt); - - return k; -} - -static int tftp_session_find(struct tftp_t *tp) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[k]; - - if (spt->in_use) { - if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) { - if (spt->client_port == tp->udp.uh_sport) { - return k; - } - } - } - } - - return -1; -} - -static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, - u_int8_t *buf, int len) -{ - int fd; - int bytes_read = 0; - - char file_path[sizeof(pcempath) + 5 + sizeof(spt->filename)]; - strcpy(file_path, pcempath); - strcat(file_path, "tftp/"); - strcat(file_path, spt->filename); - - fd = open(file_path, O_RDONLY | O_BINARY); - - if (fd < 0) { - return -1; - } - - if (len) { - lseek(fd, block_nr * 512, SEEK_SET); - - bytes_read = read(fd, buf, len); - } - - close(fd); - - return bytes_read; -} - -static int tftp_send_error(struct tftp_session *spt, - u_int16_t errorcode, const char *msg, - struct tftp_t *recv_tp) -{ - struct sockaddr_in saddr, daddr; - struct SLIRPmbuf *m; - struct tftp_t *tp; - int nobytes; - - m = m_get(); - - if (!m) { - return -1; - } - - memset(m->m_data, 0, m->m_size); - - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - - tp->tp_op = htons(TFTP_ERROR); - tp->x.tp_error.tp_error_code = htons(errorcode); - strncpy((char *)tp->x.tp_error.tp_msg, msg, sizeof(tp->x.tp_error.tp_msg)); - tp->x.tp_error.tp_msg[sizeof(tp->x.tp_error.tp_msg)-1] = 0; - - saddr.sin_addr = recv_tp->ip.ip_dst; - saddr.sin_port = recv_tp->udp.uh_dport; - - daddr.sin_addr = spt->client_ip; - daddr.sin_port = spt->client_port; - - nobytes = 2; - - m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - - sizeof(struct ip) - sizeof(struct udphdr); - - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - - tftp_session_terminate(spt); - - return 0; -} - -static int tftp_send_data(struct tftp_session *spt, - u_int16_t block_nr, - struct tftp_t *recv_tp) -{ - struct sockaddr_in saddr, daddr; - struct SLIRPmbuf *m; - struct tftp_t *tp; - int nobytes; - - if (block_nr < 1) { - return -1; - } - - m = m_get(); - - if (!m) { - return -1; - } - - memset(m->m_data, 0, m->m_size); - - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - - tp->tp_op = htons(TFTP_DATA); - tp->x.tp_data.tp_block_nr = htons(block_nr); - - saddr.sin_addr = recv_tp->ip.ip_dst; - saddr.sin_port = recv_tp->udp.uh_dport; - - daddr.sin_addr = spt->client_ip; - daddr.sin_port = spt->client_port; - - nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512); - - if (nobytes < 0) { - m_free(m); - - /* send "file not found" error back */ - - tftp_send_error(spt, 1, "File not found", tp); - - return -1; - } - - m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - - sizeof(struct ip) - sizeof(struct udphdr); - - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - - if (nobytes == 512) { - tftp_session_update(spt); - } - else { - tftp_session_terminate(spt); - } - - return 0; -} - -static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) -{ - struct tftp_session *spt; - int s, k, n; - u_int8_t *src, *dst; - - s = tftp_session_allocate(tp); - - if (s < 0) { - return; - } - - spt = &tftp_sessions[s]; - - src = tp->x.tp_buf; - dst = (u_int8_t *)spt->filename; - n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp); - - /* get name */ - - for (k = 0; k < n; k++) { - if (k < TFTP_FILENAME_MAX) { - dst[k] = src[k]; - } - else { - return; - } - - if (src[k] == '\0') { - break; - } - } - - if (k >= n) { - return; - } - - k++; - - /* check mode */ - if ((n - k) < 6) { - return; - } - - if (memcmp(&src[k], "octet\0", 6) != 0) { - tftp_send_error(spt, 4, "Unsupported transfer mode", tp); - return; - } - - pclog("tftp request: %s\n", spt->filename); - - /* do sanity checks on the filename */ - - if (strstr(spt->filename, "../") || strstr(spt->filename, "..\\")) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - /* check if the file exists */ - - if (tftp_read_data(spt, 0, (u_int8_t *)spt->filename, 0) < 0) { - tftp_send_error(spt, 1, "File not found", tp); - return; - } - - tftp_send_data(spt, 1, tp); -} - -static void tftp_handle_ack(struct tftp_t *tp, int pktlen) -{ - int s; - - s = tftp_session_find(tp); - - if (s < 0) { - return; - } - - if (tftp_send_data(&tftp_sessions[s], - ntohs(tp->x.tp_data.tp_block_nr) + 1, - tp) < 0) { - return; - } -} - -void tftp_input(struct SLIRPmbuf *m) -{ - struct tftp_t *tp = (struct tftp_t *)m->m_data; - - switch(ntohs(tp->tp_op)) { - case TFTP_RRQ: - tftp_handle_rrq(tp, m->m_len); - break; - - case TFTP_ACK: - tftp_handle_ack(tp, m->m_len); - break; - } -} diff --git a/src - Cópia/network/slirp/tftp.h b/src - Cópia/network/slirp/tftp.h deleted file mode 100644 index ba4174115..000000000 --- a/src - Cópia/network/slirp/tftp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* tftp defines */ - -#define TFTP_SESSIONS_MAX 3 - -#define TFTP_SERVER 69 - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 - -#define TFTP_FILENAME_MAX 512 - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct tftp_t { - struct ip ip; - struct udphdr udp; - u_int16_t tp_op; - union { - struct { - u_int16_t tp_block_nr; - u_int8_t tp_buf[512]; - } tp_data; - struct { - u_int16_t tp_error_code; - u_int8_t tp_msg[512]; - } tp_error; - u_int8_t tp_buf[512 + 2]; - } x; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -void tftp_input(struct SLIRPmbuf *m); diff --git a/src - Cópia/network/slirp/udp.c b/src - Cópia/network/slirp/udp.c deleted file mode 100644 index f847c51a4..000000000 --- a/src - Cópia/network/slirp/udp.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 - * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#ifndef _WIN32 -# include -#endif -#include "slirp.h" -#include "ip_icmp.h" - -struct udpstat udpstat; - -struct SLIRPsocket udb; - -/* - * UDP protocol implementation. - * Per RFC 768, August, 1980. - */ -#ifndef COMPAT_42 -int udpcksum = 1; -#else -int udpcksum = 0; /* XXX */ -#endif - -struct SLIRPsocket *udp_last_so = &udb; - -void -udp_init() -{ - udb.so_next = udb.so_prev = &udb; -} -/* m->m_data points at ip packet header - * m->m_len length ip packet - * ip->ip_len length data (IPDU) - */ -void -udp_input(m, iphlen) - struct SLIRPmbuf *m; - int iphlen; -{ - struct ip *ip; - struct udphdr *uh; -/* struct SLIRPmbuf *opts = 0;*/ - int len; - struct ip save_ip; - struct SLIRPsocket *so; - - DEBUG_CALL("udp_input"); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("iphlen = %d", iphlen); - - udpstat.udps_ipackets++; - - /* - * Strip IP options, if any; should skip this, - * make available to user, and use on returned packets, - * but we don't yet have a way to check the checksum - * with options still present. - */ - if(iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct SLIRPmbuf *)0); - iphlen = sizeof(struct ip); - } - - /* - * Get IP and UDP header together in first SLIRPmbuf. - */ - ip = mtod(m, struct ip *); - uh = (struct udphdr *)((SLIRPcaddr_t)ip + iphlen); - - /* - * Make SLIRPmbuf data length reflect UDP length. - * If not enough data to reflect UDP length, drop. - */ - len = ntohs((u_int16_t)uh->uh_ulen); - - if (ip->ip_len != len) { - if (len > ip->ip_len) { - udpstat.udps_badlen++; - goto bad; - } - m_adj(m, len - ip->ip_len); - ip->ip_len = len; - } - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip = *ip; - save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ - - /* - * Checksum extended UDP header and data. - */ - if (udpcksum && uh->uh_sum) { - ((struct ipovly *)ip)->ih_next = 0; - ((struct ipovly *)ip)->ih_prev = 0; - ((struct ipovly *)ip)->ih_x1 = 0; - ((struct ipovly *)ip)->ih_len = uh->uh_ulen; - /* keep uh_sum for ICMP reply - * uh->uh_sum = cksum(m, len + sizeof (struct ip)); - * if (uh->uh_sum) { - */ - if(cksum(m, len + sizeof(struct ip))) { - udpstat.udps_badsum++; - goto bad; - } - } - - /* - * handle DHCP/BOOTP - */ - if (ntohs(uh->uh_dport) == BOOTP_SERVER) { - bootp_input(m); - goto bad; - } - -#ifdef NEED_TFTP - /* - * handle TFTP - */ - if (ntohs(uh->uh_dport) == TFTP_SERVER) { - tftp_input(m); - goto bad; - } -#endif - - /* - * Locate pcb for datagram. - */ - so = udp_last_so; - if (so->so_lport != uh->uh_sport || - so->so_laddr.s_addr != ip->ip_src.s_addr) { - struct SLIRPsocket *tmp; - - for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { - if (tmp->so_lport == uh->uh_sport && - tmp->so_laddr.s_addr == ip->ip_src.s_addr) { - tmp->so_faddr.s_addr = ip->ip_dst.s_addr; - tmp->so_fport = uh->uh_dport; - so = tmp; - break; - } - } - if (tmp == &udb) { - so = NULL; - } else { - udpstat.udpps_pcbcachemiss++; - udp_last_so = so; - } - } - - if (so == NULL) { - /* - * If there's no socket for this packet, - * create one - */ - if ((so = socreate()) == NULL) goto bad; - if(udp_attach(so) == -1) { - DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", - errno,strerror(errno))); - sofree(so); - goto bad; - } - - /* - * Setup fields - */ - /* udp_last_so = so; */ - so->so_laddr = ip->ip_src; - so->so_lport = uh->uh_sport; - - if ((so->so_iptos = udp_tos(so)) == 0) - so->so_iptos = ip->ip_tos; - - /* - * XXXXX Here, check if it's in udpexec_list, - * and if it is, do the fork_exec() etc. - */ - } - - so->so_faddr = ip->ip_dst; /* XXX */ - so->so_fport = uh->uh_dport; /* XXX */ - - iphlen += sizeof(struct udphdr); - m->m_len -= iphlen; - m->m_data += iphlen; - - /* - * Now we sendto() the packet. - */ - if (so->so_emu) - udp_emu(so, m); - - if(sosendto(so,m) == -1) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip=save_ip; - DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); - } - - m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ - - /* restore the orig SLIRPmbuf packet */ - m->m_len += iphlen; - m->m_data -= iphlen; - *ip=save_ip; - so->so_m=m; /* ICMP backup */ - - return; -bad: - m_freem(m); - /* if (opts) m_freem(opts); */ - return; -} - -int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, - struct sockaddr_in *saddr, struct sockaddr_in *daddr, - int iptos) -{ - struct udpiphdr *ui; - int error = 0; - - DEBUG_CALL("udp_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr); - DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr); - - /* - * Adjust for header - */ - m->m_data -= sizeof(struct udpiphdr); - m->m_len += sizeof(struct udpiphdr); - - /* - * Fill in SLIRPmbuf with extended UDP header - * and addresses and length put into network format. - */ - ui = mtod(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; - ui->ui_x1 = 0; - ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ - /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ - ui->ui_src = saddr->sin_addr; - ui->ui_dst = daddr->sin_addr; - ui->ui_sport = saddr->sin_port; - ui->ui_dport = daddr->sin_port; - ui->ui_ulen = ui->ui_len; - - /* - * Stuff checksum and output datagram. - */ - ui->ui_sum = 0; - if (udpcksum) { - if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) - ui->ui_sum = 0xffff; - } - ((struct ip *)ui)->ip_len = m->m_len; - - ((struct ip *)ui)->ip_ttl = ip_defttl; - ((struct ip *)ui)->ip_tos = iptos; - - udpstat.udps_opackets++; - - error = ip_output(so, m); - - return (error); -} - -int udp_output(struct SLIRPsocket *so, struct SLIRPmbuf *m, - struct sockaddr_in *addr) - -{ - struct sockaddr_in saddr, daddr; - - saddr = *addr; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - saddr.sin_addr.s_addr = so->so_faddr.s_addr; - if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff)) - saddr.sin_addr.s_addr = alias_addr.s_addr; - } - daddr.sin_addr = so->so_laddr; - daddr.sin_port = so->so_lport; - - return udp_output2(so, m, &saddr, &daddr, so->so_iptos); -} - -int -udp_attach(so) - struct SLIRPsocket *so; -{ - struct sockaddr_in addr; - - if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) { - /* - * Here, we bind() the socket. Although not really needed - * (sendto() on an unbound socket will bind it), it's done - * here so that emulation of ytalk etc. don't have to do it - */ - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = INADDR_ANY; - if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { - int lasterrno=errno; - closesocket(so->s); - so->s=-1; -#ifdef _WIN32 - WSASetLastError(lasterrno); -#else - errno=lasterrno; -#endif - } else { - /* success, insert in queue */ - so->so_expire = curtime + SO_EXPIRE; - insque(so,&udb); - } - } - return(so->s); -} - -void -udp_detach(so) - struct SLIRPsocket *so; -{ - closesocket(so->s); - /* if (so->so_m) m_free(so->so_m); done by sofree */ - - sofree(so); -} - -struct tos_t udptos[] = { - {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */ - {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */ - {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */ - {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */ - {0, 0, 0, 0} -}; - -u_int8_t -udp_tos(so) - struct SLIRPsocket *so; -{ - int i = 0; - - while(udptos[i].tos) { - if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || - (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { - so->so_emu = udptos[i].emu; - return udptos[i].tos; - } - i++; - } - - return 0; -} - -#ifdef EMULATE_TALK -#include "talkd.h" -#endif - -/* - * Here, talk/ytalk/ntalk requests must be emulated - */ -void -udp_emu(so, m) - struct SLIRPsocket *so; - struct SLIRPmbuf *m; -{ - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); -#ifdef EMULATE_TALK - CTL_MSG_OLD *omsg; - CTL_MSG *nmsg; - char buff[sizeof(CTL_MSG)]; - u_char type; - -struct talk_request { - struct talk_request *next; - struct SLIRPsocket *udp_so; - struct SLIRPsocket *tcp_so; -} *req; - - static struct talk_request *req_tbl = 0; - -#endif - -struct cu_header { - uint16_t d_family; // destination family - uint16_t d_port; // destination port - uint32_t d_addr; // destination address - uint16_t s_family; // source family - uint16_t s_port; // source port - uint32_t so_addr; // source address - uint32_t seqn; // sequence number - uint16_t message; // message - uint16_t data_type; // data type - uint16_t pkt_len; // packet length -} *cu_head; - - switch(so->so_emu) { - -#ifdef EMULATE_TALK - case EMU_TALK: - case EMU_NTALK: - /* - * Talk emulation. We always change the ctl_addr to get - * some answers from the daemon. When an ANNOUNCE comes, - * we send LEAVE_INVITE to the local daemons. Also when a - * DELETE comes, we send copies to the local daemons. - */ - if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) - return; - -#define IS_OLD (so->so_emu == EMU_TALK) - -#define COPY_MSG(dest, src) { dest->type = src->type; \ - dest->id_num = src->id_num; \ - dest->pid = src->pid; \ - dest->addr = src->addr; \ - dest->ctl_addr = src->ctl_addr; \ - memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ - memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ - memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } - -#define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) -/* old_sockaddr to sockaddr_in */ - - - if (IS_OLD) { /* old talk */ - omsg = mtod(m, CTL_MSG_OLD*); - nmsg = (CTL_MSG *) buff; - type = omsg->type; - OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; - OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; - strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); - } else { /* new talk */ - omsg = (CTL_MSG_OLD *) buff; - nmsg = mtod(m, CTL_MSG *); - type = nmsg->type; - OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; - OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; - strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); - } - - if (type == LOOK_UP) - return; /* for LOOK_UP this is enough */ - - if (IS_OLD) { /* make a copy of the message */ - COPY_MSG(nmsg, omsg); - nmsg->vers = 1; - nmsg->answer = 0; - } else - COPY_MSG(omsg, nmsg); - - /* - * If if is an ANNOUNCE message, we go through the - * request table to see if a tcp port has already - * been redirected for this socket. If not, we solisten() - * a new socket and add this entry to the table. - * The port number of the tcp socket and our IP - * are put to the addr field of the message structures. - * Then a LEAVE_INVITE is sent to both local daemon - * ports, 517 and 518. This is why we have two copies - * of the message, one in old talk and one in new talk - * format. - */ - - if (type == ANNOUNCE) { - int s; - u_short temp_port; - - for(req = req_tbl; req; req = req->next) - if (so == req->udp_so) - break; /* found it */ - - if (!req) { /* no entry for so, create new */ - req = (struct talk_request *) - malloc(sizeof(struct talk_request)); - req->udp_so = so; - req->tcp_so = solisten(0, - OTOSIN(omsg, addr)->sin_addr.s_addr, - OTOSIN(omsg, addr)->sin_port, - SS_FACCEPTONCE); - req->next = req_tbl; - req_tbl = req; - } - - /* replace port number in addr field */ - addrlen = sizeof(addr); - getsockname(req->tcp_so->s, - (struct sockaddr *) &addr, - &addrlen); - OTOSIN(omsg, addr)->sin_port = addr.sin_port; - OTOSIN(omsg, addr)->sin_addr = our_addr; - OTOSIN(nmsg, addr)->sin_port = addr.sin_port; - OTOSIN(nmsg, addr)->sin_addr = our_addr; - - /* send LEAVE_INVITEs */ - temp_port = OTOSIN(omsg, ctl_addr)->sin_port; - OTOSIN(omsg, ctl_addr)->sin_port = 0; - OTOSIN(nmsg, ctl_addr)->sin_port = 0; - omsg->type = nmsg->type = LEAVE_INVITE; - - s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - addr.sin_addr = our_addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(517); - sendto(s, (char *)omsg, sizeof(*omsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - addr.sin_port = htons(518); - sendto(s, (char *)nmsg, sizeof(*nmsg), 0, - (struct sockaddr *) &addr, sizeof(addr)); - closesocket(s) ; - - omsg->type = nmsg->type = ANNOUNCE; - OTOSIN(omsg, ctl_addr)->sin_port = temp_port; - OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; - } - - /* - * If it is a DELETE message, we send a copy to the - * local daemons. Then we delete the entry corresponding - * to our socket from the request table. - */ - - if (type == DELETE) { - struct talk_request *temp_req, *req_next; - int s; - u_short temp_port; - - temp_port = OTOSIN(omsg, ctl_addr)->sin_port; - OTOSIN(omsg, ctl_addr)->sin_port = 0; - OTOSIN(nmsg, ctl_addr)->sin_port = 0; - - s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - addr.sin_addr = our_addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(517); - sendto(s, (char *)omsg, sizeof(*omsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - addr.sin_port = htons(518); - sendto(s, (char *)nmsg, sizeof(*nmsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - closesocket(s); - - OTOSIN(omsg, ctl_addr)->sin_port = temp_port; - OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; - - /* delete table entry */ - if (so == req_tbl->udp_so) { - temp_req = req_tbl; - req_tbl = req_tbl->next; - free(temp_req); - } else { - temp_req = req_tbl; - for(req = req_tbl->next; req; req = req_next) { - req_next = req->next; - if (so == req->udp_so) { - temp_req->next = req_next; - free(req); - break; - } else { - temp_req = req; - } - } - } - } - - return; -#endif - - case EMU_CUSEEME: - - /* - * Cu-SeeMe emulation. - * Hopefully the packet is more that 16 bytes long. We don't - * do any other tests, just replace the address and port - * fields. - */ - if (m->m_len >= sizeof (*cu_head)) { - if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) - return; - cu_head = mtod(m, struct cu_header *); - cu_head->s_port = addr.sin_port; - cu_head->so_addr = our_addr.s_addr; - } - - return; - } -} - -struct SLIRPsocket * -udp_listen(port, laddr, lport, flags) - u_int port; - u_int32_t laddr; - u_int lport; - int flags; -{ - struct sockaddr_in addr; - struct SLIRPsocket *so; - socklen_t addrlen = sizeof(struct sockaddr_in); - int opt = 1; - - if ((so = socreate()) == NULL) { - free(so); - return NULL; - } - so->s = socket(AF_INET,SOCK_DGRAM,0); - so->so_expire = curtime + SO_EXPIRE; - insque(so,&udb); - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; - - if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) { - udp_detach(so); - return NULL; - } - setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); -/* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ - - getsockname(so->s,(struct sockaddr *)&addr,&addrlen); - so->so_fport = addr.sin_port; - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - else - so->so_faddr = addr.sin_addr; - - so->so_lport = lport; - so->so_laddr.s_addr = laddr; - if (flags != SS_FACCEPTONCE) - so->so_expire = 0; - - so->so_state = SS_ISFCONNECTED; - - return so; -} diff --git a/src - Cópia/network/slirp/udp.h b/src - Cópia/network/slirp/udp.h deleted file mode 100644 index 2f6b1e483..000000000 --- a/src - Cópia/network/slirp/udp.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)udp.h 8.1 (Berkeley) 6/10/93 - * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp - */ - -#ifndef _UDP_H_ -#define _UDP_H_ - -#define UDP_TTL 0x60 -#define UDP_UDPDATALEN 16192 - -extern struct SLIRPsocket *udp_last_so; - -/* - * Udp protocol header. - * Per RFC 768, September, 1981. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct udphdr { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -/* - * UDP kernel structures and variables. - */ -struct udpiphdr { - struct ipovly ui_i; /* overlaid ip structure */ - struct udphdr ui_u; /* udp header */ -}; -#define ui_next ui_i.ih_next -#define ui_prev ui_i.ih_prev -#define ui_x1 ui_i.ih_x1 -#define ui_pr ui_i.ih_pr -#define ui_len ui_i.ih_len -#define ui_src ui_i.ih_src -#define ui_dst ui_i.ih_dst -#define ui_sport ui_u.uh_sport -#define ui_dport ui_u.uh_dport -#define ui_ulen ui_u.uh_ulen -#define ui_sum ui_u.uh_sum - -struct udpstat { - /* input statistics: */ - u_long udps_ipackets; /* total input packets */ - u_long udps_hdrops; /* packet shorter than header */ - u_long udps_badsum; /* checksum error */ - u_long udps_badlen; /* data length larger than packet */ - u_long udps_noport; /* no socket on port */ - u_long udps_noportbcast; /* of above, arrived as broadcast */ - u_long udps_fullsock; /* not delivered, input socket full */ - u_long udpps_pcbcachemiss; /* input packets missing pcb cache */ - /* output statistics: */ - u_long udps_opackets; /* total output packets */ -}; - -/* - * Names for UDP sysctl objects - */ -#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ -#define UDPCTL_MAXID 2 - -extern struct udpstat udpstat; -extern struct SLIRPsocket udb; -struct SLIRPmbuf; - -void udp_init _P((void)); -void udp_input _P((register struct SLIRPmbuf *, int)); -int udp_output _P((struct SLIRPsocket *, struct SLIRPmbuf *, struct sockaddr_in *)); -int udp_attach _P((struct SLIRPsocket *)); -void udp_detach _P((struct SLIRPsocket *)); -u_int8_t udp_tos _P((struct SLIRPsocket *)); -void udp_emu _P((struct SLIRPsocket *, struct SLIRPmbuf *)); -struct SLIRPsocket * udp_listen _P((u_int, u_int32_t, u_int, int)); -int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, - struct sockaddr_in *saddr, struct sockaddr_in *daddr, - int iptos); -#endif diff --git a/src - Cópia/nmi.c b/src - Cópia/nmi.c deleted file mode 100644 index e00061d0c..000000000 --- a/src - Cópia/nmi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "io.h" -#include "nmi.h" - - -int nmi_mask; - - -void nmi_write(uint16_t port, uint8_t val, void *p) -{ - nmi_mask = val & 0x80; -} - - -void nmi_init(void) -{ - io_sethandler(0x00a0, 0x0001, NULL, NULL, NULL, nmi_write, NULL, NULL, NULL); - nmi_mask = 0; -} diff --git a/src - Cópia/nmi.h b/src - Cópia/nmi.h deleted file mode 100644 index e5e7c891d..000000000 --- a/src - Cópia/nmi.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern int nmi_mask; -extern int nmi; -extern int nmi_auto_clear; - - -extern void nmi_init(void); -extern void nmi_write(uint16_t port, uint8_t val, void *p); diff --git a/src - Cópia/nvr.c b/src - Cópia/nvr.c deleted file mode 100644 index 2f38445b9..000000000 --- a/src - Cópia/nvr.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 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. - * - * Implement a generic NVRAM/CMOS/RTC device. - * - * Version: @(#)nvr.c 1.0.9 2018/04/29 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "device.h" -#include "machine/machine.h" -#include "machine/m_xt_t1000.h" -#include "mem.h" -#include "pic.h" -#include "pit.h" -#include "rom.h" -#include "timer.h" -#include "plat.h" -#include "nvr.h" - - -int nvr_dosave; /* NVR is dirty, needs saved */ - - -static int8_t days_in_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; -static struct tm intclk; -static nvr_t *saved_nvr = NULL; - - -#ifdef ENABLE_NVR_LOG -int nvr_do_log = ENABLE_NVR_LOG; -#endif - - -static void -nvr_log(const char *format, ...) -{ -#ifdef ENABLE_NVR_LOG - va_list ap; - - if (nvr_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Determine whether or not the year is leap. */ -int -nvr_is_leap(int year) -{ - if (year % 400 == 0) return(1); - if (year % 100 == 0) return(0); - if (year % 4 == 0) return(1); - - return(0); -} - - -/* Determine the days in the current month. */ -int -nvr_get_days(int month, int year) -{ - if (month != 2) - return(days_in_month[month - 1]); - - return(nvr_is_leap(year) ? 29 : 28); -} - - -/* One more second has passed, update the internal clock. */ -static void -rtc_tick(void) -{ - /* Ping the internal clock. */ - if (++intclk.tm_sec == 60) { - intclk.tm_sec = 0; - if (++intclk.tm_min == 60) { - intclk.tm_min = 0; - if (++intclk.tm_hour == 24) { - intclk.tm_hour = 0; - if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon, - intclk.tm_year) + 1)) { - intclk.tm_mday = 1; - intclk.tm_mon++; - if (++intclk.tm_mon == 13) { - intclk.tm_mon = 1; - intclk.tm_year++; - } - } - } - } - } -} - - -/* This is the RTC one-second timer. */ -static void -onesec_timer(void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - - if (++nvr->onesec_cnt >= 100) { - /* Update the internal clock. */ - rtc_tick(); - - /* Update the RTC device if needed. */ - if (nvr->tick != NULL) - (*nvr->tick)(nvr); - - nvr->onesec_cnt = 0; - } - - nvr->onesec_time += (int64_t)(10000 * TIMER_USEC); -} - - -/* Initialize the generic NVRAM/RTC device. */ -void -nvr_init(nvr_t *nvr) -{ - char temp[64]; - struct tm *tm; - time_t now; - int c; - - /* Set up the NVR file's name. */ - sprintf(temp, "%s.nvr", machine_get_internal_name()); - c = strlen(temp); - nvr->fn = (wchar_t *)malloc((c + 1) * sizeof(wchar_t)); - mbstowcs(nvr->fn, temp, c + 1); - - /* Initialize the internal clock as needed. */ - memset(&intclk, 0x00, sizeof(intclk)); - if (enable_sync) { - /* Get the current time of day, and convert to local time. */ - (void)time(&now); - tm = localtime(&now); - - /* Set the internal clock. */ - nvr_time_set(tm); - } else { - /* Reset the internal clock to 1980/01/01 00:00. */ - intclk.tm_mon = 1; - intclk.tm_year = 1980; - } - - /* Set up our timer. */ - timer_add(onesec_timer, &nvr->onesec_time, TIMER_ALWAYS_ENABLED, nvr); - - /* It does not need saving yet. */ - nvr_dosave = 0; - - /* Save the NVR data pointer. */ - saved_nvr = nvr; - - /* Try to load the saved data. */ - (void)nvr_load(); -} - - -/* Get path to the NVR folder. */ -wchar_t * -nvr_path(wchar_t *str) -{ - static wchar_t temp[1024]; - - /* Get the full prefix in place. */ - memset(temp, 0x00, sizeof(temp)); - wcscpy(temp, usr_path); - wcscat(temp, NVR_PATH); - - /* Create the directory if needed. */ - if (! plat_dir_check(temp)) - plat_dir_create(temp); - - /* Now append the actual filename. */ - plat_path_slash(temp); - wcscat(temp, str); - - return(temp); -} - - -/* - * Load an NVR from file. - * - * This function does two things, really. It clears and initializes - * the RTC and NVRAM areas, sets up defaults for the RTC part, and - * then attempts to load data from a saved file. - * - * Either way, after that, it will continue to configure the local - * RTC to operate, so it can update either the local RTC, and/or - * the one supplied by a client. - */ -int -nvr_load(void) -{ - wchar_t *path; - FILE *fp; - - /* Make sure we have been initialized. */ - if (saved_nvr == NULL) return(0); - - /* Clear out any old data. */ - memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs)); - - /* Set the defaults. */ - if (saved_nvr->reset != NULL) - saved_nvr->reset(saved_nvr); - - /* Load the (relevant) part of the NVR contents. */ - if (saved_nvr->size != 0) { - path = nvr_path(saved_nvr->fn); - nvr_log("NVR: loading from '%ls'\n", path); - fp = plat_fopen(path, L"rb"); - if (fp != NULL) { - /* Read NVR contents from file. */ - (void)fread(saved_nvr->regs, saved_nvr->size, 1, fp); - (void)fclose(fp); - } - } - - if (romset == ROM_T1000) - t1000_nvr_load(); - else if (romset == ROM_T1200) - t1200_nvr_load(); - - /* Get the local RTC running! */ - if (saved_nvr->start != NULL) - saved_nvr->start(saved_nvr); - - return(1); -} - - -/* Save the current NVR to a file. */ -int -nvr_save(void) -{ - wchar_t *path; - FILE *fp; - - /* Make sure we have been initialized. */ - if (saved_nvr == NULL) return(0); - - if (saved_nvr->size != 0) { - path = nvr_path(saved_nvr->fn); - nvr_log("NVR: saving to '%ls'\n", path); - fp = plat_fopen(path, L"wb"); - if (fp != NULL) { - /* Save NVR contents to file. */ - (void)fwrite(saved_nvr->regs, saved_nvr->size, 1, fp); - fclose(fp); - } - } - - if (romset == ROM_T1000) - t1000_nvr_save(); - else if (romset == ROM_T1200) - t1200_nvr_save(); - - /* Device is clean again. */ - nvr_dosave = 0; - - return(1); -} - - -void -nvr_period_recalc(void) -{ - /* Make sure we have been initialized. */ - if (saved_nvr == NULL) return; - - if (saved_nvr->size != 0) - saved_nvr->recalc(saved_nvr); -} - - -/* Get current time from internal clock. */ -void -nvr_time_get(struct tm *tm) -{ - uint8_t dom, mon, sum, wd; - uint16_t cent, yr; - - tm->tm_sec = intclk.tm_sec; - tm->tm_min = intclk.tm_min; - tm->tm_hour = intclk.tm_hour; - dom = intclk.tm_mday; - mon = intclk.tm_mon; - yr = (intclk.tm_year % 100); - cent = ((intclk.tm_year - yr) / 100) % 4; - sum = dom+mon+yr+cent; - wd = ((sum + 6) % 7); - tm->tm_wday = wd; - tm->tm_mday = intclk.tm_mday; - tm->tm_mon = (intclk.tm_mon - 1); - tm->tm_year = (intclk.tm_year - 1900); -} - - -/* Set internal clock time. */ -void -nvr_time_set(struct tm *tm) -{ - intclk.tm_sec = tm->tm_sec; - intclk.tm_min = tm->tm_min; - intclk.tm_hour = tm->tm_hour; - intclk.tm_wday = tm->tm_wday; - intclk.tm_mday = tm->tm_mday; - intclk.tm_mon = (tm->tm_mon + 1); - intclk.tm_year = (tm->tm_year + 1900); -} - - -/* Open or create a file in the NVR area. */ -FILE * -nvr_fopen(wchar_t *str, wchar_t *mode) -{ - return(plat_fopen(nvr_path(str), mode)); -} diff --git a/src - Cópia/nvr.h b/src - Cópia/nvr.h deleted file mode 100644 index cbfd23954..000000000 --- a/src - Cópia/nvr.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 generic NVRAM/CMOS driver. - * - * Version: @(#)nvr.h 1.0.6 2018/04/11 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef EMU_NVR_H -# define EMU_NVR_H - - -#define NVR_MAXSIZE 128 /* max size of NVR data */ - -/* Conversion from BCD to Binary and vice versa. */ -#define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4)) -#define RTC_DCB(x) ((((x) & 0xf0) >> 4) * 10 + ((x) & 0x0f)) -#define RTC_BCDINC(x,y) RTC_BCD(RTC_DCB(x) + y) - - -/* Define a generic RTC/NVRAM device. */ -typedef struct _nvr_ { - wchar_t *fn; /* pathname of image file */ - uint16_t size; /* device configuration */ - int8_t irq; - - uint8_t onesec_cnt; - int64_t onesec_time; - - void *data; /* local data */ - - /* Hooks to device functions. */ - void (*reset)(struct _nvr_ *); - void (*start)(struct _nvr_ *); - void (*tick)(struct _nvr_ *); - void (*recalc)(struct _nvr_ *); - - uint8_t regs[NVR_MAXSIZE]; /* these are the registers */ -} nvr_t; - - -extern int nvr_dosave; -#ifdef EMU_DEVICE_H -extern const device_t at_nvr_device; -extern const device_t ps_nvr_device; -extern const device_t amstrad_nvr_device; -#endif - - -extern void nvr_init(nvr_t *); -extern wchar_t *nvr_path(wchar_t *str); -extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode); -extern int nvr_load(void); -extern int nvr_save(void); - -extern int nvr_is_leap(int year); -extern int nvr_get_days(int month, int year); -extern void nvr_time_get(struct tm *); -extern void nvr_time_set(struct tm *); -extern void nvr_period_recalc(void); - - -#endif /*EMU_NVR_H*/ diff --git a/src - Cópia/nvr_at.c b/src - Cópia/nvr_at.c deleted file mode 100644 index ec4c09aee..000000000 --- a/src - Cópia/nvr_at.c +++ /dev/null @@ -1,746 +0,0 @@ -/* - * 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. - * - * Implement a more-or-less defacto-standard RTC/NVRAM. - * - * When IBM released the PC/AT machine, it came standard with a - * battery-backed RTC chip to keep the time of day, something - * that was optional on standard PC's with a myriad variants - * being put on the market, often on cheap multi-I/O cards. - * - * The PC/AT had an on-board DS12885-series chip ("the black - * block") which was an RTC/clock chip with onboard oscillator - * and a backup battery (hence the big size.) The chip also had - * a small amount of RAM bytes available to the user, which was - * used by IBM's ROM BIOS to store machine configuration data. - * Later versions and clones used the 12886 and/or 1288(C)7 - * series, or the MC146818 series, all with an external battery. - * Many of those batteries would create corrosion issues later - * on in mainboard life... - * - * Since then, pretty much any PC has an implementation of that - * device, which became known as the "nvr" or "cmos". - * - * NOTES Info extracted from the data sheets: - * - * * The century register at location 32h is a BCD register - * designed to automatically load the BCD value 20 as the - * year register changes from 99 to 00. The MSB of this - * register is not affected when the load of 20 occurs, - * and remains at the value written by the user. - * - * * Rate Selector (RS3:RS0) - * These four rate-selection bits select one of the 13 - * taps on the 15-stage divider or disable the divider - * output. The tap selected can be used to generate an - * output square wave (SQW pin) and/or a periodic interrupt. - * - * The user can do one of the following: - * - enable the interrupt with the PIE bit; - * - enable the SQW output pin with the SQWE bit; - * - enable both at the same time and the same rate; or - * - enable neither. - * - * Table 3 lists the periodic interrupt rates and the square - * wave frequencies that can be chosen with the RS bits. - * These four read/write bits are not affected by !RESET. - * - * * Oscillator (DV2:DV0) - * These three bits are used to turn the oscillator on or - * off and to reset the countdown chain. A pattern of 010 - * is the only combination of bits that turn the oscillator - * on and allow the RTC to keep time. A pattern of 11x - * enables the oscillator but holds the countdown chain in - * reset. The next update occurs at 500ms after a pattern - * of 010 is written to DV0, DV1, and DV2. - * - * * Update-In-Progress (UIP) - * This bit is a status flag that can be monitored. When the - * UIP bit is a 1, the update transfer occurs soon. When - * UIP is a 0, the update transfer does not occur for at - * least 244us. The time, calendar, and alarm information - * in RAM is fully available for access when the UIP bit - * is 0. The UIP bit is read-only and is not affected by - * !RESET. Writing the SET bit in Register B to a 1 - * inhibits any update transfer and clears the UIP status bit. - * - * * Daylight Saving Enable (DSE) - * This bit is a read/write bit that enables two daylight - * saving adjustments when DSE is set to 1. On the first - * Sunday in April (or the last Sunday in April in the - * MC146818A), the time increments from 1:59:59 AM to - * 3:00:00 AM. On the last Sunday in October when the time - * first reaches 1:59:59 AM, it changes to 1:00:00 AM. - * - * When DSE is enabled, the internal logic test for the - * first/last Sunday condition at midnight. If the DSE bit - * is not set when the test occurs, the daylight saving - * function does not operate correctly. These adjustments - * do not occur when the DSE bit is 0. This bit is not - * affected by internal functions or !RESET. - * - * * 24/12 - * The 24/12 control bit establishes the format of the hours - * byte. A 1 indicates the 24-hour mode and a 0 indicates - * the 12-hour mode. This bit is read/write and is not - * affected by internal functions or !RESET. - * - * * Data Mode (DM) - * This bit indicates whether time and calendar information - * is in binary or BCD format. The DM bit is set by the - * program to the appropriate format and can be read as - * required. This bit is not modified by internal functions - * or !RESET. A 1 in DM signifies binary data, while a 0 in - * DM specifies BCD data. - * - * * Square-Wave Enable (SQWE) - * When this bit is set to 1, a square-wave signal at the - * frequency set by the rate-selection bits RS3-RS0 is driven - * out on the SQW pin. When the SQWE bit is set to 0, the - * SQW pin is held low. SQWE is a read/write bit and is - * cleared by !RESET. SQWE is low if disabled, and is high - * impedance when VCC is below VPF. SQWE is cleared to 0 on - * !RESET. - * - * * Update-Ended Interrupt Enable (UIE) - * This bit is a read/write bit that enables the update-end - * flag (UF) bit in Register C to assert !IRQ. The !RESET - * pin going low or the SET bit going high clears the UIE bit. - * The internal functions of the device do not affect the UIE - * bit, but is cleared to 0 on !RESET. - * - * * Alarm Interrupt Enable (AIE) - * This bit is a read/write bit that, when set to 1, permits - * the alarm flag (AF) bit in Register C to assert !IRQ. An - * alarm interrupt occurs for each second that the three time - * bytes equal the three alarm bytes, including a don't-care - * alarm code of binary 11XXXXXX. The AF bit does not - * initiate the !IRQ signal when the AIE bit is set to 0. - * The internal functions of the device do not affect the AIE - * bit, but is cleared to 0 on !RESET. - * - * * Periodic Interrupt Enable (PIE) - * The PIE bit is a read/write bit that allows the periodic - * interrupt flag (PF) bit in Register C to drive the !IRQ pin - * low. When the PIE bit is set to 1, periodic interrupts are - * generated by driving the !IRQ pin low at a rate specified - * by the RS3-RS0 bits of Register A. A 0 in the PIE bit - * blocks the !IRQ output from being driven by a periodic - * interrupt, but the PF bit is still set at the periodic - * rate. PIE is not modified b any internal device functions, - * but is cleared to 0 on !RESET. - * - * * SET - * When the SET bit is 0, the update transfer functions - * normally by advancing the counts once per second. When - * the SET bit is written to 1, any update transfer is - * inhibited, and the program can initialize the time and - * calendar bytes without an update occurring in the midst of - * initializing. Read cycles can be executed in a similar - * manner. SET is a read/write bit and is not affected by - * !RESET or internal functions of the device. - * - * * Update-Ended Interrupt Flag (UF) - * This bit is set after each update cycle. When the UIE - * bit is set to 1, the 1 in UF causes the IRQF bit to be - * a 1, which asserts the !IRQ pin. This bit can be - * cleared by reading Register C or with a !RESET. - * - * * Alarm Interrupt Flag (AF) - * A 1 in the AF bit indicates that the current time has - * matched the alarm time. If the AIE bit is also 1, the - * !IRQ pin goes low and a 1 appears in the IRQF bit. This - * bit can be cleared by reading Register C or with a - * !RESET. - * - * * Periodic Interrupt Flag (PF) - * This bit is read-only and is set to 1 when an edge is - * detected on the selected tap of the divider chain. The - * RS3 through RS0 bits establish the periodic rate. PF is - * set to 1 independent of the state of the PIE bit. When - * both PF and PIE are 1s, the !IRQ signal is active and - * sets the IRQF bit. This bit can be cleared by reading - * Register C or with a !RESET. - * - * * Interrupt Request Flag (IRQF) - * The interrupt request flag (IRQF) is set to a 1 when one - * or more of the following are true: - * - PF == PIE == 1 - * - AF == AIE == 1 - * - UF == UIE == 1 - * Any time the IRQF bit is a 1, the !IRQ pin is driven low. - * All flag bits are cleared after Register C is read by the - * program or when the !RESET pin is low. - * - * * Valid RAM and Time (VRT) - * This bit indicates the condition of the battery connected - * to the VBAT pin. This bit is not writeable and should - * always be 1 when read. If a 0 is ever present, an - * exhausted internal lithium energy source is indicated and - * both the contents of the RTC data and RAM data are - * questionable. This bit is unaffected by !RESET. - * - * This file implements a generic version of the RTC/NVRAM chip, - * including the later update (DS12887A) which implemented a - * "century" register to be compatible with Y2K. - * - * Version: @(#)nvr_at.c 1.0.9 2018/05/10 - * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Mahod, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" -#include "mem.h" -#include "nmi.h" -#include "pic.h" -#include "pit.h" -#include "rom.h" -#include "timer.h" -#include "device.h" -#include "nvr.h" - - -/* RTC registers and bit definitions. */ -#define RTC_SECONDS 0 -#define RTC_ALSECONDS 1 -# define AL_DONTCARE 0xc0 /* Alarm time is not set */ -#define RTC_MINUTES 2 -#define RTC_ALMINUTES 3 -#define RTC_HOURS 4 -# define RTC_AMPM 0x80 /* PM flag if 12h format in use */ -#define RTC_ALHOURS 5 -#define RTC_DOW 6 -#define RTC_DOM 7 -#define RTC_MONTH 8 -#define RTC_YEAR 9 -#define RTC_REGA 10 -# define REGA_UIP 0x80 -# define REGA_DV2 0x40 -# define REGA_DV1 0x20 -# define REGA_DV0 0x10 -# define REGA_DV 0x70 -# define REGA_RS3 0x08 -# define REGA_RS2 0x04 -# define REGA_RS1 0x02 -# define REGA_RS0 0x01 -# define REGA_RS 0x0f -#define RTC_REGB 11 -# define REGB_SET 0x80 -# define REGB_PIE 0x40 -# define REGB_AIE 0x20 -# define REGB_UIE 0x10 -# define REGB_SQWE 0x08 -# define REGB_DM 0x04 -# define REGB_2412 0x02 -# define REGB_DSE 0x01 -#define RTC_REGC 12 -# define REGC_IRQF 0x80 -# define REGC_PF 0x40 -# define REGC_AF 0x20 -# define REGC_UF 0x10 -#define RTC_REGD 13 -# define REGD_VRT 0x80 -#define RTC_CENTURY_AT 0x32 /* century register for AT etc */ -#define RTC_CENTURY_PS 0x37 /* century register for PS/1 PS/2 */ -#define RTC_REGS 14 /* number of registers */ - - -typedef struct { - int8_t stat; - uint8_t cent; - - uint16_t addr; - - int64_t ecount, - rtctime; -} local_t; - - -/* Get the current NVR time. */ -static void -time_get(nvr_t *nvr, struct tm *tm) -{ - local_t *local = (local_t *)nvr->data; - int8_t temp; - - if (nvr->regs[RTC_REGB] & REGB_DM) { - /* NVR is in Binary data mode. */ - tm->tm_sec = nvr->regs[RTC_SECONDS]; - tm->tm_min = nvr->regs[RTC_MINUTES]; - temp = nvr->regs[RTC_HOURS]; - tm->tm_wday = (nvr->regs[RTC_DOW] - 1); - tm->tm_mday = nvr->regs[RTC_DOM]; - tm->tm_mon = (nvr->regs[RTC_MONTH] - 1); - tm->tm_year = nvr->regs[RTC_YEAR]; - tm->tm_year += (nvr->regs[local->cent] * 100) - 1900; - } else { - /* NVR is in BCD data mode. */ - tm->tm_sec = RTC_DCB(nvr->regs[RTC_SECONDS]); - tm->tm_min = RTC_DCB(nvr->regs[RTC_MINUTES]); - temp = RTC_DCB(nvr->regs[RTC_HOURS]); - tm->tm_wday = (RTC_DCB(nvr->regs[RTC_DOW]) - 1); - tm->tm_mday = RTC_DCB(nvr->regs[RTC_DOM]); - tm->tm_mon = (RTC_DCB(nvr->regs[RTC_MONTH]) - 1); - tm->tm_year = RTC_DCB(nvr->regs[RTC_YEAR]); - tm->tm_year += (RTC_DCB(nvr->regs[local->cent]) * 100) - 1900; - } - - /* Adjust for 12/24 hour mode. */ - if (nvr->regs[RTC_REGB] & REGB_2412) - tm->tm_hour = temp; - else - tm->tm_hour = ((temp & ~RTC_AMPM)%12) + ((temp&RTC_AMPM) ? 12 : 0); -} - - -/* Set the current NVR time. */ -static void -time_set(nvr_t *nvr, struct tm *tm) -{ - local_t *local = (local_t *)nvr->data; - int year = (tm->tm_year + 1900); - - if (nvr->regs[RTC_REGB] & REGB_DM) { - /* NVR is in Binary data mode. */ - nvr->regs[RTC_SECONDS] = tm->tm_sec; - nvr->regs[RTC_MINUTES] = tm->tm_min; - nvr->regs[RTC_DOW] = (tm->tm_wday + 1); - nvr->regs[RTC_DOM] = tm->tm_mday; - nvr->regs[RTC_MONTH] = (tm->tm_mon + 1); - nvr->regs[RTC_YEAR] = (year % 100); - nvr->regs[local->cent] = (year / 100); - - if (nvr->regs[RTC_REGB] & REGB_2412) { - /* NVR is in 24h mode. */ - nvr->regs[RTC_HOURS] = tm->tm_hour; - } else { - /* NVR is in 12h mode. */ - nvr->regs[RTC_HOURS] = (tm->tm_hour % 12) ? (tm->tm_hour % 12) : 12; - if (tm->tm_hour > 11) - nvr->regs[RTC_HOURS] |= RTC_AMPM; - } - } else { - /* NVR is in BCD data mode. */ - nvr->regs[RTC_SECONDS] = RTC_BCD(tm->tm_sec); - nvr->regs[RTC_MINUTES] = RTC_BCD(tm->tm_min); - nvr->regs[RTC_DOW] = RTC_BCD(tm->tm_wday + 1); - nvr->regs[RTC_DOM] = RTC_BCD(tm->tm_mday); - nvr->regs[RTC_MONTH] = RTC_BCD(tm->tm_mon + 1); - nvr->regs[RTC_YEAR] = RTC_BCD(year % 100); - nvr->regs[local->cent] = RTC_BCD(year / 100); - - if (nvr->regs[RTC_REGB] & REGB_2412) { - /* NVR is in 24h mode. */ - nvr->regs[RTC_HOURS] = RTC_BCD(tm->tm_hour); - } else { - /* NVR is in 12h mode. */ - nvr->regs[RTC_HOURS] = (tm->tm_hour % 12) - ? RTC_BCD(tm->tm_hour % 12) - : RTC_BCD(12); - if (tm->tm_hour > 11) - nvr->regs[RTC_HOURS] |= RTC_AMPM; - } - } -} - - -/* Check if the current time matches a set alarm time. */ -static int8_t -check_alarm(nvr_t *nvr, int8_t addr) -{ - return((nvr->regs[addr+1] == nvr->regs[addr]) || - ((nvr->regs[addr+1] & AL_DONTCARE) == AL_DONTCARE)); -} - - -/* Update the NVR registers from the internal clock. */ -static void -timer_update(void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - local_t *local = (local_t *)nvr->data; - struct tm tm; - - if (! (nvr->regs[RTC_REGB] & REGB_SET)) { - /* Get the current time from the internal clock. */ - nvr_time_get(&tm); - - /* Update registers with current time. */ - time_set(nvr, &tm); - - /* Clear update status. */ - local->stat = 0x00; - - /* Check for any alarms we need to handle. */ - if (check_alarm(nvr, RTC_SECONDS) && - check_alarm(nvr, RTC_MINUTES) && - check_alarm(nvr, RTC_HOURS)) { - nvr->regs[RTC_REGC] |= REGC_AF; - if (nvr->regs[RTC_REGB] & REGB_AIE) { - nvr->regs[RTC_REGC] |= REGC_IRQF; - - /* Generate an interrupt. */ - if (nvr->irq != -1) - picint(1 << nvr->irq); - } - } - - /* - * The flag and interrupt should be issued - * on update ended, not started. - */ - nvr->regs[RTC_REGC] |= REGC_UF; - if (nvr->regs[RTC_REGB] & REGB_UIE) { - nvr->regs[RTC_REGC] |= REGC_IRQF; - - /* Generate an interrupt. */ - if (nvr->irq != -1) - picint(1 << nvr->irq); - } - } - - local->ecount = 0; -} - - -/* Re-calculate the timer values. */ -static void -timer_recalc(nvr_t *nvr, int add) -{ - local_t *local = (local_t *)nvr->data; - int64_t c, nt; - - c = 1ULL << ((nvr->regs[RTC_REGA] & REGA_RS) - 1); - nt = (int64_t)(RTCCONST * c * (1<rtctime += nt; - else if (local->rtctime > nt) - local->rtctime = nt; -} - - -static void -timer_intr(void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - local_t *local = (local_t *)nvr->data; - - if (! (nvr->regs[RTC_REGA] & REGA_RS)) { - local->rtctime = 0x7fffffff; - return; - } - - /* Update our timer interval. */ - timer_recalc(nvr, 1); - - nvr->regs[RTC_REGC] |= REGC_PF; - if (nvr->regs[RTC_REGB] & REGB_PIE) { - nvr->regs[RTC_REGC] |= REGC_IRQF; - - /* Generate an interrupt. */ - if (nvr->irq != -1) - picint(1 << nvr->irq); - } -} - - -/* Callback from internal clock, another second passed. */ -static void -timer_tick(nvr_t *nvr) -{ - local_t *local = (local_t *)nvr->data; - - /* Only update it there is no SET in progress. */ - if (! (nvr->regs[RTC_REGB] & REGB_SET)) { - /* Set the UIP bit, announcing the update. */ - local->stat = REGA_UIP; - - timer_recalc(nvr, 0); - - /* Schedule the actual update. */ - local->ecount = (int64_t)((244.0 + 1984.0) * TIMER_USEC); - } -} - - -/* Write to one of the NVR registers. */ -static void -nvr_write(uint16_t addr, uint8_t val, void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - local_t *local = (local_t *)nvr->data; - struct tm tm; - uint8_t old; - - cycles -= ISA_CYCLES(8); - - if (addr & 1) { - old = nvr->regs[local->addr]; - switch(local->addr) { - case RTC_REGA: - nvr->regs[RTC_REGA] = val; - if (val & REGA_RS) - timer_recalc(nvr, 1); - else - local->rtctime = 0x7fffffff; - break; - - case RTC_REGB: - nvr->regs[RTC_REGB] = val; - if (((old^val) & REGB_SET) && (val®B_SET)) { - /* According to the datasheet... */ - nvr->regs[RTC_REGA] &= ~REGA_UIP; - nvr->regs[RTC_REGB] &= ~REGB_UIE; - } - break; - - case RTC_REGC: /* R/O */ - case RTC_REGD: /* R/O */ - break; - - default: /* non-RTC registers are just NVRAM */ - if (nvr->regs[local->addr] != val) { - nvr->regs[local->addr] = val; - nvr_dosave = 1; - } - break; - } - - if ((local->addr < RTC_REGA) || (local->addr == local->cent)) { - if ((local->addr != 1) && (local->addr != 3) && (local->addr != 5)) { - if ((old != val) && !enable_sync) { - /* Update internal clock. */ - time_get(nvr, &tm); - nvr_time_set(&tm); - nvr_dosave = 1; - } - } - } - } else { - local->addr = (val & (nvr->size - 1)); - if (!(machines[machine].flags & MACHINE_MCA) && - (romset != ROM_IBMPS1_2133)) - nmi_mask = (~val & 0x80); - } -} - - -/* Read from one of the NVR registers. */ -static uint8_t -nvr_read(uint16_t addr, void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - local_t *local = (local_t *)nvr->data; - uint8_t ret; - - cycles -= ISA_CYCLES(8); - - if (addr & 1) switch(local->addr) { - case RTC_REGA: - ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat; - break; - - case RTC_REGC: - picintc(1 << nvr->irq); - ret = nvr->regs[RTC_REGC]; - nvr->regs[RTC_REGC] = 0x00; - break; - - case RTC_REGD: - nvr->regs[RTC_REGD] |= REGD_VRT; - ret = nvr->regs[RTC_REGD]; - break; - - default: - ret = nvr->regs[local->addr]; - break; - } else { - ret = local->addr; - } - - return(ret); -} - - -/* Reset the RTC state to 1980/01/01 00:00. */ -static void -nvr_reset(nvr_t *nvr) -{ - local_t *local = (local_t *)nvr->data; - - memset(nvr->regs, 0x00, RTC_REGS); - nvr->regs[RTC_DOM] = 1; - nvr->regs[RTC_MONTH] = 1; - nvr->regs[RTC_YEAR] = RTC_BCD(80); - nvr->regs[local->cent] = RTC_BCD(19); -} - - -/* Process after loading from file. */ -static void -nvr_start(nvr_t *nvr) -{ - struct tm tm; - - /* Initialize the internal and chip times. */ - if (enable_sync) { - /* Use the internal clock's time. */ - nvr_time_get(&tm); - time_set(nvr, &tm); - } else { - /* Set the internal clock from the chip time. */ - time_get(nvr, &tm); - nvr_time_set(&tm); - } - - /* Start the RTC. */ - nvr->regs[RTC_REGA] = (REGA_RS2|REGA_RS1); - nvr->regs[RTC_REGB] = REGB_2412; - timer_recalc(nvr, 1); -} - - -static void -nvr_recalc(nvr_t *nvr) -{ - timer_recalc(nvr, 0); -} - - -static void * -nvr_at_init(const device_t *info) -{ - local_t *local; - nvr_t *nvr; - - /* Allocate an NVR for this machine. */ - nvr = (nvr_t *)malloc(sizeof(nvr_t)); - if (nvr == NULL) return(NULL); - /* FIXME: See which is correct, this or 0xFF. */ - /* memset(nvr, 0x00, sizeof(nvr_t)); */ - memset(nvr, 0xFF, sizeof(nvr_t)); - - local = (local_t *)malloc(sizeof(local_t)); - memset(local, 0xff, sizeof(local_t)); - nvr->data = local; - - /* This is machine specific. */ - nvr->size = machines[machine].nvrmask + 1; - switch(info->local) { - case 0: /* standard AT */ - nvr->irq = 8; - local->cent = RTC_CENTURY_AT; - break; - - case 1: /* PS/1 or PS/2 */ - nvr->irq = 8; - local->cent = RTC_CENTURY_PS; - break; - - case 2: /* Amstrad PC's */ - nvr->irq = 1; - local->cent = RTC_CENTURY_AT; - break; - } - - /* Set up any local handlers here. */ - nvr->reset = nvr_reset; - nvr->start = nvr_start; - nvr->tick = timer_tick; - nvr->recalc = nvr_recalc; - - /* Initialize the generic NVR. */ - nvr_init(nvr); - - /* Start the timers. */ - timer_add(timer_update, &local->ecount, &local->ecount, nvr); - timer_add(timer_intr, &local->rtctime, TIMER_ALWAYS_ENABLED, nvr); - - /* Set up the I/O handler for this device. */ - io_sethandler(0x0070, 2, - nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); - - return(nvr); -} - - -static void -nvr_at_close(void *priv) -{ - nvr_t *nvr = (nvr_t *)priv; - - if (nvr->fn != NULL) - free(nvr->fn); - - if (nvr->data != NULL) - free(nvr->data); - - free(nvr); -} - - -const device_t at_nvr_device = { - "PC/AT NVRAM", - DEVICE_ISA | DEVICE_AT, - 0, - nvr_at_init, nvr_at_close, NULL, - NULL, NULL, - NULL -}; - -const device_t ps_nvr_device = { - "PS/1 or PS/2 NVRAM", - DEVICE_PS2, - 1, - nvr_at_init, nvr_at_close, NULL, - NULL, NULL, - NULL -}; - -const device_t amstrad_nvr_device = { - "Amstrad NVRAM", - MACHINE_ISA | MACHINE_AT, - 2, - nvr_at_init, nvr_at_close, NULL, - NULL, NULL, - NULL -}; diff --git a/src - Cópia/nvr_ps2.c b/src - Cópia/nvr_ps2.c deleted file mode 100644 index 4431d7a4f..000000000 --- a/src - Cópia/nvr_ps2.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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. - * - * Handling of the PS/2 series CMOS devices. - * - * Version: @(#)nvr_ps2.c 1.0.7 2018/04/26 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * - * 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. - */ -#include -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "nvr.h" -#include "nvr_ps2.h" -#include "rom.h" - - -typedef struct { - int addr; - - uint8_t ram[8192]; -} ps2_nvr_t; - - -static uint8_t -ps2_nvr_read(uint16_t port, void *priv) -{ - ps2_nvr_t *nvr = (ps2_nvr_t *)priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x74: - ret = nvr->addr & 0xff; - break; - - case 0x75: - ret = nvr->addr >> 8; - break; - - case 0x76: - ret = nvr->ram[nvr->addr]; - break; - } - - return(ret); -} - - -static void -ps2_nvr_write(uint16_t port, uint8_t val, void *priv) -{ - ps2_nvr_t *nvr = (ps2_nvr_t *)priv; - - switch (port) { - case 0x74: - nvr->addr = (nvr->addr & 0x1f00) | val; - break; - - case 0x75: - nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8); - break; - - case 0x76: - nvr->ram[nvr->addr] = val; - break; - } -} - - -static void * -ps2_nvr_init(const device_t *info) -{ - ps2_nvr_t *nvr; - FILE *f = NULL; - - nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); - memset(nvr, 0x00, sizeof(ps2_nvr_t)); - - io_sethandler(0x0074, 3, - ps2_nvr_read,NULL,NULL, ps2_nvr_write,NULL,NULL, nvr); - - switch (romset) { - case ROM_IBMPS2_M70_TYPE3: - f = nvr_fopen(L"ibmps2_m70_type3_sec.nvr", L"rb"); - break; - case ROM_IBMPS2_M70_TYPE4: - f = nvr_fopen(L"ibmps2_m70_type4_sec.nvr", L"rb"); - break; - case ROM_IBMPS2_M80: - f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"rb"); - break; - } - - memset(nvr->ram, 0xff, 8192); - if (f != NULL) { - (void)fread(nvr->ram, 8192, 1, f); - fclose(f); - } - - return(nvr); -} - - -static void -ps2_nvr_close(void *priv) -{ - ps2_nvr_t *nvr = (ps2_nvr_t *)priv; - FILE *f = NULL; - - switch (romset) { - case ROM_IBMPS2_M70_TYPE3: - f = nvr_fopen(L"ibmps2_m70_type3_sec.nvr", L"wb"); - break; - case ROM_IBMPS2_M70_TYPE4: - f = nvr_fopen(L"ibmps2_m70_type4_sec.nvr", L"wb"); - break; - case ROM_IBMPS2_M80: - f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"wb"); - break; - } - - if (f != NULL) { - (void)fwrite(nvr->ram, 8192, 1, f); - fclose(f); - } - - free(nvr->ram); - - free(nvr); -} - - -const device_t ps2_nvr_device = { - "PS/2 Secondary NVRAM", - 0, 0, - ps2_nvr_init, ps2_nvr_close, NULL, - NULL, NULL, - NULL -}; diff --git a/src - Cópia/nvr_ps2.h b/src - Cópia/nvr_ps2.h deleted file mode 100644 index 57293f212..000000000 --- a/src - Cópia/nvr_ps2.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 PS/2 cmos/nvr device. - * - * Version: @(#)nvr_ps2.h 1.0.2 2018/03/18 - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * - * 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 EMU_NVRPS2_H -# define EMU_NVRPS2_H - - -extern const device_t ps2_nvr_device; - - -#endif /*EMU_NVRPS2_H*/ diff --git a/src - Cópia/pc.c b/src - Cópia/pc.c deleted file mode 100644 index 6e9d9e0ec..000000000 --- a/src - Cópia/pc.c +++ /dev/null @@ -1,1144 +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. - * - * Main emulator module where most things are controlled. - * - * Version: @(#)pc.c 1.0.73 2018/06/02 - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "cpu/cpu.h" -#ifdef USE_DYNAREC -# include "cpu/codegen.h" -#endif -#include "cpu/x86_ops.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "dma.h" -#include "pci.h" -#include "pic.h" -#include "pit.h" -#include "random.h" -#include "timer.h" -#include "device.h" -#include "nvr.h" -#include "machine/machine.h" -#include "bugger.h" -#include "lpt.h" -#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 "cdrom/cdrom.h" -#include "disk/zip.h" -#include "scsi/scsi_disk.h" -#include "cdrom/cdrom_image.h" -#include "cdrom/cdrom_null.h" -#include "network/network.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_speaker.h" -#include "video/video.h" -#include "ui.h" -#include "plat.h" -#include "plat_midi.h" - - -/* Commandline options. */ -int dump_on_exit = 0; /* (O) dump regs on exit */ -int do_dump_config = 0; /* (O) dump config on load */ -int start_in_fullscreen = 0; /* (O) start in fullscreen */ -#ifdef _WIN32 -int force_debug = 0; /* (O) force debug output */ -#endif -#ifdef USE_WX -int video_fps = RENDER_FPS; /* (O) render speed in fps */ -#endif -int settings_only = 0; /* (O) show only the settings dialog */ -#ifdef _WIN32 -uint64_t unique_id = 0; -uint64_t source_hwnd = 0; -#endif -wchar_t log_path[1024] = { L'\0'}; /* (O) full path of logfile */ - -/* Configuration values. */ -int window_w, window_h, /* (C) window size and */ - window_x, window_y, /* position info */ - window_remember, - vid_resize, /* (C) allow resizing */ - invert_display, /* (C) invert the display */ - suppress_overscan = 0; /* (C) suppress overscans */ -int scale = 0; /* (C) screen scale factor */ -int vid_api = 0; /* (C) video renderer */ -int vid_cga_contrast = 0, /* (C) video */ - video_fullscreen = 0, /* (C) video */ - video_fullscreen_scale = 0, /* (C) video */ - video_fullscreen_first = 0, /* (C) video */ - enable_overscan = 0, /* (C) video */ - force_43 = 0; /* (C) video */ -int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ - lpt_enabled = 0, /* (C) enable LPT ports */ - bugger_enabled = 0; /* (C) enable ISAbugger */ -int gfxcard = 0; /* (C) graphics/video card */ -int sound_is_float = 1, /* (C) sound uses FP values */ - GAMEBLASTER = 0, /* (C) sound option */ - GUS = 0, /* (C) sound option */ - SSI2001 = 0, /* (C) sound option */ - voodoo_enabled = 0; /* (C) video option */ -uint32_t mem_size = 0; /* (C) memory size */ -int cpu_manufacturer = 0, /* (C) cpu manufacturer */ - cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */ - cpu = 3, /* (C) cpu type */ - enable_external_fpu = 0; /* (C) enable external FPU */ -int enable_sync = 0; /* (C) enable time sync */ - -/* Statistics. */ -extern int - mmuflush, - readlnum, - writelnum; - -int fps, framecount; /* emulator % */ - -int CPUID; -int output; -int atfullspeed; -int cpuspeed2; -int clockrate; - -int gfx_present[GFX_MAX]; /* should not be here */ - -wchar_t exe_path[1024]; /* path (dir) of executable */ -wchar_t usr_path[1024]; /* path (dir) of user data */ -wchar_t cfg_path[1024]; /* full path of config file */ -FILE *stdlog = NULL; /* file to log output to */ -int scrnsz_x = SCREEN_RES_X, /* current screen size, X */ - scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ -int config_changed; /* config has changed */ -int romset; /* current machine ID */ -int title_update; -int64_t main_time; - - -int unscaled_size_x = SCREEN_RES_X, /* current unscaled size X */ - unscaled_size_y = SCREEN_RES_Y, /* current unscaled size Y */ - efscrnsz_y = SCREEN_RES_Y; - - -#ifndef RELEASE_BUILD -static char buff[1024]; -static int seen = 0; - -static int suppr_seen = 1; -#endif - -/* - * Log something to the logfile or stdout. - * - * To avoid excessively-large logfiles because some - * module repeatedly logs, we keep track of what is - * being logged, and catch repeating entries. - */ -void -pclog_ex(const char *fmt, va_list ap) -{ -#ifndef RELEASE_BUILD - char temp[1024]; - - if (stdlog == NULL) { - if (log_path[0] != L'\0') { - stdlog = plat_fopen(log_path, L"w"); - if (stdlog == NULL) - stdlog = stdout; - } else { - stdlog = stdout; - } - } - - vsprintf(temp, fmt, ap); - if (suppr_seen && ! strcmp(buff, temp)) { - seen++; - } else { - if (suppr_seen && seen) { - fprintf(stdlog, "*** %d repeats ***\n", seen); - } - seen = 0; - strcpy(buff, temp); - fprintf(stdlog, temp, ap); - } - - fflush(stdlog); -#endif -} - - -void -pclog_toggle_suppr(void) -{ -#ifndef RELEASE_BUILD - suppr_seen ^= 1; -#endif -} - - -/* Log something. We only do this in non-release builds. */ -void -pclog(const char *fmt, ...) -{ -#ifndef RELEASE_BUILD - va_list ap; - - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); -#endif -} - - -/* Log a fatal error, and display a UI message before exiting. */ -void -fatal(const char *fmt, ...) -{ - char temp[1024]; - va_list ap; - char *sp; - - va_start(ap, fmt); - - if (stdlog == NULL) { - if (log_path[0] != L'\0') { - stdlog = plat_fopen(log_path, L"w"); - if (stdlog == NULL) - stdlog = stdout; - } else { - stdlog = stdout; - } - } - - vsprintf(temp, fmt, ap); - fprintf(stdlog, "%s", temp); - fflush(stdlog); - va_end(ap); - - nvr_save(); - - config_save(); - - dumppic(); - dumpregs(1); - - /* Make sure the message does not have a trailing newline. */ - if ((sp = strchr(temp, '\n')) != NULL) *sp = '\0'; - - ui_msgbox(MBX_ERROR|MBX_FATAL|MBX_ANSI, temp); - - fflush(stdlog); - - exit(-1); -} - - -#ifdef ENABLE_PC_LOG -int pc_do_log = ENABLE_PC_LOG; -#endif - - -static void -pc_log(const char *format, ...) -{ -#ifdef ENABLE_PC_LOG - va_list ap; - - if (pc_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* - * Perform initial startup of the PC. - * - * This is the platform-indepenent part of the startup, - * where we check commandline arguments and load a - * configuration file. - */ -int -pc_init(int argc, wchar_t *argv[]) -{ - wchar_t path[2048]; - wchar_t *cfg = NULL, *p; - char temp[128]; - struct tm *info; - time_t now; - int c; - uint32_t *uid, *shwnd; - - /* Grab the executable's full path. */ - plat_get_exe_name(exe_path, sizeof(exe_path)-1); - p = plat_get_filename(exe_path); - *p = L'\0'; - - /* - * Get the current working directory. - * - * This is normally the directory from where the - * program was run. If we have been started via - * a shortcut (desktop icon), however, the CWD - * could have been set to something else. - */ - plat_getcwd(usr_path, sizeof_w(usr_path)-1); - memset(path, 0x00, sizeof(path)); - - for (c=1; c=0; c--) { - if (gfx_present[c]) { - gfxcard = c; - config_save(); - - /* This can loop if all cards now bad.. */ - goto again2; - } - } - } - - cpuspeed2 = (AT) ? 2 : 1; - atfullspeed = 0; - - random_init(); - - mem_init(); - -#ifdef USE_DYNAREC - codegen_init(); -#endif - - keyboard_init(); - joystick_init(); - video_init(); - device_init(); - - timer_reset(); - - fdd_init(); - - sound_init(); - - hdc_init(hdc_name); - - cdrom_hard_reset(); - - zip_hard_reset(); - - scsi_disk_hard_reset(); - - scsi_card_init(); - - pc_full_speed(); - shadowbios = 0; - - return(1); -} - - -/* Insert keystrokes into the machine's keyboard buffer. */ -static void -pc_keyboard_send(uint8_t val) -{ - if (AT) - keyboard_at_adddata_keyboard_raw(val); - else - keyboard_send(val); -} - - -void -pc_send_ca(uint8_t sc) -{ - pc_keyboard_send(29); /* Ctrl key pressed */ - pc_keyboard_send(56); /* Alt key pressed */ - pc_keyboard_send(sc); - pc_keyboard_send(sc | 0x80); - pc_keyboard_send(184); /* Alt key released */ - pc_keyboard_send(157); /* Ctrl key released */ -} - - -/* Send the machine a Control-Alt-DEL sequence. */ -void -pc_send_cad(void) -{ - pc_send_ca(83); -} - - -/* Send the machine a Control-Alt-ESC sequence. */ -void -pc_send_cae(void) -{ - pc_send_ca(1); -} - - -void -pc_reset_hard_close(void) -{ - suppress_overscan = 0; - - nvr_save(); - - mouse_close(); - - lpt_devices_close(); - - device_close_all(); - - midi_close(); - - cdrom_close(); - - closeal(); -} - - -/* - * This is basically the spot where we start up the actual machine, - * by issuing a 'hard reset' to the entire configuration. Order is - * somewhat important here. Functions here should be named _reset - * really, as that is what they do. - */ -void -pc_reset_hard_init(void) -{ - /* - * First, we reset the modules that are not part of - * the actual machine, but which support some of the - * modules that are. - */ - - /* Reset the general machine support modules. */ - io_init(); - timer_reset(); - - device_init(); - - sound_reset(); - - /* This is needed to initialize the serial timer. */ - serial_init(); - - cdrom_hard_reset(); - - zip_hard_reset(); - - scsi_disk_hard_reset(); - - /* Initialize the actual machine and its basic modules. */ - machine_init(); - - fdd_reset(); - - /* - * Once the machine has been initialized, all that remains - * should be resetting all devices set up for it, to their - * current configurations ! - * - * For now, we will call their reset functions here, but - * that will be a call to device_reset_all() later ! - */ - - /* Reset some basic devices. */ - speaker_init(); - serial_reset(); - lpt_devices_init(); - shadowbios = 0; - - /* - * This has to be after the serial initialization so that - * serial_init() doesn't break the serial mouse by resetting - * the RCR callback to NULL. - */ - mouse_reset(); - - /* Reset the video card. */ - video_reset(gfxcard); - - /* Reset the Hard Disk Controller module. */ - hdc_reset(); - - /* Reset and reconfigure the SCSI layer. */ - scsi_card_init(); - - /* Reset and reconfigure the Sound Card layer. */ - sound_card_reset(); - - /* Reset and reconfigure the Network Card layer. */ - network_reset(); - - if (joystick_type != 7) - gameport_update_joystick_type(); - - if (config_changed) { - ui_sb_update_panes(); - - config_save(); - - config_changed = 0; - } - - /* Needs the status bar... */ - if (bugger_enabled) - device_add(&bugger_device); - - /* Reset the CPU module. */ - resetx86(); - dma_reset(); - pic_reset(); - cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; - - if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setpitclock(14318184.0); -} - - -void -pc_reset_hard(void) -{ - pc_reset_hard_close(); - - pc_reset_hard_init(); -} - - -void -pc_reset(int hard) -{ - plat_pause(1); - - plat_delay_ms(100); - - nvr_save(); - - config_save(); - - if (hard) - pc_reset_hard(); - else - pc_send_cad(); - - plat_pause(0); -} - - -void -pc_close(thread_t *ptr) -{ - int i; - - /* Wait a while so things can shut down. */ - plat_delay_ms(200); - - /* Claim the video blitter. */ - startblit(); - - /* Terminate the main thread. */ - if (ptr != NULL) { - thread_kill(ptr); - - /* Wait some more. */ - plat_delay_ms(200); - } - - nvr_save(); - - config_save(); - - plat_mouse_capture(0); - - lpt_devices_close(); - - for (i=0; i 0 && !dopause) { - /* Yes, so do one frame now. */ - start_time = plat_timer_read(); - drawits -= 10; - if (drawits > 50) - drawits = 0; - - /* Run a block of code. */ - startblit(); - clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; - - if (is386) { -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - exec386_dynarec(clockrate/100); - else -#endif - exec386(clockrate/100); - } else if (AT) { - exec386(clockrate/100); - } else { - execx86(clockrate/100); - } - - mouse_process(); - - joystick_process(); - - endblit(); - - /* Done with this frame, update statistics. */ - framecount++; - if (++framecountx >= 100) { - framecountx = 0; - - readlnum = writelnum = 0; - egareads = egawrites = 0; - mmuflush = 0; - frames = 0; - } - - if (title_update) { - mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); - mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name, - strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name)+1); - swprintf(temp, sizeof_w(temp), - L"%ls v%ls - %i%% - %ls - %ls - %ls", - EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpu, - (!mouse_capture) ? plat_get_string(IDS_2077) - : (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); - - ui_window_title(temp); - - title_update = 0; - } - - /* One more frame done! */ - done++; - - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { - nvr_save(); - nvr_dosave = 0; - frames = 0; - } - - end_time = plat_timer_read(); - main_time += (end_time - start_time); - } else { - /* Just so we dont overload the host OS. */ - plat_delay_ms(1); - } - - /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen) { - plat_resize(scrnsz_x, scrnsz_y); - - doresize = 0; - } - } - - pc_log("PC: main thread done.\n"); -} - - -/* Handler for the 1-second timer to refresh the window title. */ -void -pc_onesec(void) -{ - fps = framecount; - framecount = 0; - - title_update = 1; -} - - -void -set_screen_size(int x, int y) -{ - int owsx = scrnsz_x; - int owsy = scrnsz_y; - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - double dx, dy, dtx, dty; - - /* Make sure we keep usable values. */ -#if 0 - pc_log("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize); -#endif - if (x < 320) x = 320; - if (y < 200) y = 200; - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; - - /* Save the new values as "real" (unscaled) resolution. */ - unscaled_size_x = x; - efscrnsz_y = y; - - if (suppress_overscan) - temp_overscan_x = temp_overscan_y = 0; - - if (force_43) { - dx = (double)x; - dtx = (double)temp_overscan_x; - - dy = (double)y; - dty = (double)temp_overscan_y; - - /* Account for possible overscan. */ - if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { - /* CGA */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { - /* MDA/Hercules */ - dy = (x / 4.0) * 3.0; - } else { - if (enable_overscan) { - /* EGA/(S)VGA with overscan */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else { - /* EGA/(S)VGA without overscan */ - dy = (x / 4.0) * 3.0; - } - } - unscaled_size_y = (int)dy; - } else { - unscaled_size_y = efscrnsz_y; - } - - switch(scale) { - case 0: /* 50% */ - scrnsz_x = (unscaled_size_x>>1); - scrnsz_y = (unscaled_size_y>>1); - break; - - case 1: /* 100% */ - scrnsz_x = unscaled_size_x; - scrnsz_y = unscaled_size_y; - break; - - case 2: /* 150% */ - scrnsz_x = ((unscaled_size_x*3)>>1); - scrnsz_y = ((unscaled_size_y*3)>>1); - break; - - case 3: /* 200% */ - scrnsz_x = (unscaled_size_x<<1); - scrnsz_y = (unscaled_size_y<<1); - break; - } - - /* If the resolution has changed, let the main thread handle it. */ - if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) - doresize = 1; - else - doresize = 0; -} - - -void -set_screen_size_natural(void) -{ - set_screen_size(unscaled_size_x, unscaled_size_y); -} - - -int -get_actual_size_x(void) -{ - return(unscaled_size_x); -} - - -int -get_actual_size_y(void) -{ - return(efscrnsz_y); -} diff --git a/src - Cópia/pci.c b/src - Cópia/pci.c deleted file mode 100644 index f3b7a9ce1..000000000 --- a/src - Cópia/pci.c +++ /dev/null @@ -1,762 +0,0 @@ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "machine/machine.h" -#include "cpu/cpu.h" -#include "io.h" -#include "pic.h" -#include "mem.h" -#include "device.h" -#include "pci.h" -#include "piix.h" -#include "keyboard.h" -#if 0 -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/zip.h" -#endif - - -static uint64_t pci_irq_hold[16]; - -typedef struct -{ - uint8_t id, type; - uint8_t irq_routing[4]; - void (*write) (int func, int addr, uint8_t val, void *priv); - uint8_t (*read) (int func, int addr, void *priv); - void * priv; -} pci_card_t; - -static pci_card_t pci_cards[32]; -static uint8_t last_pci_card = 0; - -static uint8_t pci_card_to_slot_mapping[32]; - -static uint8_t elcr[2] = { 0, 0 }; - -static uint8_t pci_irqs[4]; - -typedef struct -{ - uint8_t enabled; - uint8_t irq_line; -} pci_mirq_t; - -static pci_mirq_t pci_mirqs[2]; - -static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; -int pci_burst_time, pci_nonburst_time; - -static int trc_reg = 0; - -#ifdef ENABLE_PCI_LOG -int pci_do_log = ENABLE_PCI_LOG; -#endif - - -static void -pcilog(const char *fmt, ...) -{ -#ifdef ENABLE_PCI_LOG - va_list ap; - - if (pci_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void pci_cf8_write(uint16_t port, uint32_t val, void *p) -{ - pci_index = val & 0xff; - pci_func = (val >> 8) & 7; - pci_card = (val >> 11) & 31; - pci_bus = (val >> 16) & 0xff; - pci_enable = (val >> 31) & 1; -} - -static uint32_t pci_cf8_read(uint16_t port, void *p) -{ - return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); -} - -static void pci_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t slot = 0; - - switch (port) - { - case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: - if (!pci_enable) - return; - - if (!pci_bus) - { - slot = pci_card_to_slot_mapping[pci_card]; - if (slot != 0xFF) - { - if (pci_cards[slot].write) - { - /* pcilog("Reading PCI card on slot %02X (pci_cards[%i])...\n", pci_card, slot); */ - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } - } - } - - break; - } -} - -static uint8_t pci_read(uint16_t port, void *priv) -{ - uint8_t slot = 0; - - switch (port) - { - case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: - if (!pci_enable) - return 0xff; - - if (!pci_bus) - { - slot = pci_card_to_slot_mapping[pci_card]; - if (slot != 0xFF) - { - if (pci_cards[slot].read) - { - return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - } - } - } - - return 0xff; - } - return 0xff; -} - -static void elcr_write(uint16_t port, uint8_t val, void *priv) -{ - /* pcilog("ELCR%i: WRITE %02X\n", port & 1, val); */ - if (port & 1) - { - val &= 0xDE; - } - else - { - val &= 0xF8; - } - elcr[port & 1] = val; - - pcilog("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); -} - -static uint8_t elcr_read(uint16_t port, void *priv) -{ - /* pcilog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */ - return elcr[port & 1]; -} - -static void elcr_reset(void) -{ - pic_reset(); - /* elcr[0] = elcr[1] = 0; */ - elcr[0] = 0x98; - elcr[1] = 0x00; -} - -static void pci_type2_write(uint16_t port, uint8_t val, void *priv); -static uint8_t pci_type2_read(uint16_t port, void *priv); - -static void pci_type2_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t slot = 0; - - if (port == 0xcf8) - { - pci_func = (val >> 1) & 7; - if (!pci_key && (val & 0xf0)) - io_sethandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - else - io_removehandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - pci_key = val & 0xf0; - } - else if (port == 0xcfa) - { - pci_bus = val; - } - else - { - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - if (!pci_bus) - { - slot = pci_card_to_slot_mapping[pci_card]; - if (slot != 0xFF) - { - if (pci_cards[slot].write) - { - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } - } - } - } -} - -static uint8_t pci_type2_read(uint16_t port, void *priv) -{ - uint8_t slot = 0; - - if (port == 0xcf8) - { - return pci_key | (pci_func << 1); - } - else if (port == 0xcfa) - { - return pci_bus; - } - else - { - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - if (!pci_bus) - { - slot = pci_card_to_slot_mapping[pci_card]; - if (slot != 0xFF) - { - if (pci_cards[slot].read) - { - return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - } - } - } - } - return 0xff; -} - -void pci_set_irq_routing(int pci_int, int irq) -{ - pci_irqs[pci_int - 1] = irq; -} - -void pci_enable_mirq(int mirq) -{ - pci_mirqs[mirq].enabled = 1; -} - -void pci_set_mirq_routing(int mirq, int irq) -{ - pci_mirqs[mirq].irq_line = irq; -} - -int pci_irq_is_level(int irq) -{ - int real_irq = irq & 7; - - if ((irq <= 2) || (irq == 8) || (irq == 13)) - { - return 0; - } - - if (irq > 7) - { - return !!(elcr[1] & (1 << real_irq)); - } - else - { - return !!(elcr[0] & (1 << real_irq)); - } -} - -uint8_t pci_use_mirq(uint8_t mirq) -{ - if (!PCI || !pci_mirqs[0].enabled) - { - return 0; - } - - if (pci_mirqs[mirq].irq_line & 0x80) - { - return 0; - } - - return 1; -} - -#define pci_mirq_log pcilog - -void pci_set_mirq(uint8_t mirq) -{ - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!pci_mirqs[mirq].enabled) - { - pci_mirq_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } - - if (pci_mirqs[mirq].irq_line > 0x0F) - { - pci_mirq_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - else - { - irq_line = pci_mirqs[mirq].irq_line; - pci_mirq_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - } - - if (pci_irq_is_level(irq_line) && (pci_irq_hold[irq_line] & (1 << (0x1E + mirq)))) - { - /* IRQ already held, do nothing. */ - pci_mirq_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq); - return; - } - else - { - pci_mirq_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq); - } - - level = pci_irq_is_level(irq_line); - - if (!level || !pci_irq_hold[irq_line]) - { - pci_mirq_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - picintlevel(1 << irq_line); - } - else if (level && pci_irq_hold[irq_line]) - { - pci_mirq_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq); - } - - /* If the IRQ is level-triggered, mark that this MIRQ is holding it. */ - if (level) - { - pci_mirq_log("pci_set_mirq(%02X): Marking that this card is holding the IRQ\n", mirq); - pci_irq_hold[irq_line] |= (1 << (0x1E + mirq)); - } - else - { - pci_mirq_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq); - } -} - -void pci_set_irq(uint8_t card, uint8_t pci_int) -{ - uint8_t slot = 0; - uint8_t irq_routing = 0; - uint8_t pci_int_index = pci_int - PCI_INTA; - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!last_pci_card) - { - pcilog("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); - return; - } - else - { - pcilog("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - } - - slot = pci_card_to_slot_mapping[card]; - - if (slot == 0xFF) - { - pcilog("pci_set_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - else - { - pcilog("pci_set_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - } - - if (!pci_cards[slot].irq_routing[pci_int_index]) - { - pcilog("pci_set_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - else - { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; - pcilog("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - } - - if (pci_irqs[irq_routing] > 0x0F) - { - pcilog("pci_set_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } - else - { - irq_line = pci_irqs[irq_routing]; - pcilog("pci_set_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); - } - - if (pci_irq_is_level(irq_line) && (pci_irq_hold[irq_line] & (1 << card))) - { - /* IRQ already held, do nothing. */ - pcilog("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int); - return; - } - else - { - pcilog("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int); - } - - level = pci_irq_is_level(irq_line); - - if (!level || !pci_irq_hold[irq_line]) - { - pcilog("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - picintlevel(1 << irq_line); - } - else if (level && pci_irq_hold[irq_line]) - { - pcilog("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int); - } - - /* If the IRQ is level-triggered, mark that this card is holding it. */ - if (pci_irq_is_level(irq_line)) - { - pcilog("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] |= (1 << card); - } - else - { - pcilog("pci_set_irq(%02X, %02X): Edge-triggered interrupt, not marking\n", card, pci_int); - } -} - -void pci_clear_mirq(uint8_t mirq) -{ - uint8_t irq_line = 0; - uint8_t level = 0; - - mirq = 0; - - if (mirq > 1) - { - pci_mirq_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); - return; - } - - if (!pci_mirqs[mirq].enabled) - { - pci_mirq_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } - - if (pci_mirqs[mirq].irq_line > 0x0F) - { - pci_mirq_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - else - { - irq_line = pci_mirqs[mirq].irq_line; - pci_mirq_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - } - - if (pci_irq_is_level(irq_line) && !(pci_irq_hold[irq_line] & (1 << (0x1E + mirq)))) - { - /* IRQ not held, do nothing. */ - pci_mirq_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq); - return; - } - - level = pci_irq_is_level(irq_line); - - if (level) - { - pci_mirq_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq); - pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq)); - - if (!pci_irq_hold[irq_line]) - { - pci_mirq_log("pci_clear_mirq(%02X): IRQ no longer held by any card, clearing it\n", mirq); - picintc(1 << irq_line); - } - else - { - pci_mirq_log("pci_clear_mirq(%02X): IRQ is still being held\n", mirq); - } - } - else - { - pci_mirq_log("pci_clear_mirq(%02X): Clearing edge-triggered interrupt\n", mirq); - picintc(1 << irq_line); - } -} - -void pci_clear_irq(uint8_t card, uint8_t pci_int) -{ - uint8_t slot = 0; - uint8_t irq_routing = 0; - uint8_t pci_int_index = pci_int - PCI_INTA; - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!last_pci_card) - { - pcilog("pci_clear_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); - return; - } - else - { - pcilog("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - } - - slot = pci_card_to_slot_mapping[card]; - - if (slot == 0xFF) - { - pcilog("pci_clear_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - else - { - pcilog("pci_clear_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - } - - if (!pci_cards[slot].irq_routing[pci_int_index]) - { - pcilog("pci_clear_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - else - { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; - pcilog("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - } - - if (pci_irqs[irq_routing] > 0x0F) - { - pcilog("pci_clear_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } - else - { - irq_line = pci_irqs[irq_routing]; - pcilog("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); - } - - if (pci_irq_is_level(irq_line) && !(pci_irq_hold[irq_line] & (1 << card))) - { - /* IRQ not held, do nothing. */ - pcilog("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int); - return; - } - - level = pci_irq_is_level(irq_line); - - if (level) - { - pcilog("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] &= ~(1 << card); - - if (!pci_irq_hold[irq_line]) - { - pcilog("pci_clear_irq(%02X, %02X): IRQ no longer held by any card, clearing it\n", card, pci_int); - picintc(1 << irq_line); - } - else - { - pcilog("pci_clear_irq(%02X, %02X): IRQ is still being held\n", card, pci_int); - } - } - else - { - pcilog("pci_clear_irq(%02X, %02X): Clearing edge-triggered interrupt\n", card, pci_int); - picintc(1 << irq_line); - } -} - -void pci_reset(void) -{ - int i = 0; - - for (i = 0; i < 16; i++) - { - if (pci_irq_hold[i]) - { - pci_irq_hold[i] = 0; - - picintc(1 << i); - } - } - - elcr_reset(); -} - -static void pci_slots_clear(void) -{ - uint8_t i = 0; - uint8_t j = 0; - - last_pci_card = 0; - - for (i = 0; i < 32; i++) - { - pci_cards[i].id = 0xFF; - pci_cards[i].type = 0xFF; - - for (j = 0; j < 4; j++) - { - pci_cards[i].irq_routing[j] = 0; - } - - pci_cards[i].read = NULL; - pci_cards[i].write = NULL; - pci_cards[i].priv = NULL; - - pci_card_to_slot_mapping[i] = 0xFF; - } -} - -static uint8_t trc_read(uint16_t port, void *priv) -{ - return trc_reg & 0xfb; -} - -static void trc_reset(uint8_t val) -{ - if (val & 2) - { - device_reset_all_pci(); - - port_92_reset(); - - pci_reset(); - } - resetx86(); -} - -static void trc_write(uint16_t port, uint8_t val, void *priv) -{ - /* pcilog("TRC Write: %02X\n", val); */ - if (!(trc_reg & 4) && (val & 4)) - { - trc_reset(val); - } - trc_reg = val & 0xfd; -} - -void trc_init(void) -{ - trc_reg = 0; - - io_sethandler(0x0cf9, 0x0001, trc_read, NULL, NULL, trc_write, NULL, NULL, NULL); -} - -void pci_init(int type) -{ - int c; - - PCI = 1; - - pci_slots_clear(); - - pci_reset(); - - trc_init(); - - io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL); - - if (type == PCI_CONFIG_TYPE_1) - { - io_sethandler(0x0cf8, 0x0001, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_sethandler(0x0cfc, 0x0004, pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); - } - else - { - io_sethandler(0x0cf8, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - } - - for (c = 0; c < 4; c++) - { - pci_irqs[c] = PCI_IRQ_DISABLED; - } - - for (c = 0; c < 2; c++) - { - pci_mirqs[c].enabled = 0; - pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; - } -} - -void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd) -{ - pci_cards[last_pci_card].id = card; - pci_cards[last_pci_card].type = type; - pci_cards[last_pci_card].irq_routing[0] = inta; - pci_cards[last_pci_card].irq_routing[1] = intb; - pci_cards[last_pci_card].irq_routing[2] = intc; - pci_cards[last_pci_card].irq_routing[3] = intd; - pci_cards[last_pci_card].read = NULL; - pci_cards[last_pci_card].write = NULL; - pci_cards[last_pci_card].priv = NULL; - pci_card_to_slot_mapping[card] = last_pci_card; - pcilog("pci_register_slot(): pci_cards[%i].id = %02X\n", last_pci_card, card); - last_pci_card++; -} - -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) -{ - uint8_t i = 0; - - if (add_type < PCI_ADD_NORMAL) - { - pcilog("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); - } - - if (!PCI) - { - pcilog("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); - return 0xFF; - } - - if (!last_pci_card) - { - pcilog("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); - return 0xFF; - } - - for (i = 0; i < last_pci_card; i++) - { - if (!pci_cards[i].read && !pci_cards[i].write) - { - if (((pci_cards[i].type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || - ((pci_cards[i].type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) || - ((pci_cards[i].id == add_type) && (add_type < PCI_ADD_NORMAL))) - { - pci_cards[i].read = read; - pci_cards[i].write = write; - pci_cards[i].priv = priv; - pcilog("pci_add_card(): Adding PCI CARD to pci_cards[%i] (slot %02X) [%s]\n", i, pci_cards[i].id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); - return pci_cards[i].id; - } - } - } - - pcilog("pci_add_card(): Adding PCI CARD failed (unable to find a suitable PCI slot) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); - return 0xFF; -} diff --git a/src - Cópia/pci.h b/src - Cópia/pci.h deleted file mode 100644 index 8f6d0e619..000000000 --- a/src - Cópia/pci.h +++ /dev/null @@ -1,57 +0,0 @@ -void pci_set_irq_routing(int pci_int, int irq); - -void pci_enable_mirq(int mirq); -void pci_set_mirq_routing(int mirq, int irq); - -uint8_t pci_use_mirq(uint8_t mirq); - -int pci_irq_is_level(int irq); - -void pci_set_mirq(uint8_t mirq); -void pci_set_irq(uint8_t card, uint8_t pci_int); -void pci_clear_mirq(uint8_t mirq); -void pci_clear_irq(uint8_t card, uint8_t pci_int); - -void pci_reset(void); -void pci_init(int type); -void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd); -void pci_close(void); -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); - -#define PCI_REG_COMMAND 0x04 - -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEM 0x02 - -#define PCI_CONFIG_TYPE_1 1 -#define PCI_CONFIG_TYPE_2 2 - -#define PCI_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 - -#define PCI_MIRQ0 0 -#define PCI_MIRQ1 1 - -#define PCI_IRQ_DISABLED -1 - -enum -{ - PCI_CARD_NORMAL = 0, - PCI_CARD_ONBOARD, - PCI_CARD_SPECIAL -}; - - -#define PCI_ADD_NORMAL 0x80 -#define PCI_ADD_VIDEO 0x81 - -extern int pci_burst_time, pci_nonburst_time; - -typedef union { - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; - -extern void trc_init(void); diff --git a/src - Cópia/pci_dummy.c b/src - Cópia/pci_dummy.c deleted file mode 100644 index 6a790ff14..000000000 --- a/src - Cópia/pci_dummy.c +++ /dev/null @@ -1,242 +0,0 @@ -/* This can also serve as a sample PCI device. */ -#include -#include -#include -#include -#include "86box.h" -#include "io.h" -#include "pci.h" -#include "pci_dummy.h" - -static uint8_t pci_regs[256]; - -static bar_t pci_bar[2]; - -static uint8_t interrupt_on = 0x00; -static uint8_t card = 0; - -static void pci_dummy_interrupt(int set) -{ - if (set) - { - pci_set_irq(card, pci_regs[0x3D]); - } - else - { - pci_clear_irq(card, pci_regs[0x3D]); - } -} - - -static uint8_t pci_dummy_read(uint16_t Port, void *p) -{ - uint8_t ret = 0; - - switch(Port & 0x20) - { - case 0x00: - return 0x1A; - case 0x01: - return 0x07; - case 0x02: - return 0x0B; - case 0x03: - return 0xAB; - case 0x04: - return pci_regs[0x3C]; - case 0x05: - return pci_regs[0x3D]; - case 0x06: - ret = interrupt_on; - if (interrupt_on) - { - pci_dummy_interrupt(0); - interrupt_on = 0; - } - return ret; - default: - return 0x00; - } -} - -static uint16_t pci_dummy_readw(uint16_t Port, void *p) -{ - return pci_dummy_read(Port, p); -} - - -static uint32_t pci_dummy_readl(uint16_t Port, void *p) -{ - return pci_dummy_read(Port, p); -} - - -static void pci_dummy_write(uint16_t Port, uint8_t Val, void *p) -{ - switch(Port & 0x20) - { - case 0x06: - if (!interrupt_on) - { - interrupt_on = 1; - pci_dummy_interrupt(1); - } - return; - default: - return; - } -} - -static void pci_dummy_writew(uint16_t Port, uint16_t Val, void *p) -{ - pci_dummy_write(Port, Val & 0xFF, p); -} - -static void pci_dummy_writel(uint16_t Port, uint32_t Val, void *p) -{ - pci_dummy_write(Port, Val & 0xFF, p); -} - - -static void pci_dummy_io_remove(void) -{ - io_removehandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL); -} - -static void pci_dummy_io_set(void) -{ - io_sethandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL); -} - - -static uint8_t pci_dummy_pci_read(int func, int addr, void *priv) -{ - pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr); - - switch(addr) { - case 0x00: - return 0x1A; - case 0x01: - return 0x07; - break; - - case 0x02: - return 0x0B; - case 0x03: - return 0xAB; - - case 0x04: /* PCI_COMMAND_LO */ - case 0x05: /* PCI_COMMAND_HI */ - return pci_regs[addr]; - - case 0x06: /* PCI_STATUS_LO */ - case 0x07: /* PCI_STATUS_HI */ - return pci_regs[addr]; - - case 0x08: - case 0x09: - return 0x00; - - case 0x0A: - return pci_regs[addr]; - - case 0x0B: - return pci_regs[addr]; - - case 0x10: /* PCI_BAR 7:5 */ - return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01; - case 0x11: /* PCI_BAR 15:8 */ - return pci_bar[0].addr_regs[1]; - case 0x12: /* PCI_BAR 23:16 */ - return pci_bar[0].addr_regs[2]; - case 0x13: /* PCI_BAR 31:24 */ - return pci_bar[0].addr_regs[3]; - - case 0x2C: - return 0x1A; - case 0x2D: - return 0x07; - - case 0x2E: - return 0x0B; - case 0x2F: - return 0xAB; - - case 0x3C: /* PCI_ILR */ - return pci_regs[addr]; - - case 0x3D: /* PCI_IPR */ - return pci_regs[addr]; - - default: - return 0x00; - } -} - -static void pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) -{ - uint8_t valxor; - - pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val); - - switch(addr) { - case 0x04: /* PCI_COMMAND_LO */ - valxor = (val & 0x03) ^ pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) - { - pci_dummy_io_remove(); - if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO)) - { - pci_dummy_io_set(); - } - } - pci_regs[addr] = val & 0x03; - break; - - case 0x10: /* PCI_BAR */ - val &= 0xe0; /* 0xe0 acc to RTL DS */ - val |= 0x01; /* re-enable IOIN bit */ - /*FALLTHROUGH*/ - - case 0x11: /* PCI_BAR */ - case 0x12: /* PCI_BAR */ - case 0x13: /* PCI_BAR */ - /* Remove old I/O. */ - pci_dummy_io_remove(); - - /* Set new I/O as per PCI request. */ - pci_bar[0].addr_regs[addr & 3] = val; - - /* Then let's calculate the new I/O base. */ - pci_bar[0].addr &= 0xffe0; - - /* Log the new base. */ - pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr); - - /* We're done, so get out of the here. */ - if (pci_regs[4] & PCI_COMMAND_IO) - { - if ((pci_bar[0].addr) != 0) - { - pci_dummy_io_set(); - } - } - break; - - case 0x3C: /* PCI_ILR */ - pclog("AB0B:071A: IRQ now: %i\n", val); - pci_regs[addr] = val; - return; - } -} - - -void pci_dummy_init(void) -{ - card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL); - - pci_bar[0].addr_regs[0] = 0x01; - pci_regs[0x04] = 0x03; - - pci_regs[0x3D] = PCI_INTD; -} diff --git a/src - Cópia/pci_dummy.h b/src - Cópia/pci_dummy.h deleted file mode 100644 index 45e1299bc..000000000 --- a/src - Cópia/pci_dummy.h +++ /dev/null @@ -1 +0,0 @@ -extern void pci_dummy_init(void); diff --git a/src - Cópia/pic.c b/src - Cópia/pic.c deleted file mode 100644 index fb107da8b..000000000 --- a/src - Cópia/pic.c +++ /dev/null @@ -1,536 +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. - * - * Implementation of the Intel PIC chip emulation. - * - * Version: @(#)pic.c 1.0.0 2018/04/29 - * - * Author: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" -#include "pci.h" -#include "pic.h" -#include "pit.h" - - -int output; -int intclear; -int keywaiting=0; -int pic_intpending; -PIC pic, pic2; -uint16_t pic_current; - - -#ifdef ENABLE_PIC_LOG -int pic_do_log = ENABLE_PIC_LOG; -#endif - - -static void -pic_log(const char *format, ...) -{ -#ifdef ENABLE_PIC_LOG - va_list ap; - - if (pic_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -void -pic_updatepending() -{ - uint16_t temp_pending = 0; - if (AT) { - if ((pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= pic.icw3; - else - pic.pend &= ~pic.icw3; - } - pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; - if (AT) { - if (!((pic.mask | pic.mask2) & pic.icw3)) { - temp_pending = ((pic2.pend&~pic2.mask)&~pic2.mask2); - temp_pending <<= 8; - pic_intpending |= temp_pending; - } - } - pic_log("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2); - pic_log(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2)); -} - - -void -pic_reset() -{ - pic.icw=0; - pic.mask=0xFF; - pic.mask2=0; - pic.pend=pic.ins=0; - pic.vector=8; - pic.read=1; - pic2.icw=0; - pic2.mask=0xFF; - pic.mask2=0; - pic2.pend=pic2.ins=0; - pic_intpending = 0; -} - - -void -pic_update_mask(uint8_t *mask, uint8_t ins) -{ - int c; - *mask = 0; - for (c = 0; c < 8; c++) { - if (ins & (1 << c)) { - *mask = 0xff << c; - return; - } - } -} - - -static int -picint_is_level(uint16_t irq) -{ - if (PCI) - return pci_irq_is_level(irq); - else { - if (irq < 8) - return (pic.icw1 & 8) ? 1 : 0; - else - return (pic2.icw1 & 8) ? 1 : 0; - } -} - - -static void -pic_autoeoi() -{ - int c; - - for (c = 0; c < 8; c++) { - if (pic.ins & ( 1 << c)) { - pic.ins &= ~(1 << c); - pic_update_mask(&pic.mask2, pic.ins); - - if (AT) { - if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= pic.icw3; - } - - if ((pic_current & (1 << c)) && picint_is_level(c)) { - if (((1 << c) != pic.icw3) || !AT) - pic.pend |= 1 << c; - } - - pic_updatepending(); - return; - } - } -} - - -void -pic_write(uint16_t addr, uint8_t val, void *priv) -{ - int c; - if (addr&1) { - switch (pic.icw) { - case 0: /*OCW1*/ - pic.mask=val; - pic_updatepending(); - break; - case 1: /*ICW2*/ - pic.vector=val&0xF8; - if (pic.icw1 & 2) pic.icw=3; - else pic.icw=2; - break; - case 2: /*ICW3*/ - pic.icw3 = val; - pic_log("PIC1 ICW3 now %02X\n", val); - if (pic.icw1 & 1) pic.icw=3; - else pic.icw=0; - break; - case 3: /*ICW4*/ - pic.icw4 = val; - pic.icw=0; - break; - } - } else { - if (val & 16) { /*ICW1*/ - pic.mask = 0; - pic.mask2=0; - pic.icw=1; - pic.icw1=val; - pic.ins = 0; - pic_updatepending(); - } - else if (!(val & 8)) { /*OCW2*/ - if ((val & 0xE0) == 0x60) { - pic.ins &= ~(1 << (val & 7)); - pic_update_mask(&pic.mask2, pic.ins); - if (AT) { - if (((val&7) == pic2.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= pic.icw3; - } - - if ((pic_current & (1 << (val & 7))) && picint_is_level(val & 7)) { - if ((((1 << (val & 7)) != pic.icw3) || !AT)) - pic.pend |= 1 << (val & 7); - } - - pic_updatepending(); - } else { - for (c = 0; c < 8; c++) { - if (pic.ins & (1 << c)) { - pic.ins &= ~(1 << c); - pic_update_mask(&pic.mask2, pic.ins); - - if (AT) { - if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= pic.icw3; - } - - if ((pic_current & (1 << c)) && picint_is_level(c)) { - if ((((1 << c) != pic.icw3) || !AT)) - pic.pend |= 1 << c; - } - - if (c==1 && keywaiting) - intclear&=~1; - pic_updatepending(); - return; - } - } - } - } else { /*OCW3*/ - if (val & 2) - pic.read=(val & 1); - } - } -} - - -uint8_t -pic_read(uint16_t addr, void *priv) -{ - if (addr & 1) { - pic_log("Read PIC mask %02X\n", pic.mask); - return pic.mask; - } - if (pic.read) { - pic_log("Read PIC ins %02X\n", pic.ins); - return pic.ins | (pic2.ins ? 4 : 0); - } - return pic.pend; -} - - -void -pic_init() -{ - io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL); -} - - -static void -pic2_autoeoi() -{ - int c; - - for (c = 0; c < 8; c++) { - if (pic2.ins & (1 << c)) { - pic2.ins &= ~(1 << c); - pic_update_mask(&pic2.mask2, pic2.ins); - - if (pic_current & (0x100 << c) && picint_is_level(c + 8)) { - pic2.pend |= (1 << c); - pic.pend |= (1 << pic2.icw3); - } - - pic_updatepending(); - return; - } - } -} - - -void -pic2_write(uint16_t addr, uint8_t val, void *priv) -{ - int c; - if (addr & 1) { - switch (pic2.icw) { - case 0: /*OCW1*/ - pic2.mask=val; - pic_updatepending(); - break; - case 1: /*ICW2*/ - pic2.vector=val & 0xF8; - pic_log("PIC2 vector now: %02X\n", pic2.vector); - if (pic2.icw1 & 2) pic2.icw=3; - else pic2.icw=2; - break; - case 2: /*ICW3*/ - pic2.icw3 = val; - pic_log("PIC2 ICW3 now %02X\n", val); - if (pic2.icw1 & 1) pic2.icw=3; - else pic2.icw=0; - break; - case 3: /*ICW4*/ - pic2.icw4 = val; - pic2.icw=0; - break; - } - } else { - if (val & 16) { /*ICW1*/ - pic2.mask = 0; - pic2.mask2=0; - pic2.icw=1; - pic2.icw1 = val; - pic2.ins = 0; - pic_updatepending(); - } else if (!(val & 8)) { /*OCW2*/ - if ((val & 0xE0) == 0x60) { - pic2.ins &= ~(1 << (val & 7)); - pic_update_mask(&pic2.mask2, pic2.ins); - - if (pic_current & (0x100 << (val & 7)) && picint_is_level((val & 7) + 8)) { - pic2.pend |= (1 << (val & 7)); - pic.pend |= (1 << pic2.icw3); - } - - pic_updatepending(); - } else { - for (c = 0; c < 8; c++) { - if (pic2.ins&(1<0xFF) { - if (!AT) - return; - - pic2.pend|=(num>>8); - if ((pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= (1 << pic2.icw3); - } else - pic.pend|=num; - - pic_updatepending(); - } -} - - -void -picint(uint16_t num) -{ - picint_common(num, 0); -} - - -void -picintlevel(uint16_t num) -{ - picint_common(num, 1); -} - - -void -picintc(uint16_t num) -{ - int c = 0; - - if (!num) { - pic_log("Attempting to lower null IRQ\n"); - return; - } - - if (AT && (num == pic.icw3) && (pic.icw3 == 4)) - num = 1 << 9; - - while (!(num & (1 << c))) - c++; - - if (AT && (num == pic.icw3) && (pic.icw3 != 4)) { - pic_log("Attempting to lower cascaded IRQ %i\n"); - return; - } - - if (pic_current & num) - pic_current &= ~num; - - pic_log("Lowering IRQ %i\n", c); - - if (num > 0xff) { - if (!AT) - return; - - pic2.pend &= ~(num >> 8); - if (!((pic2.pend&~pic2.mask)&~pic2.mask2)) - pic.pend &= ~(1 << pic2.icw3); - } else - pic.pend&=~num; - - pic_updatepending(); -} - - -static uint8_t -pic_process_interrupt(PIC* target_pic, int c) -{ - uint8_t pending = target_pic->pend & ~target_pic->mask; - - int pic_int = c & 7; - int pic_int_num = 1 << pic_int; - - if (pending & pic_int_num) { - target_pic->pend &= ~pic_int_num; - target_pic->ins |= pic_int_num; - pic_update_mask(&target_pic->mask2, target_pic->ins); - - if (c >= 8) { - pic.ins |= (1 << pic2.icw3); /*Cascade IRQ*/ - pic_update_mask(&pic.mask2, pic.ins); - } - - pic_updatepending(); - - if (target_pic->icw4 & 0x02) - (c >= 8) ? pic2_autoeoi() : pic_autoeoi(); - - if (!c) - pit_set_gate(&pit2, 0, 0); - - return pic_int + target_pic->vector; - } else - return 0xFF; -} - - -uint8_t -picinterrupt() -{ - int c, d; - uint8_t ret; - - for (c = 0; c <= 7; c++) { - if (AT && ((1 << c) == pic.icw3)) { - for (d = 8; d <= 15; d++) { - ret = pic_process_interrupt(&pic2, d); - if (ret != 0xFF) return ret; - } - } else { - ret = pic_process_interrupt(&pic, c); - if (ret != 0xFF) return ret; - } - } - return 0xFF; -} - - -void -dumppic() -{ - pic_log("PIC1 : MASK %02X PEND %02X INS %02X LEVEL %02X VECTOR %02X CASCADE %02X\n", pic.mask, pic.pend, pic.ins, (pic.icw1 & 8) ? 1 : 0, pic.vector, pic.icw3); - if (AT) - pic_log("PIC2 : MASK %02X PEND %02X INS %02X LEVEL %02X VECTOR %02X CASCADE %02X\n", pic2.mask, pic2.pend, pic2.ins, (pic2.icw1 & 8) ? 1 : 0, pic2.vector, pic2.icw3); -} diff --git a/src - Cópia/pic.h b/src - Cópia/pic.h deleted file mode 100644 index b300c11a9..000000000 --- a/src - Cópia/pic.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef EMU_PIC_H -# define EMU_PIC_H - - -typedef struct PIC { - uint8_t icw1,icw3,icw4,mask,ins,pend,mask2; - int icw; - uint8_t vector; - int read; -} PIC; - - -extern PIC pic, pic2; -extern int pic_intpending; - - -extern void pic_init(void); -extern void pic2_init(void); -extern void pic_reset(void); - -extern void picint(uint16_t num); -extern void picintlevel(uint16_t num); -extern void picintc(uint16_t num); -extern uint8_t picinterrupt(void); -extern void picclear(int num); -extern void dumppic(void); - - -#endif /*EMU_PIC_H*/ diff --git a/src - Cópia/piix.h b/src - Cópia/piix.h deleted file mode 100644 index 1cfc22c8a..000000000 --- a/src - Cópia/piix.h +++ /dev/null @@ -1,26 +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. - * - * Emulation of the Intel PIIX and PIIX3 Xcelerators. - * - * Emulation core dispatcher. - * - * Version: @(#)piix.h 1.0.3 2018/05/11 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t piix_device; -extern const device_t piix_pb640_device; -extern const device_t piix3_device; - -extern int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); -extern int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); - -extern void piix_bus_master_set_irq(int channel, void *priv); diff --git a/src - Cópia/pit.c b/src - Cópia/pit.c deleted file mode 100644 index 3a7565c25..000000000 --- a/src - Cópia/pit.c +++ /dev/null @@ -1,651 +0,0 @@ -/*IBM AT - - Write B0 - Write aa55 - Expects aa55 back*/ -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "dma.h" -#include "io.h" -#include "nmi.h" -#include "pic.h" -#include "pit.h" -#include "ppi.h" -#include "device.h" -#include "timer.h" -#include "machine/machine.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" - - -/*B0 to 40, two writes to 43, then two reads - value does not change!*/ -/*B4 to 40, two writes to 43, then two reads - value _does_ change!*/ -int64_t displine; - -PIT pit, - pit2; -float cpuclock; -float isa_timing, bus_timing; - -double PITCONST; -float CGACONST; -float MDACONST; -float VGACONST1, - VGACONST2; -float RTCCONST; - -int64_t firsttime=1; -void setrtcconst(float clock) -{ - RTCCONST=clock/32768.0; - TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); -} - -void setpitclock(float clock) -{ - cpuclock=clock; - PITCONST=clock/(1193181.0 + (2.0 / 3.0)); - CGACONST=(clock/(19687503.0/11.0)); - MDACONST=(clock/2032125.0); - VGACONST1=(clock/25175000.0); - VGACONST2=(clock/28322000.0); - isa_timing = clock/8000000.0; - bus_timing = clock/(double)cpu_busspeed; - video_update_timing(); - - xt_cpu_multi = (int64_t)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - /* RTCCONST=clock/32768.0; - TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); */ - device_speed_changed(); -} - -void pit_reset(PIT *pit) -{ - void (*old_set_out_funcs[3])(int new_out, int old_out); - PIT_nr old_pit_nr[3]; - - memcpy(old_set_out_funcs, pit->set_out_funcs, 3 * sizeof(void *)); - memcpy(old_pit_nr, pit->pit_nr, 3 * sizeof(PIT_nr)); - memset(pit, 0, sizeof(PIT)); - memcpy(pit->set_out_funcs, old_set_out_funcs, 3 * sizeof(void *)); - memcpy(pit->pit_nr, old_pit_nr, 3 * sizeof(PIT_nr)); - - pit->l[0] = 0xFFFF; pit->c[0] = 0xFFFF*PITCONST; - pit->l[1] = 0xFFFF; pit->c[1] = 0xFFFF*PITCONST; - pit->l[2] = 0xFFFF; pit->c[2] = 0xFFFF*PITCONST; - pit->m[0] = pit->m[1] = pit->m[2] = 0; - pit->ctrls[0] = pit->ctrls[1] = pit->ctrls[2] = 0; - pit->thit[0]=1; - pit->gate[0] = pit->gate[1] = 1; - pit->gate[2] = 0; - pit->using_timer[0] = pit->using_timer[1] = pit->using_timer[2] = 1; -} - -void clearpit() -{ - pit.c[0]=(pit.l[0]<<2); -} - -float pit_timer0_freq() -{ - if (pit.l[0]) - return (1193181.0 + (2.0 / 3.0))/(float)pit.l[0]; - else - return (1193181.0 + (2.0 / 3.0))/(float)0x10000; -} - -static void pit_set_out(PIT *pit, int t, int out) -{ - pit->set_out_funcs[t](out, pit->out[t]); - pit->out[t] = out; -} - -static void pit_load(PIT *pit, int t) -{ - int l = pit->l[t] ? pit->l[t] : 0x10000; - timer_clock(); - pit->newcount[t] = 0; - pit->disabled[t] = 0; - switch (pit->m[t]) - { - case 0: /*Interrupt on terminal count*/ - pit->count[t] = l; - pit->c[t] = (int64_t)((((int64_t) l) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 0); - pit->thit[t] = 0; - pit->enabled[t] = pit->gate[t]; - break; - case 1: /*Hardware retriggerable one-shot*/ - pit->enabled[t] = 1; - break; - case 2: /*Rate generator*/ - if (pit->initial[t]) - { - pit->count[t] = l - 1; - pit->c[t] = (int64_t)(((((int64_t) l) - 1LL) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 1); - pit->thit[t] = 0; - } - pit->enabled[t] = pit->gate[t]; - break; - case 3: /*Square wave mode*/ - if (pit->initial[t]) - { - pit->count[t] = l; - pit->c[t] = (int64_t)((((((int64_t) l) + 1LL) >> 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 1); - pit->thit[t] = 0; - } - pit->enabled[t] = pit->gate[t]; - break; - case 4: /*Software triggered stobe*/ - if (!pit->thit[t] && !pit->initial[t]) - pit->newcount[t] = 1; - else - { - pit->count[t] = l; - pit->c[t] = (int64_t)((l << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 0); - pit->thit[t] = 0; - } - pit->enabled[t] = pit->gate[t]; - break; - case 5: /*Hardware triggered stobe*/ - pit->enabled[t] = 1; - break; - } - pit->initial[t] = 0; - pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; - timer_update_outstanding(); -} - -void pit_set_gate_no_timer(PIT *pit, int t, int gate) -{ - int64_t l = pit->l[t] ? pit->l[t] : 0x10000; - - if (pit->disabled[t]) - { - pit->gate[t] = gate; - return; - } - - switch (pit->m[t]) - { - case 0: /*Interrupt on terminal count*/ - case 4: /*Software triggered stobe*/ - pit->enabled[t] = gate; - break; - case 1: /*Hardware retriggerable one-shot*/ - case 5: /*Hardware triggered stobe*/ - if (gate && !pit->gate[t]) - { - pit->count[t] = l; - pit->c[t] = (int64_t)((((int64_t) l) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 0); - pit->thit[t] = 0; - pit->enabled[t] = 1; - } - break; - case 2: /*Rate generator*/ - if (gate && !pit->gate[t]) - { - pit->count[t] = l - 1; - pit->c[t] = (int64_t)(((((int64_t) l) - 1LL) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 1); - pit->thit[t] = 0; - } - pit->enabled[t] = gate; - break; - case 3: /*Square wave mode*/ - if (gate && !pit->gate[t]) - { - pit->count[t] = l; - pit->c[t] = (int64_t)((((((int64_t) l) + 1LL) >> 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 1); - pit->thit[t] = 0; - } - pit->enabled[t] = gate; - break; - } - pit->gate[t] = gate; - pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; -} - -void pit_set_gate(PIT *pit, int t, int gate) -{ - if (pit->disabled[t]) - { - pit->gate[t] = gate; - return; - } - - timer_process(); - - pit_set_gate_no_timer(pit, t, gate); - - timer_update_outstanding(); -} - -static void pit_over(PIT *pit, int t) -{ - int64_t l = pit->l[t] ? pit->l[t] : 0x10000; - if (pit->disabled[t]) - { - pit->count[t] += 0xffff; - pit->c[t] += (int64_t)((0xffffLL << TIMER_SHIFT) * PITCONST); - return; - } - - switch (pit->m[t]) - { - case 0: /*Interrupt on terminal count*/ - case 1: /*Hardware retriggerable one-shot*/ - if (!pit->thit[t]) - pit_set_out(pit, t, 1); - pit->thit[t] = 1; - pit->count[t] += 0xffff; - pit->c[t] += (int64_t)((0xffffLL << TIMER_SHIFT) * PITCONST); - break; - case 2: /*Rate generator*/ - pit->count[t] += l; - pit->c[t] += (int64_t)((((int64_t) l) << TIMER_SHIFT) * PITCONST); - pit_set_out(pit, t, 0); - pit_set_out(pit, t, 1); - break; - case 3: /*Square wave mode*/ - if (pit->out[t]) - { - pit_set_out(pit, t, 0); - pit->count[t] += (l >> 1); - pit->c[t] += (int64_t)(((((int64_t) l) >> 1) << TIMER_SHIFT) * PITCONST); - } - else - { - pit_set_out(pit, t, 1); - pit->count[t] += ((l + 1) >> 1); - pit->c[t] = (int64_t)((((((int64_t) l) + 1LL) >> 1) << TIMER_SHIFT) * PITCONST); - } - break; - case 4: /*Software triggered strove*/ - if (!pit->thit[t]) - { - pit_set_out(pit, t, 0); - pit_set_out(pit, t, 1); - } - if (pit->newcount[t]) - { - pit->newcount[t] = 0; - pit->count[t] += l; - pit->c[t] += (int64_t)((((int64_t) l) << TIMER_SHIFT) * PITCONST); - } - else - { - pit->thit[t] = 1; - pit->count[t] += 0xffff; - pit->c[t] += (int64_t)((0xffffLL << TIMER_SHIFT) * PITCONST); - } - break; - case 5: /*Hardware triggered strove*/ - if (!pit->thit[t]) - { - pit_set_out(pit, t, 0); - pit_set_out(pit, t, 1); - } - pit->thit[t] = 1; - pit->count[t] += 0xffff; - pit->c[t] += (int64_t)((0xffffLL << TIMER_SHIFT) * PITCONST); - break; - } - pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; -} - -int pit_get_timer_0() -{ - int read = (int)((int64_t)((pit.c[0] + ((1LL << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT); - if (pit.m[0] == 2) - read++; - if (read < 0) - read = 0; - if (read > 0x10000) - read = 0x10000; - if (pit.m[0] == 3) - read <<= 1; - return read; -} - -static int pit_read_timer(PIT *pit, int t) -{ - timer_clock(); - if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t])) - { - int read = (int)((int64_t)((pit->c[t] + ((1LL << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT); - if (pit->m[t] == 2) - read++; - if (read < 0) - read = 0; - if (read > 0x10000) - read = 0x10000; - if (pit->m[t] == 3) - read <<= 1; - return read; - } - if (pit->m[t] == 2) - return pit->count[t] + 1; - return pit->count[t]; -} - -void pit_write(uint16_t addr, uint8_t val, void *p) -{ - PIT *pit = (PIT *)p; - int t; - - switch (addr&3) - { - case 3: /*CTRL*/ - if ((val&0xC0)==0xC0) - { - if (!(val&0x20)) - { - if (val & 2) - pit->rl[0] = pit_read_timer(pit, 0); - if (val & 4) - pit->rl[1] = pit_read_timer(pit, 1); - if (val & 8) - pit->rl[2] = pit_read_timer(pit, 2); - } - if (!(val & 0x10)) - { - if (val & 2) - { - pit->read_status[0] = (pit->ctrls[0] & 0x3f) | (pit->out[0] ? 0x80 : 0); - pit->do_read_status[0] = 1; - } - if (val & 4) - { - pit->read_status[1] = (pit->ctrls[1] & 0x3f) | (pit->out[1] ? 0x80 : 0); - pit->do_read_status[1] = 1; - } - if (val & 8) - { - pit->read_status[2] = (pit->ctrls[2] & 0x3f) | (pit->out[2] ? 0x80 : 0); - pit->do_read_status[2] = 1; - } - } - return; - } - t = val >> 6; - pit->ctrl=val; - if ((val>>7)==3) - { - return; - } - if (!(pit->ctrl&0x30)) - { - pit->rl[t] = pit_read_timer(pit, t); - pit->ctrl |= 0x30; - pit->rereadlatch[t] = 0; - pit->rm[t] = 3; - pit->latched[t] = 1; - } - else - { - pit->ctrls[t] = val; - pit->rm[t]=pit->wm[t]=(pit->ctrl>>4)&3; - pit->m[t]=(val>>1)&7; - if (pit->m[t]>5) - pit->m[t]&=3; - if (!(pit->rm[t])) - { - pit->rm[t]=3; - pit->rl[t] = pit_read_timer(pit, t); - } - pit->rereadlatch[t]=1; - pit->initial[t] = 1; - if (!pit->m[t]) - pit_set_out(pit, t, 0); - else - pit_set_out(pit, t, 1); - pit->disabled[t] = 1; - } - pit->wp=0; - pit->thit[t]=0; - break; - case 0: case 1: case 2: /*Timers*/ - t=addr&3; - switch (pit->wm[t]) - { - case 1: - pit->l[t]=val; - pit_load(pit, t); - break; - case 2: - pit->l[t]=(val<<8); - pit_load(pit, t); - break; - case 0: - pit->l[t]&=0xFF; - pit->l[t]|=(val<<8); - pit_load(pit, t); - pit->wm[t]=3; - break; - case 3: - pit->l[t]&=0xFF00; - pit->l[t]|=val; - pit->wm[t]=0; - break; - } - speakval=(((float)pit->l[2]/(float)pit->l[0])*0x4000)-0x2000; - if (speakval>0x2000) speakval=0x2000; - break; - } -} - -uint8_t pit_read(uint16_t addr, void *p) -{ - PIT *pit = (PIT *)p; - int64_t t; - uint8_t temp = 0xff; - switch (addr&3) - { - case 0: case 1: case 2: /*Timers*/ - t = addr & 3; - if (pit->do_read_status[t]) - { - pit->do_read_status[t] = 0; - temp = pit->read_status[t]; - break; - } - if (pit->rereadlatch[addr & 3] && !pit->latched[addr & 3]) - { - pit->rereadlatch[addr & 3] = 0; - pit->rl[t] = pit_read_timer(pit, t); - } - switch (pit->rm[addr & 3]) - { - case 0: - temp = pit->rl[addr & 3] >> 8; - pit->rm[addr & 3] = 3; - pit->latched[addr & 3] = 0; - pit->rereadlatch[addr & 3] = 1; - break; - case 1: - temp = (pit->rl[addr & 3]) & 0xFF; - pit->latched[addr & 3] = 0; - pit->rereadlatch[addr & 3] = 1; - break; - case 2: - temp = (pit->rl[addr & 3]) >> 8; - pit->latched[addr & 3] = 0; - pit->rereadlatch[addr & 3] = 1; - break; - case 3: - temp = (pit->rl[addr & 3]) & 0xFF; - if (pit->m[addr & 3] & 0x80) - pit->m[addr & 3] &= 7; - else - pit->rm[addr & 3] = 0; - break; - } - break; - case 3: /*Control*/ - temp = pit->ctrl; - break; - } - return temp; -} - -void pit_timer_over(void *p) -{ - PIT_nr *pit_nr = (PIT_nr *)p; - PIT *pit = pit_nr->pit; - int64_t timer = pit_nr->nr; - - pit_over(pit, timer); -} - -void pit_clock(PIT *pit, int t) -{ - if (pit->thit[t] || !pit->enabled[t]) - return; - - if (pit->using_timer[t]) - return; - - pit->count[t] -= (pit->m[t] == 3) ? 2 : 1; - if (!pit->count[t]) - pit_over(pit, t); -} - -void pit_set_using_timer(PIT *pit, int t, int using_timer) -{ - timer_process(); - if (pit->using_timer[t] && !using_timer) - pit->count[t] = pit_read_timer(pit, t); - if (!pit->using_timer[t] && using_timer) - pit->c[t] = (int64_t)((((int64_t) pit->count[t]) << TIMER_SHIFT) * PITCONST); - pit->using_timer[t] = using_timer; - pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; - timer_update_outstanding(); -} - -void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out)) -{ - pit->set_out_funcs[t] = func; -} - -void pit_null_timer(int new_out, int old_out) -{ -} - -void pit_irq0_timer(int new_out, int old_out) -{ - if (new_out && !old_out) - picint(1); - if (!new_out) - picintc(1); -} - -void pit_irq0_timer_pcjr(int new_out, int old_out) -{ - if (new_out && !old_out) - { - picint(1); - pit_clock(&pit, 1); - } - if (!new_out) - picintc(1); -} - -void pit_irq0_ps2(int new_out, int old_out) -{ - if (new_out && !old_out) - { - picint(1); - pit_set_gate_no_timer(&pit2, 0, 1); - } - if (!new_out) - picintc(1); - if (!new_out && old_out) - pit_clock(&pit2, 0); -} - -void pit_refresh_timer_xt(int new_out, int old_out) -{ - if (new_out && !old_out) - dma_channel_read(0); -} - -void pit_refresh_timer_at(int new_out, int old_out) -{ - if (new_out && !old_out) - ppi.pb ^= 0x10; -} - -void pit_speaker_timer(int new_out, int old_out) -{ - int64_t l; - - speaker_update(); - - l = pit.l[2] ? pit.l[2] : 0x10000; - if (l < 25) - speakon = 0; - else - speakon = new_out; - ppispeakon = new_out; -} - - -void pit_nmi_ps2(int new_out, int old_out) -{ - nmi = new_out; - if (nmi) - nmi_auto_clear = 1; -} - -void pit_init() -{ - pit_reset(&pit); - - io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit); - pit.gate[0] = pit.gate[1] = 1; - pit.gate[2] = 0; - pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1; - - pit.pit_nr[0].nr = 0; - pit.pit_nr[1].nr = 1; - pit.pit_nr[2].nr = 2; - pit.pit_nr[0].pit = pit.pit_nr[1].pit = pit.pit_nr[2].pit = &pit; - - timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)&pit.pit_nr[0]); - timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)&pit.pit_nr[1]); - timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)&pit.pit_nr[2]); - - pit_set_out_func(&pit, 0, pit_irq0_timer); - pit_set_out_func(&pit, 1, pit_null_timer); - pit_set_out_func(&pit, 2, pit_speaker_timer); -} - -void pit_ps2_init() -{ - pit_reset(&pit2); - - io_sethandler(0x0044, 0x0001, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit2); - io_sethandler(0x0047, 0x0001, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit2); - - pit2.gate[0] = 0; - pit2.using_timer[0] = 0; - pit2.disabled[0] = 1; - - pit2.pit_nr[0].nr = 0; - pit2.pit_nr[0].pit = &pit2; - - timer_add(pit_timer_over, &pit2.c[0], &pit2.running[0], (void *)&pit2.pit_nr[0]); - - pit_set_out_func(&pit, 0, pit_irq0_ps2); - pit_set_out_func(&pit2, 0, pit_nmi_ps2); -} diff --git a/src - Cópia/pit.h b/src - Cópia/pit.h deleted file mode 100644 index 00297eb26..000000000 --- a/src - Cópia/pit.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef EMU_PIT_H -# define EMU_PIT_H - - -typedef struct { - int64_t nr; - struct PIT *pit; -} PIT_nr; - -typedef struct PIT { - uint32_t l[3]; - int64_t c[3]; - uint8_t m[3]; - uint8_t ctrl, - ctrls[3]; - int wp, - rm[3], - wm[3]; - uint16_t rl[3]; - int thit[3]; - int delay[3]; - int rereadlatch[3]; - int gate[3]; - int out[3]; - int64_t running[3]; - int enabled[3]; - int newcount[3]; - int count[3]; - int using_timer[3]; - int initial[3]; - int latched[3]; - int disabled[3]; - - uint8_t read_status[3]; - int do_read_status[3]; - - PIT_nr pit_nr[3]; - - void (*set_out_funcs[3])(int new_out, int old_out); -} PIT; - - -extern PIT pit, - pit2; -extern double PITCONST; -extern float CGACONST, - MDACONST, - VGACONST1, - VGACONST2, - RTCCONST; - - -extern void pit_init(void); -extern void pit_ps2_init(void); -extern void pit_reset(PIT *pit); -extern void pit_set_gate(PIT *pit, int channel, int gate); -extern void pit_set_using_timer(PIT *pit, int t, int using_timer); -extern void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out)); -extern void pit_clock(PIT *pit, int t); - -extern void setrtcconst(float clock); - -extern void setpitclock(float clock); -extern float pit_timer0_freq(void); - -extern void pit_null_timer(int new_out, int old_out); -extern void pit_irq0_timer(int new_out, int old_out); -extern void pit_irq0_timer_pcjr(int new_out, int old_out); -extern void pit_refresh_timer_xt(int new_out, int old_out); -extern void pit_refresh_timer_at(int new_out, int old_out); -extern void pit_speaker_timer(int new_out, int old_out); - - -#endif /*EMU_PIT_H*/ diff --git a/src - Cópia/plat.h b/src - Cópia/plat.h deleted file mode 100644 index fc7e5e252..000000000 --- a/src - Cópia/plat.h +++ /dev/null @@ -1,152 +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. - * - * Define the various platform support functions. - * - * Version: @(#)plat.h 1.0.26 2018/02/14 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_PLAT_H -# define EMU_PLAT_H - -#ifndef GLOBAL -# define GLOBAL extern -#endif - -/* String ID numbers. */ -#include "lang/language.h" - -/* The Win32 API uses _wcsicmp. */ -#ifdef _WIN32 -# define wcscasecmp _wcsicmp -#endif - -#if defined(UNIX) && defined(FREEBSD) -/* FreeBSD has largefile by default. */ -# define fopen64 fopen -# define fseeko64 fseeko -# define ftello64 ftello -# define off64_t off_t -#endif - - -/* A hack (GCC-specific?) to allow us to ignore unused parameters. */ -#define UNUSED(arg) __attribute__((unused))arg - -/* Return the size (in wchar's) of a wchar_t array. */ -#define sizeof_w(x) (sizeof((x)) / sizeof(wchar_t)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global variables residing in the platform module. */ -GLOBAL int dopause, /* system is paused */ - doresize, /* screen resize requested */ - quited, /* system exit requested */ - mouse_capture; /* mouse is captured in app */ -GLOBAL uint64_t timer_freq; -GLOBAL int infocus; -GLOBAL char emu_version[128]; /* version ID string */ -GLOBAL int rctrl_is_lalt; -GLOBAL int update_icons; - -GLOBAL int unscaled_size_x, /* current unscaled size X */ - unscaled_size_y; /* current unscaled size Y */ - -/* System-related functions. */ -extern wchar_t *fix_exe_path(wchar_t *str); -extern FILE *plat_fopen(wchar_t *path, wchar_t *mode); -extern void plat_remove(wchar_t *path); -extern int plat_getcwd(wchar_t *bufp, int max); -extern int plat_chdir(wchar_t *path); -extern void plat_get_exe_name(wchar_t *s, int size); -extern wchar_t *plat_get_filename(wchar_t *s); -extern wchar_t *plat_get_extension(wchar_t *s); -extern void plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2); -extern void plat_put_backslash(wchar_t *s); -extern void plat_path_slash(wchar_t *path); -extern int plat_path_abs(wchar_t *path); -extern int plat_dir_check(wchar_t *path); -extern int plat_dir_create(wchar_t *path); -extern uint64_t plat_timer_read(void); -extern uint32_t plat_get_ticks(void); -extern void plat_delay_ms(uint32_t count); -extern void plat_pause(int p); -extern void plat_mouse_capture(int on); -extern int plat_vidapi(char *name); -extern char *plat_vidapi_name(int api); -extern int plat_setvid(int api); -extern void plat_vidsize(int x, int y); -extern void plat_setfullscreen(int on); -extern void plat_resize(int x, int y); - - -/* Resource management. */ -extern void set_language(int id); -extern wchar_t *plat_get_string(int id); - - -/* Emulator start/stop support functions. */ -extern void do_start(void); -extern void do_stop(void); - - -/* Platform-specific device support. */ -extern uint8_t host_cdrom_drive_available[26]; -extern uint8_t host_cdrom_drive_available_num; - -#ifdef USE_IOCTL -extern void cdrom_init_host_drives(void); -#endif -extern void cdrom_eject(uint8_t id); -extern void cdrom_reload(uint8_t id); -extern void zip_eject(uint8_t id); -extern void zip_reload(uint8_t id); -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); -extern void ioctl_close(uint8_t id); - - -/* Thread support. */ -typedef void thread_t; -typedef void event_t; -typedef void mutex_t; - -extern thread_t *thread_create(void (*thread_func)(void *param), void *param); -extern void thread_kill(thread_t *arg); -extern int thread_wait(thread_t *arg, int timeout); -extern event_t *thread_create_event(void); -extern void thread_set_event(event_t *arg); -extern void thread_reset_event(event_t *arg); -extern int thread_wait_event(event_t *arg, int timeout); -extern void thread_destroy_event(event_t *arg); - -extern mutex_t *thread_create_mutex(wchar_t *name); -extern void thread_close_mutex(mutex_t *arg); -extern int thread_wait_mutex(mutex_t *arg); -extern int thread_release_mutex(mutex_t *mutex); - - -/* Other stuff. */ -extern void startblit(void); -extern void endblit(void); -extern void take_screenshot(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_PLAT_H*/ diff --git a/src - Cópia/plat_dynld.h b/src - Cópia/plat_dynld.h deleted file mode 100644 index 74af2e8f8..000000000 --- a/src - Cópia/plat_dynld.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Define the Dynamic Module Loader interface. - * - * Version: @(#)plat_dynld.h 1.0.1 2017/05/21 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen - */ -#ifndef PLAT_DYNLD_H -# define PLAT_DYNLD_H - - -typedef struct { - const char *name; - void *func; -} dllimp_t; - - -extern void *dynld_module(const char *, dllimp_t *); -extern void dynld_close(void *); - - -#endif /*PLAT_DYNLD_H*/ diff --git a/src - Cópia/plat_midi.h b/src - Cópia/plat_midi.h deleted file mode 100644 index 1d167c475..000000000 --- a/src - Cópia/plat_midi.h +++ /dev/null @@ -1,8 +0,0 @@ -extern void plat_midi_init(void); -extern void plat_midi_close(void); - -extern void plat_midi_play_msg(uint8_t* val); -extern void plat_midi_play_sysex(uint8_t* data, unsigned int len); -extern int plat_midi_write(uint8_t val); -extern int plat_midi_get_num_devs(); -extern void plat_midi_get_dev_name(int num, char *s); diff --git a/src - Cópia/ppi.c b/src - Cópia/ppi.c deleted file mode 100644 index ef81ee19c..000000000 --- a/src - Cópia/ppi.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -/*IBM 5150 cassette nonsense - Calls F979 twice - Expects CX to be nonzero, BX >$410 and <$540 - CX is loops between bit 4 of $62 changing - BX is timer difference between calls - */ -#include -#include -#include -#include -#include "pit.h" -#include "ppi.h" - - -PPI ppi; -int ppispeakon; - - -void ppi_reset(void) -{ - ppi.pa=0x0; - ppi.pb=0x40; -} diff --git a/src - Cópia/ppi.h b/src - Cópia/ppi.h deleted file mode 100644 index a46a407f5..000000000 --- a/src - Cópia/ppi.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef EMU_PPI_H -# define EMU_PPI_H - - -typedef struct PPI { - int s2; - uint8_t pa,pb; -} PPI; - - -extern int ppispeakon; -extern PPI ppi; - - -extern void ppi_reset(void); - - -#endif /*EMU_PPI_H*/ diff --git a/src - Cópia/random.c b/src - Cópia/random.c deleted file mode 100644 index 9d7f1b229..000000000 --- a/src - Cópia/random.c +++ /dev/null @@ -1,92 +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. - * - * A better random number generation, used for floppy weak bits - * and network MAC address generation. - * - * Version: @(#)random.c 1.0.3 2017/09/24 - * - * Author: Miran Grca, - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "random.h" - - -uint32_t preconst = 0x6ED9EBA1; - - -static __inline__ uint32_t rotl32c (uint32_t x, uint32_t n) -{ -#if 0 - assert (n<32); -#endif - return (x<>(-n&31)); -} - -static __inline__ uint32_t rotr32c (uint32_t x, uint32_t n) -{ -#if 0 - assert (n<32); -#endif - return (x>>n) | (x<<(-n&31)); -} - -#define ROTATE_LEFT rotl32c - -#define ROTATE_RIGHT rotr32c - -static __inline__ unsigned long long rdtsc(void) -{ - unsigned hi, lo; -#ifdef __MSC__ - __asm { - rdtsc - mov hi, edx ; EDX:EAX is already standard return!! - mov lo, eax - } -#else - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); -#endif - return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); -} - -static uint32_t RDTSC(void) -{ - return (uint32_t) (rdtsc()); -} - - -static void random_twist(uint32_t *val) -{ - *val = ROTATE_LEFT(*val, rand() % 32); - *val ^= 0x5A827999; - *val = ROTATE_RIGHT(*val, rand() % 32); - *val ^= 0x4ED32706; -} - - -uint8_t random_generate(void) -{ - uint16_t r = 0; - r = (rand() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256; - random_twist(&preconst); - return (r & 0xff); -} - - -void random_init(void) -{ - uint32_t seed = RDTSC(); - srand(seed); - return; -} diff --git a/src - Cópia/random.h b/src - Cópia/random.h deleted file mode 100644 index d6f56bca9..000000000 --- a/src - Cópia/random.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. - * - * A better random number generation, used for floppy weak bits - * and network MAC address generation. - * - * Version: @(#)random.h 1.0.2 2017/09/03 - * - * Author: Miran Grca, - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_RANDOM_H -# define EMU_RANDOM_H - - -extern uint8_t random_generate(void); -extern void random_init(void); - - -#endif /*EMU_RANDOM_H*/ diff --git a/src - Cópia/rom.c b/src - Cópia/rom.c deleted file mode 100644 index 0fbb102a4..000000000 --- a/src - Cópia/rom.c +++ /dev/null @@ -1,968 +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 ROM image files. - * - * NOTES: - pc2386 BIOS is corrupt (JMP at F000:FFF0 points to RAM) - * - pc2386 video BIOS is underdumped (16k instead of 24k) - * - c386sx16 BIOS fails checksum - * - the loadfont() calls should be done elsewhere - * - * Version: @(#)rom.c 1.0.37 2018/05/20 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "cpu/cpu.h" -#include "mem.h" -#include "rom.h" -#include "video/video.h" /* for loadfont() */ -#include "plat.h" -#include "machine/m_xt_xi8088.h" - - -int romspresent[ROM_MAX]; - - -#ifdef ENABLE_ROM_LOG -int rom_do_log = ENABLE_ROM_LOG; -#endif - - -static void -rom_log(const char *format, ...) -{ -#ifdef ENABLE_ROM_LOG - va_list ap; - - if (rom_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -FILE * -rom_fopen(wchar_t *fn, wchar_t *mode) -{ - wchar_t temp[1024]; - - wcscpy(temp, exe_path); - plat_put_backslash(temp); - wcscat(temp, fn); - - return(plat_fopen(temp, mode)); -} - - -int -rom_getfile(wchar_t *fn, wchar_t *s, int size) -{ - FILE *f; - - wcscpy(s, exe_path); - plat_put_backslash(s); - wcscat(s, fn); - - f = plat_fopen(s, L"rb"); - if (f != NULL) { - (void)fclose(f); - return(1); - } - - return(0); -} - - -int -rom_present(wchar_t *fn) -{ - FILE *f; - - f = rom_fopen(fn, L"rb"); - if (f != NULL) { - (void)fclose(f); - return(1); - } - - return(0); -} - - -uint8_t -rom_read(uint32_t addr, void *priv) -{ - rom_t *rom = (rom_t *)priv; - -#ifdef ROM_TRACE - if (rom->mapping.base==ROM_TRACE) - rom_log("ROM: read byte from BIOS at %06lX\n", addr); -#endif - - return(rom->rom[addr & rom->mask]); -} - - -uint16_t -rom_readw(uint32_t addr, void *priv) -{ - rom_t *rom = (rom_t *)priv; - -#ifdef ROM_TRACE - if (rom->mapping.base==ROM_TRACE) - rom_log("ROM: read word from BIOS at %06lX\n", addr); -#endif - - return(*(uint16_t *)&rom->rom[addr & rom->mask]); -} - - -uint32_t -rom_readl(uint32_t addr, void *priv) -{ - rom_t *rom = (rom_t *)priv; - -#ifdef ROM_TRACE - if (rom->mapping.base==ROM_TRACE) - rom_log("ROM: read long from BIOS at %06lX\n", addr); -#endif - - return(*(uint32_t *)&rom->rom[addr & rom->mask]); -} - - -/* Load a ROM BIOS from its chips, interleaved mode. */ -int -rom_load_linear(wchar_t *fn, uint32_t addr, int sz, int off, uint8_t *ptr) -{ - FILE *f = rom_fopen(fn, L"rb"); - - if (f == NULL) { - rom_log("ROM: image '%ls' not found\n", fn); - return(0); - } - - /* Make sure we only look at the base-256K offset. */ - if (addr >= 0x40000) - { - addr = 0; - } - else - { - addr &= 0x03ffff; - } - - (void)fseek(f, off, SEEK_SET); - (void)fread(ptr+addr, sz, 1, f); - (void)fclose(f); - - return(1); -} - - -/* Load a ROM BIOS from its chips, linear mode with high bit flipped. */ -int -rom_load_linear_inverted(wchar_t *fn, uint32_t addr, int sz, int off, uint8_t *ptr) -{ - FILE *f = rom_fopen(fn, L"rb"); - - if (f == NULL) { - rom_log("ROM: image '%ls' not found\n", fn); - return(0); - } - - /* Make sure we only look at the base-256K offset. */ - if (addr >= 0x40000) - { - addr = 0; - } - else - { - addr &= 0x03ffff; - } - - (void)fseek(f, 0, SEEK_END); - if (ftell(f) < sz) { - (void)fclose(f); - return(0); - } - - (void)fseek(f, off, SEEK_SET); - (void)fread(ptr+addr+0x10000, sz >> 1, 1, f); - (void)fread(ptr+addr, sz >> 1, 1, f); - (void)fclose(f); - - return(1); -} - - -/* Load a ROM BIOS from its chips, interleaved mode. */ -int -rom_load_interleaved(wchar_t *fnl, wchar_t *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) -{ - FILE *fl = rom_fopen(fnl, L"rb"); - FILE *fh = rom_fopen(fnh, L"rb"); - int c; - - if (fl == NULL || fh == NULL) { - if (fl == NULL) rom_log("ROM: image '%ls' not found\n", fnl); - else (void)fclose(fl); - if (fh == NULL) rom_log("ROM: image '%ls' not found\n", fnh); - else (void)fclose(fh); - - return(0); - } - - /* Make sure we only look at the base-256K offset. */ - if (addr >= 0x40000) - { - addr = 0; - } - else - { - addr &= 0x03ffff; - } - - (void)fseek(fl, off, SEEK_SET); - (void)fseek(fh, off, SEEK_SET); - for (c=0; crom = malloc(sz); - memset(rom->rom, 0xff, sz); - - /* Load the image file into the buffer. */ - if (! rom_load_linear(fn, addr, sz, off, rom->rom)) { - /* Nope.. clean up. */ - free(rom->rom); - rom->rom = NULL; - return(-1); - } - - rom->mask = mask; - - mem_mapping_add(&rom->mapping, - addr, sz, - rom_read, rom_readw, rom_readl, - mem_write_null, mem_write_nullw, mem_write_nulll, - rom->rom, flags | MEM_MAPPING_ROM, rom); - - return(0); -} - - -int -rom_init_interleaved(rom_t *rom, wchar_t *fnl, wchar_t *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags) -{ - /* Allocate a buffer for the image. */ - rom->rom = malloc(sz); - memset(rom->rom, 0xff, sz); - - /* Load the image file into the buffer. */ - if (! rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) { - /* Nope.. clean up. */ - free(rom->rom); - rom->rom = NULL; - return(-1); - } - - rom->mask = mask; - - mem_mapping_add(&rom->mapping, - addr, sz, - rom_read, rom_readw, rom_readl, - mem_write_null, mem_write_nullw, mem_write_nulll, - rom->rom, flags | MEM_MAPPING_ROM, rom); - - return(0); -} - - -/* Load the ROM BIOS image(s) for the selected machine into memory. */ -int -rom_load_bios(int rom_id) -{ - FILE *f; - - loadfont(L"roms/video/mda/mda.rom", 0); - - /* If not done yet, allocate a 128KB buffer for the BIOS ROM. */ - if (rom == NULL) - rom = (uint8_t *)malloc(131072); - memset(rom, 0xff, 131072); - - /* Default to a 64K ROM BIOS image. */ - biosmask = 0xffff; - - /* Zap the BIOS ROM EXTENSION area. */ - memset(romext, 0xff, 0x8000); - mem_mapping_disable(&romext_mapping); - - switch (rom_id) { - case ROM_IBMPC: /* IBM PC */ - if (! rom_load_linear( - L"roms/machines/ibmpc/pc102782.bin", - 0x00e000, 8192, 0, rom)) break; - - /* Try to load the (full) BASIC ROM. */ - if (rom_load_linear( - L"roms/machines/ibmpc/ibm-basic-1.10.rom", - 0x006000, 32768, 0, rom)) return(1); - - /* Nope. Try to load the first BASIC ROM image. */ - if (! rom_load_linear( - L"roms/machines/ibmpc/basicc11.f6", - 0x006000, 8192, 0, rom)) return(1); /* nope */ - if (! rom_load_linear( - L"roms/machines/ibmpc/basicc11.f8", - 0x008000, 8192, 0, rom)) break; /* nope */ - if (! rom_load_linear( - L"roms/machines/ibmpc/basicc11.fa", - 0x00a000, 8192, 0, rom)) break; /* nope */ - if (! rom_load_linear( - L"roms/machines/ibmpc/basicc11.fc", - 0x00c000, 8192, 0, rom)) break; /* nope */ - return(1); - - case ROM_IBMXT: /* IBM PX-XT */ - if (rom_load_linear( - L"roms/machines/ibmxt/xt.rom", - 0x000000, 65536, 0, rom)) return(1); - - if (! rom_load_linear( - L"roms/machines/ibmxt/5000027.u19", - 0x000000, 32768, 0, rom)) break; - if (rom_load_linear( - L"roms/machines/ibmxt/1501512.u18", - 0x008000, 32768, 0, rom)) return(1); - break; - - case ROM_XI8088: - if (rom_load_linear_inverted( - L"roms/machines/xi8088/bios-xi8088.bin", - 0x000000, 131072, 0, rom)) { - biosmask = 0x1ffff; - xi8088_bios_128kb_set(1); - return(1); - } else { - if (rom_load_linear( - L"roms/machines/xi8088/bios-xi8088.bin", - 0x000000, 65536, 0, rom)) { - xi8088_bios_128kb_set(0); - return(1); - } - } - break; - - case ROM_IBMXT286: /* IBM PX-XT 286 */ - if (rom_load_interleaved( - L"roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin", - L"roms/machines/ibmxt286/bios_5162_21apr86_u35_78x7461_27256.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_IBMPCJR: /* IBM PCjr */ - if (rom_load_linear( - L"roms/machines/ibmpcjr/bios.rom", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_IBMAT: /* IBM PC-AT */ - if (rom_load_interleaved( - L"roms/machines/ibmat/62x0820.u27", - L"roms/machines/ibmat/62x0821.u47", - 0x000000, 65536, 0, rom)) return(1); - break; - -#ifdef WALTJE - case ROM_OPENAT: /* PC/AT clone with OpenBIOS */ - if (rom_load_linear( - L"roms/machines/open_at/bios.bin", - 0x000000, 65536, 0, rom)) return(1); - break; -#endif - - case ROM_GENXT: /* Generic PC-XT clone */ - if (rom_load_linear( - L"roms/machines/genxt/pcxt.rom", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_PC1512: /* Amstrad PC-1512 */ - if (! rom_load_interleaved( - L"roms/machines/pc1512/40044", - L"roms/machines/pc1512/40043", - 0x00c000, 16384, 0, rom)) break; - f = rom_fopen(L"roms/machines/pc1512/40078", L"rb"); - if (f == NULL) break; - (void)fclose(f); - return(1); - - case ROM_PC1640: /* Amstrad PC-1640 */ - if (! rom_load_interleaved( - L"roms/machines/pc1640/40044.v3", - L"roms/machines/pc1640/40043.v3", - 0x00c000, 16384, 0, rom)) break; - f = rom_fopen(L"roms/machines/pc1640/40100", L"rb"); - if (f == NULL) break; - (void)fclose(f); - return(1); - - case ROM_PC200: - if (! rom_load_interleaved( - L"roms/machines/pc200/pc20v2.1", - L"roms/machines/pc200/pc20v2.0", - 0x00c000, 16384, 0, rom)) break; - f = rom_fopen(L"roms/machines/pc200/40109", L"rb"); - if (f == NULL) break; - (void)fclose(f); - return(1); - - case ROM_TANDY: - if (rom_load_linear( - L"roms/machines/tandy/tandy1t1.020", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_TANDY1000HX: - if (! rom_load_linear( - L"roms/machines/tandy1000hx/v020000.u12", - 0x000000, 0x20000, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_TANDY1000SL2: - if (rom_load_interleaved( - L"roms/machines/tandy1000sl2/8079047.hu1", - L"roms/machines/tandy1000sl2/8079048.hu2", - 0x000000, 65536, 0x30000/2, rom)) return(1); - break; - - case ROM_PORTABLE: - if (rom_load_linear( - L"roms/machines/portable/compaq portable plus 100666-001 rev c u47.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_PORTABLEII: - if (! rom_load_interleaved( - L"roms/machines/portableii/109740-001.rom", - L"roms/machines/portableii/109739-001.rom", - 0x000000, 32768, 0, rom)) break; - biosmask = 0x7fff; - return(1); - -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - case ROM_PORTABLEIII: - case ROM_PORTABLEIII386: - if (rom_load_interleaved( - L"roms/machines/portableiii/109738-002.bin", - L"roms/machines/portableiii/109737-002.bin", - 0x000000, 65536, 0, rom)) return(1); - break; -#endif - - case ROM_DTKXT: - if (rom_load_linear( - L"roms/machines/dtk/dtk_erso_2.42_2764.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_OLIM24: - if (rom_load_interleaved( - L"roms/machines/olivetti_m24/olivetti_m24_version_1.43_low.bin", - L"roms/machines/olivetti_m24/olivetti_m24_version_1.43_high.bin", - 0x00c000, 16384, 0, rom)) return(1); - break; - - case ROM_PC2086: - if (! rom_load_interleaved( - L"roms/machines/pc2086/40179.ic129", - L"roms/machines/pc2086/40180.ic132", - 0x000000, 16384, 0, rom)) break; - f = rom_fopen(L"roms/machines/pc2086/40186.ic171", L"rb"); - if (f == NULL) break; - (void)fclose(f); - biosmask = 0x3fff; - return(1); - - case ROM_PC3086: - if (! rom_load_linear( - L"roms/machines/pc3086/fc00.bin", - 0x000000, 16384, 0, rom)) break; - f = rom_fopen(L"roms/machines/pc3086/c000.bin", L"rb"); - if (f == NULL) break; - (void)fclose(f); - biosmask = 0x3fff; - return(1); - - case ROM_CMDPC30: - if (! rom_load_interleaved( - L"roms/machines/cmdpc30/commodore pc 30 iii even.bin", - L"roms/machines/cmdpc30/commodore pc 30 iii odd.bin", - 0x000000, 32768, 0, rom)) break; - biosmask = 0x7fff; - return(1); - - case ROM_AMI386SX: - if (rom_load_linear( - L"roms/machines/ami386/ami386.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_AMI386DX_OPTI495: /* uses the OPTi 82C495 chipset */ - if (rom_load_linear( - L"roms/machines/ami386dx/opt495sx.ami", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_MR386DX_OPTI495: /* uses the OPTi 82C495 chipset */ - if (rom_load_linear( - L"roms/machines/mr386dx/opt495sx.mr", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_AWARD386SX_OPTI495: /* uses the OPTi 82C495 chipset */ - case ROM_AWARD386DX_OPTI495: /* uses the OPTi 82C495 chipset */ - case ROM_AWARD486_OPTI495: /* uses the OPTi 82C495 chipset */ - if (rom_load_linear( - L"roms/machines/award495/opt495s.awa", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_AMI286: - if (rom_load_linear( - L"roms/machines/ami286/amic206.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_AWARD286: - if (rom_load_linear( - L"roms/machines/award286/award.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_EUROPC: - if (rom_load_linear( - L"roms/machines/europc/50145", - 0x008000, 32768, 0, rom)) return(1); - break; - - case ROM_MEGAPC: - case ROM_MEGAPCDX: - if (rom_load_interleaved( - L"roms/machines/megapc/41651-bios lo.u18", - L"roms/machines/megapc/211253-bios hi.u19", - 0x000000, 65536, 0x08000, rom)) return(1); - break; - - case ROM_AMI486: - if (rom_load_linear( - L"roms/machines/ami486/ami486.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_WIN486: - if (rom_load_linear( - L"roms/machines/win486/ali1429g.amw", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_430VX: - if (! rom_load_linear( - L"roms/machines/430vx/55xwuq0e.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_REVENGE: - if (! rom_load_linear( - L"roms/machines/revenge/1009af2_.bio", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/revenge/1009af2_.bi1", - 0x000000, 0x00c000, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_ENDEAVOR: - if (! rom_load_linear( - L"roms/machines/endeavor/1006cb0_.bio", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/endeavor/1006cb0_.bi1", - 0x000000, 0x00d000, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS1_2011: - if (! rom_load_linear( - L"roms/machines/ibmps1es/f80000.bin", - 0x000000, 131072, 0x60000, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2121_ISA: - if (! rom_load_linear( - L"roms/machines/ibmps1_2121/fc0000.bin", - 0x000000, 131072, 0x20000, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS1_2133: - if (! rom_load_linear( - L"roms/machines/ibmps1_2133/ps1_2133_52g2974_rom.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - case ROM_DESKPRO_386: - if (! rom_load_interleaved( - L"roms/machines/deskpro386/109592-005.u11.bin", - L"roms/machines/deskpro386/109591-005.u13.bin", - 0x000000, 32768, 0, rom)) break; - biosmask = 0x7fff; - return(1); -#endif - - case ROM_AMIXT: - if (rom_load_linear( - L"roms/machines/amixt/ami_8088_bios_31jan89.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - case ROM_LTXT: - if (rom_load_linear( - L"roms/machines/ltxt/27c64.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_LXT3: - if (rom_load_linear( - L"roms/machines/lxt3/27c64d.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; -#endif - - case ROM_GW286CT: - if (rom_load_linear( - L"roms/machines/gw286ct/2ctc001.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_SPC4200P: /* Samsung SPC-4200P */ - if (rom_load_linear( - L"roms/machines/spc4200p/u8.01", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_SPC4216P: - if (! rom_load_interleaved( - L"roms/machines/spc4216p/7101.u8", - L"roms/machines/spc4216p/ac64.u10", - 0x000000, 65536, 0, rom)) break; - return(1); - - case ROM_KMXC02: - if (rom_load_linear( - L"roms/machines/kmxc02/3ctm005.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_SUPER286TR: /* Hyundai Super-286TR */ - if (rom_load_linear( - L"roms/machines/super286tr/hyundai_award286.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_DTK386: /* uses NEAT chipset */ - if (rom_load_linear( - L"roms/machines/dtk386/3cto001.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_PXXT: - if (rom_load_linear( - L"roms/machines/pxxt/000p001.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_JUKOPC: - if (rom_load_linear( - L"roms/machines/jukopc/000o001.bin", - 0x00e000, 8192, 0, rom)) return(1); - break; - - case ROM_IBMPS2_M30_286: - if (! rom_load_linear( - L"roms/machines/ibmps2_m30_286/33f5381a.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS2_M70_TYPE3: - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m70_type3/70-a_even.bin", - L"roms/machines/ibmps2_m70_type3/70-a_odd.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS2_M70_TYPE4: - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m70_type4/70-b_even.bin", - L"roms/machines/ibmps2_m70_type4/70-b_odd.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_DTK486: - if (rom_load_linear( - L"roms/machines/dtk486/4siw005.bin", - 0x000000, 65536, 0, rom)) return(1); - break; - - case ROM_R418: - if (! rom_load_linear( - L"roms/machines/r418/r418i.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - -#if 0 - case ROM_586MC1: - if (! rom_load_linear( - L"roms/machines/586mc1/is.34", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); -#endif - - case ROM_PLATO: - if (! rom_load_linear( - L"roms/machines/plato/1016ax1_.bio", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/plato/1016ax1_.bi1", - 0x000000, 0x00d000, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_MB500N: - if (! rom_load_linear( - L"roms/machines/mb500n/031396s.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_AP53: - if (! rom_load_linear( - L"roms/machines/ap53/ap53r2c0.rom", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_P55T2S: - if (! rom_load_linear( - L"roms/machines/p55t2s/s6y08t.rom", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_PRESIDENT: - if (! rom_load_linear( - L"roms/machines/president/bios.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_P54TP4XE: - if (! rom_load_linear( - L"roms/machines/p54tp4xe/t15i0302.awd", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_ACERM3A: - if (! rom_load_linear( - L"roms/machines/acerm3a/r01-b3.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_ACERV35N: - if (! rom_load_linear( - L"roms/machines/acerv35n/v35nd1s1.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_P55VA: - if (! rom_load_linear( - L"roms/machines/p55va/va021297.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_P55T2P4: - if (! rom_load_linear( - L"roms/machines/p55t2p4/0207_j2.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_P55TVP4: - if (! rom_load_linear( - L"roms/machines/p55tvp4/tv5i0204.awd", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - -#if defined(DEV_BRANCH) && defined(USE_I686) - case ROM_440FX: /* working Tyan BIOS */ - if (! rom_load_linear( - L"roms/machines/440fx/ntmaw501.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_S1668: /* working Tyan BIOS */ - if (! rom_load_linear( - L"roms/machines/tpatx/s1668p.rom", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); -#endif - - case ROM_THOR: - if (! rom_load_linear( - L"roms/machines/thor/1006cn0_.bio", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/thor/1006cn0_.bi1", - 0x000000, 65536, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) - case ROM_MRTHOR: - if (! rom_load_linear( - L"roms/machines/mrthor/mr_atx.bio", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); -#endif - - case ROM_PB640: - if (! rom_load_linear( - L"roms/machines/pb640/1007CP0R.BIO", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/pb640/1007CP0R.BI1", - 0x000000, 0x00d000, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_ZAPPA: - if (! rom_load_linear( - L"roms/machines/zappa/1006bs0_.bio", - 0x010000, 65536, 128, rom)) break; - if (! rom_load_linear( - L"roms/machines/zappa/1006bs0_.bi1", - 0x000000, 65536, 128, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS2_M50: - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m50/90x7423.zm14", - L"roms/machines/ibmps2_m50/90x7426.zm16", - 0x000000, 65536, 0, rom)) break; - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m50/90x7420.zm13", - L"roms/machines/ibmps2_m50/90x7429.zm18", - 0x010000, 65536, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS2_M55SX: - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m55sx/33f8146.zm41", - L"roms/machines/ibmps2_m55sx/33f8145.zm40", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_IBMPS2_M80: - if (! rom_load_interleaved( - L"roms/machines/ibmps2_m80/15f6637.bin", - L"roms/machines/ibmps2_m80/15f6639.bin", - 0x000000, 131072, 0, rom)) break; - biosmask = 0x1ffff; - return(1); - - case ROM_T1000: - loadfont(L"roms/machines/t1000/t1000font.bin", 2); - if (!rom_load_linear( - L"roms/machines/t1000/t1000.rom", - 0x000000, 32768, 0, rom)) break; - biosmask = 0x7fff; - return(1); - - case ROM_T1200: - loadfont(L"roms/machines/t1200/t1000font.bin", 2); - if (!rom_load_linear( - L"roms/machines/t1200/t1200_019e.ic15.bin", - 0x000000, 32768, 0, rom)) break; - biosmask = 0x7fff; - return(1); - - case ROM_T3100E: - loadfont(L"roms/machines/t3100e/t3100e_font.bin", 5); - if (rom_load_linear( - L"roms/machines/t3100e/t3100e.rom", - 0x000000, 65536, 0, rom)) return(1); - break; - - default: - rom_log("ROM: don't know how to handle ROM set %d !\n", rom_id); - } - - return(0); -} diff --git a/src - Cópia/rom.h b/src - Cópia/rom.h deleted file mode 100644 index 095ddb1d3..000000000 --- a/src - Cópia/rom.h +++ /dev/null @@ -1,195 +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. - * - * Definitions for the ROM image handler. - * - * Version: @(#)rom.h 1.0.17 2018/05/10 - * - * Author: Fred N. van Kempen, - * Copyright 2018 Fred N. van Kempen. - */ -#ifndef EMU_ROM_H -# define EMU_ROM_H - - -#define PCJR (romset==ROM_IBMPCJR) -#if defined(DEV_BRANCH) && defined(USE_GREENB) -#define AMIBIOS (romset==ROM_AMI386SX || \ - romset==ROM_AMI486 || \ - romset==ROM_WIN486 || \ - romset==ROM_4GPV31) -#else -#define AMIBIOS (romset==ROM_AMI386SX || \ - romset==ROM_AMI486 || \ - romset==ROM_WIN486) -#endif - - -typedef struct { - uint8_t *rom; - uint32_t mask; - mem_mapping_t mapping; -} rom_t; - - -enum { - ROM_IBMPC = 0, /* 301 keyboard error, 131 cassette (!!!) error */ - ROM_AMIXT, /* XT Clone with AMI BIOS */ - ROM_DTKXT, - ROM_IBMXT, /* 301 keyboard error */ - ROM_GENXT, /* 'Generic XT BIOS' */ - ROM_JUKOPC, - ROM_PORTABLE, - ROM_PXXT, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) - ROM_LTXT, - - ROM_LXT3, -#endif - - ROM_T1000, - ROM_T1200, - - ROM_XI8088, - - ROM_IBMPCJR, - ROM_TANDY, - ROM_TANDY1000HX, - ROM_EUROPC, - ROM_PC1512, - ROM_PC1640, - ROM_PC200, - ROM_PC2086, - ROM_PC3086, - ROM_OLIM24, - ROM_TANDY1000SL2, - - ROM_T3100E, - - ROM_AMI286, - ROM_AWARD286, - ROM_CMDPC30, - ROM_PORTABLEII, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - ROM_PORTABLEIII, -#endif - ROM_GW286CT, - ROM_SUPER286TR, /* Hyundai Super-286TR/SCAT/Award */ - ROM_IBMAT, - ROM_IBMPS1_2011, - ROM_IBMPS2_M30_286, - ROM_IBMXT286, - ROM_SPC4200P, /* Samsung SPC-4200P/SCAT/Phoenix */ - ROM_SPC4216P, /* Samsung SPC-4216P/SCAT */ -#ifdef WALTJE - ROM_OPENAT, /* PC/AT clone with Open BIOS */ -#endif - - ROM_IBMPS2_M50, - - ROM_AMI386SX, - ROM_KMXC02, - ROM_MEGAPC, - ROM_AWARD386SX_OPTI495, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - ROM_DESKPRO_386, -#endif - ROM_DTK386, - ROM_IBMPS1_2121, - ROM_IBMPS1_2121_ISA,/* IBM PS/1 Model 2121 with ISA expansion bus */ -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - ROM_PORTABLEIII386, -#endif - - ROM_IBMPS2_M55SX, - - ROM_AMI386DX_OPTI495, - ROM_MEGAPCDX, /* 386DX mdl - Note: documentation (in German) clearly says such a model exists */ - ROM_AWARD386DX_OPTI495, - ROM_MR386DX_OPTI495, - - ROM_IBMPS2_M80, - - ROM_AMI486, - ROM_WIN486, -#ifdef UNIMPLEMENTED_MACHINES - ROM_VLI486SV2G, /* ASUS VL/I-486SV2G/SiS 471/Award/SiS 85C471 */ /* 51 */ -#endif - ROM_AWARD486_OPTI495, - ROM_DTK486, /* DTK PKM-0038S E-2/SiS 471/Award/SiS 85C471 */ - ROM_IBMPS1_2133, - - ROM_IBMPS2_M70_TYPE3, - ROM_IBMPS2_M70_TYPE4, - - ROM_R418, /* Rise Computer R418/SiS 496/497/Award/SMC FDC37C665 */ - - ROM_REVENGE, /* Intel Premiere/PCI I/430LX/AMI/SMC FDC37C665 */ - - ROM_PLATO, /* Intel Premiere/PCI II/430NX/AMI/SMC FDC37C665 */ - - ROM_P54TP4XE, /* ASUS P/I-P55TP4XE/430FX/Award/SMC FDC37C665 */ - ROM_ENDEAVOR, /* Intel Advanced_EV/430FX/AMI/NS PC87306 */ - ROM_ZAPPA, /* Intel Advanced_ZP/430FX/AMI/NS PC87306 */ -#ifdef UNIMPLEMENTED_MACHINES - ROM_POWERMATE_V, /* NEC PowerMate V/430FX/Phoenix/SMC FDC37C66 5*/ -#endif - ROM_MB500N, /* PC Partner MB500N/430FX/Award/SMC FDC37C665 */ - ROM_PRESIDENT, /* President Award 430FX PCI/430FX/Award/Unknown SIO */ - - ROM_THOR, /* Intel Advanced_ATX/430FX/AMI/NS PC87306 */ -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) - ROM_MRTHOR, /* Intel Advanced_ATX/430FX/MR.BIOS/NS PC87306 */ -#endif - ROM_PB640, /* Packard Bell PB640/430FX/AMI/NS PC87306 */ - - ROM_ACERM3A, /* Acer M3A/430HX/Acer/SMC FDC37C932FR */ - ROM_ACERV35N, /* Acer V35N/430HX/Acer/SMC FDC37C932FR */ - ROM_AP53, /* AOpen AP53/430HX/AMI/SMC FDC37C665/669 */ - ROM_P55T2P4, /* ASUS P/I-P55T2P4/430HX/Award/Winbond W8387F*/ - ROM_P55T2S, /* ASUS P/I-P55T2S/430HX/AMI/NS PC87306 */ - - ROM_P55TVP4, /* ASUS P/I-P55TVP4/430HX/Award/Winbond W8387F*/ - ROM_430VX, /* Award 430VX PCI/430VX/Award/UMC UM8669F*/ - ROM_P55VA, /* Epox P55-VA/430VX/Award/SMC FDC37C932FR*/ - -#if defined(DEV_BRANCH) && defined(USE_I686) - ROM_440FX, /* Tyan Titan-Pro AT/440FX/Award BIOS/SMC FDC37C665 */ - ROM_S1668, /* Tyan Titan-Pro ATX/440FX/AMI/SMC FDC37C669 */ -#endif - - ROM_MAX -}; - - -extern int romspresent[ROM_MAX]; - -extern uint8_t rom_read(uint32_t addr, void *p); -extern uint16_t rom_readw(uint32_t addr, void *p); -extern uint32_t rom_readl(uint32_t addr, void *p); - -extern FILE *rom_fopen(wchar_t *fn, wchar_t *mode); -extern int rom_getfile(wchar_t *fn, wchar_t *s, int size); -extern int rom_present(wchar_t *fn); - -extern int rom_load_linear(wchar_t *fn, uint32_t addr, int sz, - int off, uint8_t *ptr); -extern int rom_load_interleaved(wchar_t *fnl, wchar_t *fnh, uint32_t addr, - int sz, int off, uint8_t *ptr); - -extern int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, - int mask, int file_offset, uint32_t flags); -extern int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, - wchar_t *fn_high, uint32_t address, - int size, int mask, int file_offset, - uint32_t flags); - -extern int rom_load_bios(int rom_id); - - -#endif /*EMU_ROM_H*/ diff --git a/src - Cópia/scsi/scsi.c b/src - Cópia/scsi/scsi.c deleted file mode 100644 index a21f9a157..000000000 --- a/src - Cópia/scsi/scsi.c +++ /dev/null @@ -1,237 +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 SCSI controllers. - * - * Version: @(#)scsi.c 1.0.20 2018/06/02 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * TheCollector1995, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "scsi_disk.h" -#include "scsi_device.h" -#include "scsi_aha154x.h" -#include "scsi_buslogic.h" -#include "scsi_ncr5380.h" -#include "scsi_ncr53c810.h" -#ifdef WALTJE -# include "scsi_wd33c93.h" -#endif -#include "scsi_x54x.h" - - -scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; -char scsi_fn[SCSI_NUM][512]; -uint16_t scsi_disk_location[SCSI_NUM]; - -int scsi_card_current = 0; -int scsi_card_last = 0; - -uint32_t SCSI_BufferLength; -static volatile -mutex_t *scsiMutex; - - -typedef const struct { - const char *name; - const char *internal_name; - const device_t *device; -} SCSI_CARD; - - -static SCSI_CARD scsi_cards[] = { - { "None", "none", NULL, }, - { "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, }, - { "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, }, - { "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, }, - { "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, }, - { "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,}, - { "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,}, - { "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, }, - { "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, }, - { "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, }, -#ifdef WALTJE - { "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, }, -#endif - { "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, }, - { "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,}, - { "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, }, - { "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,}, - { "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,}, - { "", "", NULL, }, -}; - - -#ifdef ENABLE_SCSI_LOG -int scsi_do_log = ENABLE_SCSI_LOG; -#endif - - -static void -scsi_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_LOG - va_list ap; - - if (scsi_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -int scsi_card_available(int card) -{ - if (scsi_cards[card].device) - return(device_available(scsi_cards[card].device)); - - return(1); -} - - -char *scsi_card_getname(int card) -{ - return((char *) scsi_cards[card].name); -} - - -const device_t *scsi_card_getdevice(int card) -{ - return(scsi_cards[card].device); -} - - -int scsi_card_has_config(int card) -{ - if (! scsi_cards[card].device) return(0); - - return(scsi_cards[card].device->config ? 1 : 0); -} - - -char *scsi_card_get_internal_name(int card) -{ - return((char *) scsi_cards[card].internal_name); -} - - -int scsi_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen((char *) scsi_cards[c].internal_name)) { - if (!strcmp((char *) scsi_cards[c].internal_name, s)) - return(c); - c++; - } - - return(0); -} - - -void scsi_mutex(uint8_t start) -{ - if (start) - scsiMutex = thread_create_mutex(L"86Box.SCSIMutex"); - else - thread_close_mutex((mutex_t *) scsiMutex); -} - - -void scsi_card_init(void) -{ - int i, j; - - if (!scsi_cards[scsi_card_current].device) - return; - - scsi_log("Building SCSI hard disk map...\n"); - build_scsi_disk_map(); - scsi_log("Building SCSI CD-ROM map...\n"); - build_scsi_cdrom_map(); - scsi_log("Building SCSI ZIP map...\n"); - build_scsi_zip_map(); - - for (i=0; i - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_SCSI_H -#define EMU_SCSI_H - - -#ifdef WALTJE -#define SCSI_TIME (50 * (1 << TIMER_SHIFT)) -#else -#define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) -#endif - - -/* Configuration. */ -#define SCSI_ID_MAX 16 /* 16 on wide buses */ -#define SCSI_LUN_MAX 8 /* always 8 */ - - -/* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_IOMEGA_SENSE 0x06 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c -#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_SCSI_RESERVE 0x16 -#define GPCMD_SCSI_RELEASE 0x17 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_SEND_DIAGNOSTIC 0x1d -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_FORMAT_CAPACITIES 0x23 -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_WRITE_AND_VERIFY_10 0x2e -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_READ_BUFFER 0x3c -#define GPCMD_WRITE_SAME_10 0x41 -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_WRITE_AND_VERIFY_12 0xae -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_SCAN 0xba -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ - -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f - -/* Mode page codes for presence */ -#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL -#define GPMODEP_CDROM_PAGE 0x0000000000002000LL -#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL -#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL -#define GPMODEP_ALL_PAGES 0x8000000000000000LL - -/* SCSI Status Codes */ -#define SCSI_STATUS_OK 0 -#define SCSI_STATUS_CHECK_CONDITION 2 - -/* SCSI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - -/* SCSI Additional Sense Codes */ -#define ASC_AUDIO_PLAY_OPERATION 0x00 -#define ASC_NOT_READY 0x04 -#define ASC_ILLEGAL_OPCODE 0x20 -#define ASC_LBA_OUT_OF_RANGE 0x21 -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 -#define ASC_INV_LUN 0x25 -#define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 -#define ASC_WRITE_PROTECTED 0x27 -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_CAPACITY_DATA_CHANGED 0x2A -#define ASC_INCOMPATIBLE_FORMAT 0x30 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 - -#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 -#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 -#define ASCQ_CAPACITY_DATA_CHANGED 0x09 -#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 - -/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). - Not that it means anything */ -#define CDROM_SPEED 706 /* 0x2C2 */ - -#define BUFFER_SIZE (256*1024) - -#define RW_DELAY (TIMER_USEC * 500) - -/* Some generally useful CD-ROM information */ -#define CD_MINS 75 /* max. minutes per CD */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ -#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) -#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) - -/* Event notification classes for GET EVENT STATUS NOTIFICATION */ -#define GESN_NO_EVENTS 0 -#define GESN_OPERATIONAL_CHANGE 1 -#define GESN_POWER_MANAGEMENT 2 -#define GESN_EXTERNAL_REQUEST 3 -#define GESN_MEDIA 4 -#define GESN_MULTIPLE_HOSTS 5 -#define GESN_DEVICE_BUSY 6 - -/* Event codes for MEDIA event status notification */ -#define MEC_NO_CHANGE 0 -#define MEC_EJECT_REQUESTED 1 -#define MEC_NEW_MEDIA 2 -#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ -#define MEC_MEDIA_CHANGED 4 /* only for media changers */ -#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ -#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ -#define MS_TRAY_OPEN 1 -#define MS_MEDIA_PRESENT 2 - -/* - * The MMC values are not IDE specific and might need to be moved - * to a common header if they are also needed for the SCSI emulation - */ - -/* Profile list from MMC-6 revision 1 table 91 */ -#define MMC_PROFILE_NONE 0x0000 -#define MMC_PROFILE_CD_ROM 0x0008 -#define MMC_PROFILE_CD_R 0x0009 -#define MMC_PROFILE_CD_RW 0x000A -#define MMC_PROFILE_DVD_ROM 0x0010 -#define MMC_PROFILE_DVD_R_SR 0x0011 -#define MMC_PROFILE_DVD_RAM 0x0012 -#define MMC_PROFILE_DVD_RW_RO 0x0013 -#define MMC_PROFILE_DVD_RW_SR 0x0014 -#define MMC_PROFILE_DVD_R_DL_SR 0x0015 -#define MMC_PROFILE_DVD_R_DL_JR 0x0016 -#define MMC_PROFILE_DVD_RW_DL 0x0017 -#define MMC_PROFILE_DVD_DDR 0x0018 -#define MMC_PROFILE_DVD_PLUS_RW 0x001A -#define MMC_PROFILE_DVD_PLUS_R 0x001B -#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A -#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B -#define MMC_PROFILE_BD_ROM 0x0040 -#define MMC_PROFILE_BD_R_SRM 0x0041 -#define MMC_PROFILE_BD_R_RRM 0x0042 -#define MMC_PROFILE_BD_RE 0x0043 -#define MMC_PROFILE_HDDVD_ROM 0x0050 -#define MMC_PROFILE_HDDVD_R 0x0051 -#define MMC_PROFILE_HDDVD_RAM 0x0052 -#define MMC_PROFILE_HDDVD_RW 0x0053 -#define MMC_PROFILE_HDDVD_R_DL 0x0058 -#define MMC_PROFILE_HDDVD_RW_DL 0x005A -#define MMC_PROFILE_INVALID 0xFFFF - -#define SCSI_ONLY 32 -#define ATAPI_ONLY 16 -#define IMPLEMENTED 8 -#define NONDATA 4 -#define CHECK_READY 2 -#define ALLOW_UA 1 - - -extern uint8_t SCSICommandTable[0x100]; -extern uint8_t mode_sense_pages[0x40]; -extern int readcdmode; - -/* Mode sense/select stuff. */ -extern uint8_t mode_pages_in[256][256]; -extern uint8_t page_flags[256]; -extern uint8_t prefix_len; -extern uint8_t page_current; -#define PAGE_CHANGEABLE 1 -#define PAGE_CHANGED 2 - -struct _scsisense_ { - uint8_t SenseBuffer[18]; - uint8_t SenseLength; - uint8_t UnitAttention; - uint8_t SenseKey; - uint8_t Asc; - uint8_t Ascq; -} SCSISense; - -extern int cd_status; -extern int prev_status; - -enum { - SCSI_NONE = 0, - SCSI_DISK, - SCSI_CDROM, - SCSI_ZIP -}; - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -#define MSG_COMMAND_COMPLETE 0x00 - -#define BUS_DBP 0x01 -#define BUS_SEL 0x02 -#define BUS_IO 0x04 -#define BUS_CD 0x08 -#define BUS_MSG 0x10 -#define BUS_REQ 0x20 -#define BUS_BSY 0x40 -#define BUS_RST 0x80 -#define BUS_ACK 0x200 -#define BUS_ATN 0x200 -#define BUS_ARB 0x8000 -#define BUS_SETDATA(val) ((uint32_t)val << 16) -#define BUS_GETDATA(val) ((val >> 16) & 0xff) -#define BUS_DATAMASK 0xff0000 - -#define BUS_IDLE (1 << 31) - -#define SCSI_PHASE_DATA_OUT 0 -#define SCSI_PHASE_DATA_IN BUS_IO -#define SCSI_PHASE_COMMAND BUS_CD -#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO) -#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD) -#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) - -typedef struct { - uint8_t *CmdBuffer; - int LunType; - int32_t BufferLength; - uint8_t Status; - uint8_t Phase; -} scsi_device_t; - - -extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; - -extern void SCSIReset(uint8_t id, uint8_t lun); - -extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); -extern int cdrom_LBAtoMSF_accurate(void); - -extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); -extern int mode_select_terminate(int force); -extern int mode_select_write(uint8_t val); - -extern int scsi_card_current; - -extern int scsi_card_available(int card); -extern char *scsi_card_getname(int card); -#ifdef EMU_DEVICE_H -extern const device_t *scsi_card_getdevice(int card); -#endif -extern int scsi_card_has_config(int card); -extern char *scsi_card_get_internal_name(int card); -extern int scsi_card_get_from_internal_name(char *s); -extern void scsi_mutex(uint8_t start); -extern void scsi_card_init(void); - - -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - -#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) -#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) - - -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t pages[0x40][0x40]; -} mode_sense_pages_t; -#pragma pack(pop) - - -#define MODE_SELECT_PHASE_IDLE 0 -#define MODE_SELECT_PHASE_HEADER 1 -#define MODE_SELECT_PHASE_BLOCK_DESC 2 -#define MODE_SELECT_PHASE_PAGE_HEADER 3 -#define MODE_SELECT_PHASE_PAGE 4 - -#endif /*EMU_SCSI_H*/ - -extern void scsi_mutex_wait(uint8_t wait); diff --git a/src - Cópia/scsi/scsi_aha154x.c b/src - Cópia/scsi/scsi_aha154x.c deleted file mode 100644 index 270af90ef..000000000 --- a/src - Cópia/scsi/scsi_aha154x.c +++ /dev/null @@ -1,1145 +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. - * - * Implementation of the AHA-154x series of SCSI Host Adapters - * made by Adaptec, Inc. These controllers were designed for - * the ISA bus. - * - * Version: @(#)scsi_aha154x.c 1.0.41 2018/04/26 - * - * Authors: Fred N. van Kempen, - * Original Buslogic version by SA1988 and Miran Grca. - * - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.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 "../timer.h" -#include "../plat.h" -#include "../cpu/cpu.h" -#include "scsi.h" -#include "scsi_aha154x.h" -#include "scsi_x54x.h" - - -enum { - AHA_154xB, - AHA_154xC, - AHA_154xCF, - AHA_154xCP, - AHA_1640 -}; - - -#define CMD_WRITE_EEPROM 0x22 /* UNDOC: Write EEPROM */ -#define CMD_READ_EEPROM 0x23 /* UNDOC: Read EEPROM */ -#define CMD_SHADOW_RAM 0x24 /* UNDOC: BIOS shadow ram */ -#define CMD_BIOS_MBINIT 0x25 /* UNDOC: BIOS mailbox initialization */ -#define CMD_MEMORY_MAP_1 0x26 /* UNDOC: Memory Mapper */ -#define CMD_MEMORY_MAP_2 0x27 /* UNDOC: Memory Mapper */ -#define CMD_EXTBIOS 0x28 /* UNDOC: return extended BIOS info */ -#define CMD_MBENABLE 0x29 /* set mailbox interface enable */ -#define CMD_BIOS_SCSI 0x82 /* start ROM BIOS SCSI command */ - - -uint16_t aha_ports[] = { - 0x0330, 0x0334, 0x0230, 0x0234, - 0x0130, 0x0134, 0x0000, 0x0000 -}; - - -#pragma pack(push,1) -typedef struct { - uint8_t CustomerSignature[20]; - uint8_t uAutoRetry; - uint8_t uBoardSwitches; - uint8_t uChecksum; - uint8_t uUnknown; - addr24 BIOSMailboxAddress; -} aha_setup_t; -#pragma pack(pop) - - -#ifdef ENABLE_AHA154X_LOG -int aha_do_log = ENABLE_AHA154X_LOG; -#endif - - -static void -aha_log(const char *fmt, ...) -{ -#ifdef ENABLE_AHA154X_LOG - va_list ap; - - if (aha_do_log) { - pclog("In %s mode: ",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* - * Write data to the BIOS space. - * - * AHA-1542C's and up have a feature where they map a 128-byte - * RAM space into the ROM BIOS' address space, and then use it - * as working memory. This function implements the writing to - * that memory. - * - * We enable/disable this memory through AHA command 0x24. - */ -static void -aha_mem_write(uint32_t addr, uint8_t val, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - addr &= 0x3fff; - - if ((addr >= dev->rom_shram) && (dev->shram_mode & 1)) - dev->shadow_ram[addr & (dev->rom_shramsz - 1)] = val; -} - - -static uint8_t -aha_mem_read(uint32_t addr, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - rom_t *rom = &dev->bios; - - addr &= 0x3fff; - - if ((addr >= dev->rom_shram) && (dev->shram_mode & 2)) - return dev->shadow_ram[addr & (dev->rom_shramsz - 1)]; - - return(rom->rom[addr]); -} - - -static uint8_t -aha154x_shram(x54x_t *dev, uint8_t cmd) -{ - /* If not supported, give up. */ - if (dev->rom_shram == 0x0000) return(0x04); - - /* Bit 0 = Shadow RAM write enable; - Bit 1 = Shadow RAM read enable. */ - dev->shram_mode = cmd; - - /* Firmware expects 04 status. */ - return(0x04); -} - - -static void -aha_eeprom_save(x54x_t *dev) -{ - FILE *f; - - f = nvr_fopen(dev->nvr_path, L"wb"); - if (f) - { - fwrite(dev->nvr, 1, NVR_SIZE, f); - fclose(f); - f = NULL; - } -} - - -static uint8_t -aha154x_eeprom(x54x_t *dev, uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) -{ - uint8_t r = 0xff; - int c; - - aha_log("%s: EEPROM cmd=%02x, arg=%02x len=%d, off=%02x\n", - dev->name, cmd, arg, len, off); - - /* Only if we can handle it.. */ - if (dev->nvr == NULL) return(r); - - if (cmd == 0x22) { - /* Write data to the EEPROM. */ - for (c = 0; c < len; c++) - dev->nvr[(off + c) & 0xff] = bufp[c]; - r = 0; - - aha_eeprom_save(dev); - } - - if (cmd == 0x23) { - /* Read data from the EEPROM. */ - for (c = 0; c < len; c++) - bufp[c] = dev->nvr[(off + c) & 0xff]; - r = len; - } - - return(r); -} - - -/* Map either the main or utility (Select) ROM into the memory space. */ -static uint8_t -aha154x_mmap(x54x_t *dev, uint8_t cmd) -{ - aha_log("%s: MEMORY cmd=%02x\n", dev->name, cmd); - - switch(cmd) { - case 0x26: - /* Disable the mapper, so, set ROM1 active. */ - dev->bios.rom = dev->rom1; - break; - - case 0x27: - /* Enable the mapper, so, set ROM2 active. */ - dev->bios.rom = dev->rom2; - break; - } - - return(0); -} - - -static uint8_t -aha_get_host_id(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - return dev->nvr[0] & 0x07; -} - - -static uint8_t -aha_get_irq(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - return (dev->nvr[1] & 0x07) + 9; -} - - -static uint8_t -aha_get_dma(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - return (dev->nvr[1] >> 4) & 0x07; -} - - -static uint8_t -aha_cmd_is_fast(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - if (dev->Command == CMD_BIOS_SCSI) - return 1; - else - return 0; -} - - -static uint8_t -aha_fast_cmds(void *p, uint8_t cmd) -{ - x54x_t *dev = (x54x_t *)p; - - if (cmd == CMD_BIOS_SCSI) { - dev->BIOSMailboxReq++; - return 1; - } - - return 0; -} - - -static uint8_t -aha_param_len(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - switch (dev->Command) { - case CMD_BIOS_MBINIT: - /* Same as 0x01 for AHA. */ - return sizeof(MailboxInit_t); - break; - - case CMD_SHADOW_RAM: - return 1; - break; - - case CMD_WRITE_EEPROM: - return 3+32; - break; - - case CMD_READ_EEPROM: - return 3; - - case CMD_MBENABLE: - return 2; - - default: - return 0; - } -} - - -static uint8_t -aha_cmds(void *p) -{ - x54x_t *dev = (x54x_t *)p; - MailboxInit_t *mbi; - - if (! dev->CmdParamLeft) { - aha_log("Running Operation Code 0x%02X\n", dev->Command); - switch (dev->Command) { - case CMD_WRITE_EEPROM: /* write EEPROM */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_eeprom(dev, - dev->Command, - dev->CmdBuf[0], - dev->CmdBuf[1], - dev->CmdBuf[2], - &(dev->CmdBuf[3])); - if (dev->DataReplyLeft == 0xff) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - - case CMD_READ_EEPROM: /* read EEPROM */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_eeprom(dev, - dev->Command, - dev->CmdBuf[0], - dev->CmdBuf[1], - dev->CmdBuf[2], - dev->DataBuf); - if (dev->DataReplyLeft == 0xff) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - - case CMD_SHADOW_RAM: /* Shadow RAM */ - /* - * For AHA1542CF, this is the command - * to play with the Shadow RAM. BIOS - * gives us one argument (00,02,03) - * and expects a 0x04 back in the INTR - * register. --FvK - */ - /* dev->Interrupt = aha154x_shram(dev,val); */ - dev->Interrupt = aha154x_shram(dev, dev->CmdBuf[0]); - break; - - case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ - /* Sent by CF BIOS. */ - dev->Mbx24bit = 1; - - mbi = (MailboxInit_t *)dev->CmdBuf; - - dev->BIOSMailboxInit = 1; - dev->BIOSMailboxCount = mbi->Count; - dev->BIOSMailboxOutAddr = ADDR_TO_U32(mbi->Address); - - aha_log("Initialize BIOS Mailbox: MBO=0x%08lx, %d entries at 0x%08lx\n", - dev->BIOSMailboxOutAddr, - mbi->Count, - ADDR_TO_U32(mbi->Address)); - - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - break; - - case CMD_MEMORY_MAP_1: /* AHA memory mapper */ - case CMD_MEMORY_MAP_2: /* AHA memory mapper */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_mmap(dev, dev->Command); - break; - - case CMD_EXTBIOS: /* Return extended BIOS information */ - dev->DataBuf[0] = 0x08; - dev->DataBuf[1] = dev->Lock; - dev->DataReplyLeft = 2; - break; - - case CMD_MBENABLE: /* Mailbox interface enable Command */ - dev->DataReplyLeft = 0; - if (dev->CmdBuf[1] == dev->Lock) { - if (dev->CmdBuf[0] & 1) { - dev->Lock = 1; - } else { - dev->Lock = 0; - } - } - break; - - case 0x2C: /* AHA-1542CP sends this */ - dev->DataBuf[0] = 0x00; - dev->DataReplyLeft = 1; - break; - - case 0x33: /* AHA-1542CP sends this */ - dev->DataBuf[0] = 0x00; - dev->DataBuf[1] = 0x00; - dev->DataBuf[2] = 0x00; - dev->DataBuf[3] = 0x00; - dev->DataReplyLeft = 256; - break; - - default: - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - } - - return 0; -} - - -static void -aha_setup_data(void *p) -{ - x54x_t *dev = (x54x_t *)p; - ReplyInquireSetupInformation *ReplyISI; - aha_setup_t *aha_setup; - - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - aha_setup = (aha_setup_t *)ReplyISI->VendorSpecificData; - - ReplyISI->fSynchronousInitiationEnabled = dev->sync & 1; - ReplyISI->fParityCheckingEnabled = dev->parity & 1; - - U32_TO_ADDR(aha_setup->BIOSMailboxAddress, dev->BIOSMailboxOutAddr); - aha_setup->uChecksum = 0xA3; - aha_setup->uUnknown = 0xC2; -} - - -static void -aha_do_bios_mail(x54x_t *dev) -{ - dev->MailboxIsBIOS = 1; - - if (!dev->BIOSMailboxCount) { - aha_log("aha_do_bios_mail(): No BIOS Mailboxes\n"); - return; - } - - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - for (dev->BIOSMailboxOutPosCur = 0; dev->BIOSMailboxOutPosCur < dev->BIOSMailboxCount; dev->BIOSMailboxOutPosCur++) { - if (x54x_mbo_process(dev)) - break; - } -} - - -static void -aha_callback(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - if (dev->BIOSMailboxInit && dev->BIOSMailboxReq) - aha_do_bios_mail(dev); -} - - -static uint8_t -aha_mca_read(int port, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - return(dev->pos_regs[port & 7]); -} - - -static void -aha_mca_write(int port, uint8_t val, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; - - /* Save the MCA register value. */ - dev->pos_regs[port & 7] = val; - - /* This is always necessary so that the old handler doesn't remain. */ - x54x_io_remove(dev, dev->Base, 4); - - /* Get the new assigned I/O base address. */ - dev->Base = (dev->pos_regs[3] & 7) << 8; - dev->Base |= ((dev->pos_regs[3] & 0xc0) ? 0x34 : 0x30); - - /* Save the new IRQ and DMA channel values. */ - dev->Irq = (dev->pos_regs[4] & 0x07) + 8; - dev->DmaChannel = dev->pos_regs[5] & 0x0f; - - /* Extract the BIOS ROM address info. */ - if (! (dev->pos_regs[2] & 0x80)) switch(dev->pos_regs[3] & 0x38) { - case 0x38: /* [1]=xx11 1xxx */ - dev->rom_addr = 0xDC000; - break; - - case 0x30: /* [1]=xx11 0xxx */ - dev->rom_addr = 0xD8000; - break; - - case 0x28: /* [1]=xx10 1xxx */ - dev->rom_addr = 0xD4000; - break; - - case 0x20: /* [1]=xx10 0xxx */ - dev->rom_addr = 0xD0000; - break; - - case 0x18: /* [1]=xx01 1xxx */ - dev->rom_addr = 0xCC000; - break; - - case 0x10: /* [1]=xx01 0xxx */ - dev->rom_addr = 0xC8000; - break; - } else { - /* Disabled. */ - dev->rom_addr = 0x000000; - } - - /* - * Get misc SCSI config stuff. For now, we are only - * interested in the configured HA target ID: - * - * pos[2]=111xxxxx = 7 - * pos[2]=000xxxxx = 0 - */ - dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; - - /* - * SYNC mode is pos[2]=xxxx1xxx. - * - * SCSI Parity is pos[2]=xxx1xxxx. - */ - dev->sync = (dev->pos_regs[4] >> 3) & 1; - dev->parity = (dev->pos_regs[4] >> 4) & 1; - - /* - * The PS/2 Model 80 BIOS always enables a card if it finds one, - * even if no resources were assigned yet (because we only added - * the card, but have not run AutoConfig yet...) - * - * So, remove current address, if any. - */ - mem_mapping_disable(&dev->bios.mapping); - - /* Initialize the device if fully configured. */ - if (dev->pos_regs[2] & 0x01) { - /* Card enabled; register (new) I/O handler. */ - x54x_io_set(dev, dev->Base, 4); - - /* Reset the device. */ - x54x_reset_ctrl(dev, CTRL_HRST); - - /* Enable or disable the BIOS ROM. */ - if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&dev->bios.mapping); - mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); - } - - /* Say hello. */ - pclog("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", - dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr, dev->HostID); - } -} - - -/* Initialize the board's ROM BIOS. */ -static void -aha_setbios(x54x_t *dev) -{ - uint32_t size; - uint32_t mask; - uint32_t temp; - FILE *f; - int i; - - /* Only if this device has a BIOS ROM. */ - if (dev->bios_path == NULL) return; - - /* Open the BIOS image file and make sure it exists. */ - aha_log("%s: loading BIOS from '%ls'\n", dev->name, dev->bios_path); - if ((f = rom_fopen(dev->bios_path, L"rb")) == NULL) { - aha_log("%s: BIOS ROM not found!\n", dev->name); - return; - } - - /* - * Manually load and process the ROM image. - * - * We *could* use the system "rom_init" function here, but for - * this special case, we can't: we may need WRITE access to the - * memory later on. - */ - (void)fseek(f, 0L, SEEK_END); - temp = ftell(f); - (void)fseek(f, 0L, SEEK_SET); - - /* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */ - dev->rom1 = malloc(ROM_SIZE); - (void)fread(dev->rom1, ROM_SIZE, 1, f); - temp -= ROM_SIZE; - if (temp > 0) { - dev->rom2 = malloc(ROM_SIZE); - (void)fread(dev->rom2, ROM_SIZE, 1, f); - temp -= ROM_SIZE; - } else { - dev->rom2 = NULL; - } - if (temp != 0) { - aha_log("%s: BIOS ROM size invalid!\n", dev->name); - free(dev->rom1); - if (dev->rom2 != NULL) - free(dev->rom2); - (void)fclose(f); - return; - } - temp = ftell(f); - if (temp > ROM_SIZE) - temp = ROM_SIZE; - (void)fclose(f); - - /* Adjust BIOS size in chunks of 2K, as per BIOS spec. */ - size = 0x10000; - if (temp <= 0x8000) - size = 0x8000; - if (temp <= 0x4000) - size = 0x4000; - if (temp <= 0x2000) - size = 0x2000; - mask = (size - 1); - aha_log("%s: BIOS at 0x%06lX, size %lu, mask %08lx\n", - dev->name, dev->rom_addr, size, mask); - - /* Initialize the ROM entry for this BIOS. */ - memset(&dev->bios, 0x00, sizeof(rom_t)); - - /* Enable ROM1 into the memory map. */ - dev->bios.rom = dev->rom1; - - /* Set up an address mask for this memory. */ - dev->bios.mask = mask; - - /* Map this system into the memory map. */ - mem_mapping_add(&dev->bios.mapping, dev->rom_addr, size, - aha_mem_read, NULL, NULL, /* aha_mem_readw, aha_mem_readl, */ - aha_mem_write, NULL, NULL, - dev->bios.rom, MEM_MAPPING_EXTERNAL, dev); - mem_mapping_disable(&dev->bios.mapping); - - /* - * Patch the ROM BIOS image for stuff Adaptec deliberately - * made hard to understand. Well, maybe not, maybe it was - * their way of handling issues like these at the time.. - * - * Patch 1: emulate the I/O ADDR SW setting by patching a - * byte in the BIOS that indicates the I/O ADDR - * switch setting on the board. - */ - if (dev->rom_ioaddr != 0x0000) { - /* Look up the I/O address in the table. */ - for (i=0; i<8; i++) - if (aha_ports[i] == dev->Base) break; - if (i == 8) { - aha_log("%s: invalid I/O address %04x selected!\n", - dev->name, dev->Base); - return; - } - dev->bios.rom[dev->rom_ioaddr] = (uint8_t)i; - /* Negation of the DIP switches to satify the checksum. */ - dev->bios.rom[dev->rom_ioaddr + 1] = (uint8_t)((i ^ 0xff) + 1); - } -} - - -static void -aha_initnvr(x54x_t *dev) -{ - /* Initialize the on-board EEPROM. */ - dev->nvr[0] = dev->HostID; /* SCSI ID 7 */ - dev->nvr[0] |= (0x10 | 0x20 | 0x40); - dev->nvr[1] = dev->Irq-9; /* IRQ15 */ - dev->nvr[1] |= (dev->DmaChannel<<4); /* DMA6 */ - dev->nvr[2] = (EE2_HABIOS | /* BIOS enabled */ - EE2_DYNSCAN | /* scan bus */ - EE2_EXT1G | EE2_RMVOK); /* Imm return on seek */ - dev->nvr[3] = SPEED_50; /* speed 5.0 MB/s */ - dev->nvr[6] = (EE6_TERM | /* host term enable */ - EE6_RSTBUS); /* reset SCSI bus on boot*/ -} - - -/* Initialize the board's EEPROM (NVR.) */ -static void -aha_setnvr(x54x_t *dev) -{ - FILE *f; - - /* Only if this device has an EEPROM. */ - if (dev->nvr_path == NULL) return; - - /* Allocate and initialize the EEPROM. */ - dev->nvr = (uint8_t *)malloc(NVR_SIZE); - memset(dev->nvr, 0x00, NVR_SIZE); - - f = nvr_fopen(dev->nvr_path, L"rb"); - if (f) - { - fread(dev->nvr, 1, NVR_SIZE, f); - fclose(f); - f = NULL; - } - else - { - aha_initnvr(dev); - } -} - - -/* General initialization routine for all boards. */ -static void * -aha_init(const device_t *info) -{ - x54x_t *dev; - - /* Call common initializer. */ - dev = x54x_init(info); - - /* - * Set up the (initial) I/O address, IRQ and DMA info. - * - * Note that on MCA, configuration is handled by the BIOS, - * and so any info we get here will be overwritten by the - * MCA-assigned values later on! - */ - dev->Base = device_get_config_hex16("base"); - dev->Irq = device_get_config_int("irq"); - dev->DmaChannel = device_get_config_int("dma"); - dev->rom_addr = device_get_config_hex20("bios_addr"); - dev->HostID = 7; /* default HA ID */ - dev->setup_info_len = sizeof(aha_setup_t); - dev->max_id = 7; - dev->int_geom_writable = 0; - dev->cdrom_boot = 0; - dev->bit32 = 0; - dev->lba_bios = 0; - - dev->ven_callback = aha_callback; - dev->ven_cmd_is_fast = aha_cmd_is_fast; - dev->ven_fast_cmds = aha_fast_cmds; - dev->get_ven_param_len = aha_param_len; - dev->ven_cmds = aha_cmds; - dev->get_ven_data = aha_setup_data; - - strcpy(dev->vendor, "Adaptec"); - - /* Perform per-board initialization. */ - switch(dev->type) { - case AHA_154xB: - strcpy(dev->name, "AHA-154xB"); - switch(dev->Base) { - case 0x0330: - dev->bios_path = - L"roms/scsi/adaptec/aha1540b320_330.bin"; - break; - - case 0x0334: - dev->bios_path = - L"roms/scsi/adaptec/aha1540b320_334.bin"; - break; - } - dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ - dev->HostID = device_get_config_int("hostid"); - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; - - case AHA_154xC: - strcpy(dev->name, "AHA-154xC"); - dev->bios_path = L"roms/scsi/adaptec/aha1542c102.bin"; - dev->nvr_path = L"aha1542c.nvr"; - dev->fw_rev = "D001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; - - case AHA_154xCF: - strcpy(dev->name, "AHA-154xCF"); - dev->bios_path = L"roms/scsi/adaptec/aha1542cf211.bin"; - dev->nvr_path = L"aha1542cf.nvr"; - dev->fw_rev = "E001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ - dev->cdrom_boot = 1; - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 10000000.0; /* fast SCSI */ - break; - - case AHA_154xCP: - strcpy(dev->name, "AHA-154xCP"); - dev->bios_path = L"roms/scsi/adaptec/aha1542cp102.bin"; - dev->nvr_path = L"aha1540cp.nvr"; - dev->fw_rev = "F001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0055; /* firmware version (hi/lo) */ - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 10000000.0; /* fast SCSI */ - break; - - case AHA_1640: - strcpy(dev->name, "AHA-1640"); - dev->bios_path = L"roms/scsi/adaptec/aha1640.bin"; - dev->fw_rev = "BB01"; - - dev->lba_bios = 1; - - /* Enable MCA. */ - dev->pos_regs[0] = 0x1F; /* MCA board ID */ - dev->pos_regs[1] = 0x0F; - mca_add(aha_mca_read, aha_mca_write, dev); - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; - } - - /* Initialize ROM BIOS if needed. */ - aha_setbios(dev); - - /* Initialize EEPROM (NVR) if needed. */ - aha_setnvr(dev); - - if (dev->Base != 0) { - /* Initialize the device. */ - x54x_device_reset(dev); - - if (!(dev->bus & DEVICE_MCA)) { - /* Register our address space. */ - x54x_io_set(dev, dev->Base, 4); - - /* Enable the memory. */ - if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&dev->bios.mapping); - mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); - } - } - } - - return(dev); -} - - -static const device_config_t aha_154xb_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x334, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "hostid", "Host ID", CONFIG_SELECTION, "", 7, - { - { - "0", 0 - }, - { - "1", 1 - }, - { - "2", 2 - }, - { - "3", 3 - }, - { - "4", 4 - }, - { - "5", 5 - }, - { - "6", 6 - }, - { - "7", 7 - }, - { - "" - } - }, - }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - - -static const device_config_t aha_154x_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x334, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - - -const device_t aha1540b_device = { - "Adaptec AHA-1540B", - DEVICE_ISA | DEVICE_AT, - AHA_154xB, - aha_init, x54x_close, NULL, - NULL, NULL, NULL, - aha_154xb_config -}; - -const device_t aha1542c_device = { - "Adaptec AHA-1542C", - DEVICE_ISA | DEVICE_AT, - AHA_154xC, - aha_init, x54x_close, NULL, - NULL, NULL, NULL, - aha_154x_config -}; - -const device_t aha1542cf_device = { - "Adaptec AHA-1542CF", - DEVICE_ISA | DEVICE_AT, - AHA_154xCF, - aha_init, x54x_close, NULL, - NULL, NULL, NULL, - aha_154x_config -}; - -const device_t aha1640_device = { - "Adaptec AHA-1640", - DEVICE_MCA, - AHA_1640, - aha_init, x54x_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/scsi/scsi_aha154x.h b/src - Cópia/scsi/scsi_aha154x.h deleted file mode 100644 index 73eb10b89..000000000 --- a/src - Cópia/scsi/scsi_aha154x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SCSI_AHA154X_H -# define SCSI_AHA154X_H - - -extern const device_t aha1540b_device; -extern const device_t aha1542c_device; -extern const device_t aha1542cf_device; -extern const device_t aha1640_device; - -extern void aha_device_reset(void *p); - - -#endif /*SCSI_AHA154X_H*/ diff --git a/src - Cópia/scsi/scsi_bus.c b/src - Cópia/scsi/scsi_bus.c deleted file mode 100644 index 5d870954d..000000000 --- a/src - Cópia/scsi/scsi_bus.c +++ /dev/null @@ -1,366 +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. - * - * The generic SCSI bus operations handler. - * - * Version: @(#)scsi_bus.c 1.0.6 2018/01/06 - * - * NOTES: For now ported from PCem with some modifications - * but at least it's a start. - * - * Authors: TheCollector1995, - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "scsi.h" -#include "scsi_device.h" - - -#define STATE_IDLE 0 -#define STATE_COMMAND 1 -#define STATE_COMMANDWAIT 2 -#define STATE_DATAIN 3 -#define STATE_DATAOUT 4 -#define STATE_STATUS 5 -#define STATE_MESSAGEIN 6 -#define STATE_PHASESEL 7 - -#define SET_BUS_STATE(bus, state) bus->bus_out = (bus->bus_out & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) - -uint32_t SCSI_BufferLength; -#ifdef ENABLE_SCSI_BUS_LOG -int scsi_bus_do_log = ENABLE_SCSI_BUS_LOG; -#endif - - -static void -scsi_bus_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_BUS_LOG - va_list ap; - - if (scsi_bus_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* get the length of a SCSI command based on its command byte type */ -static int get_cmd_len(int cbyte) -{ - int len; - int group; - - group = (cbyte>>5) & 7; - - if (group == 0) len = 6; - if (group == 1 || group == 2) len = 10; - if (group == 5) len = 12; - -// scsi_bus_log("Command group %d, length %d\n", group, len); - - return(len); -} - - -static int -get_dev_id(uint8_t data) -{ - int c; - - for (c = 0; c < SCSI_ID_MAX; c++) { - if (data & (1 << c)) return(c); - } - - return(-1); -} - - -int -scsi_bus_update(scsi_bus_t *bus, int bus_assert) -{ - scsi_device_t *dev; - uint8_t lun = 0; - - if (bus_assert & BUS_ARB) - bus->state = STATE_IDLE; - - switch (bus->state) { - case STATE_IDLE: - scsi_bus_log("State Idle\n"); - bus->clear_req = bus->change_state_delay = bus->new_req_delay = 0; - if ((bus_assert & BUS_SEL) && !(bus_assert & BUS_BSY)) { - uint8_t sel_data = BUS_GETDATA(bus_assert); - - bus->dev_id = get_dev_id(sel_data); - - if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0)) { - bus->bus_out |= BUS_BSY; - bus->state = STATE_PHASESEL; - } - //scsi_bus_log("Device id %i\n", bus->dev_id); - break; - } - break; - - case STATE_PHASESEL: - scsi_bus_log("State Phase Sel\n"); - if (! (bus_assert & BUS_SEL)) { - if (! (bus_assert & BUS_ATN)) { - if ((bus->dev_id != -1) && - scsi_device_present(bus->dev_id, 0)) { - bus->state = STATE_COMMAND; - bus->bus_out = BUS_BSY | BUS_REQ; - bus->command_pos = 0; - SET_BUS_STATE(bus, SCSI_PHASE_COMMAND); - } else { - bus->state = STATE_IDLE; - bus->bus_out = 0; - } - } else - fatal("dropped sel %x\n", bus_assert & BUS_ATN); - } - break; - - case STATE_COMMAND: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - scsi_bus_log("State Command\n"); - bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert); - - bus->clear_req = 3; - bus->new_state = bus->bus_out & SCSI_PHASE_MESSAGE_IN; - bus->bus_out &= ~BUS_REQ; - - if (get_cmd_len(bus->command[0]) == bus->command_pos) { - lun = (bus->command[1] >> 5) & 7; - bus->data_pos = 0; - - dev = &SCSIDevices[bus->dev_id][lun]; - - scsi_bus_log("Command 0x%02X\n", bus->command[0]); - - dev->BufferLength = -1; - - scsi_device_command_phase0(bus->dev_id, lun, - get_cmd_len(bus->command[0]), - bus->command); - - scsi_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, dev->Phase); - - if ((dev->Phase == SCSI_PHASE_DATA_IN) || - (dev->Phase == SCSI_PHASE_DATA_OUT)) { - scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer); - dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength); - scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer); - } - - if (dev->Phase == SCSI_PHASE_DATA_OUT) { - /* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */ - scsi_bus_log("Next state is data out\n"); - - bus->state = STATE_COMMANDWAIT; - bus->clear_req = 0; - } else { - /* Other command - execute immediately. */ - bus->new_state = dev->Phase; - if (dev->Phase == SCSI_PHASE_DATA_IN) { - scsi_device_command_phase1(bus->dev_id, lun); - } - - bus->change_state_delay = 4; - } - } - } - break; - - case STATE_COMMANDWAIT: - bus->new_state = SCSI_PHASE_DATA_OUT; - bus->change_state_delay = 4; - bus->clear_req = 4; - break; - - case STATE_DATAIN: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - scsi_bus_log("State Data In\n"); - - /* This seems to be read, so we first execute the command, then we return the bytes to the host. */ - - lun = (bus->command[1] >> 5) & 7; - - dev = &SCSIDevices[bus->dev_id][lun]; - - if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - bus->bus_out &= ~BUS_REQ; - bus->new_state = SCSI_PHASE_STATUS; - bus->change_state_delay = 4; - bus->new_req_delay = 8; - } else { - uint8_t val = dev->CmdBuffer[bus->data_pos++]; - - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; - bus->clear_req = 3; - bus->bus_out &= ~BUS_REQ; - bus->new_state = SCSI_PHASE_DATA_IN; - } - } - break; - - case STATE_DATAOUT: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - scsi_bus_log("State Data Out\n"); - - lun = (bus->command[1] >> 5) & 7; - - dev = &SCSIDevices[bus->dev_id][lun]; - - /* This is write, so first get the data from the host, then execute the last phase of the command. */ - dev->CmdBuffer[bus->data_pos++] = BUS_GETDATA(bus_assert); - - if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) { - /* scsi_bus_log("%04X bytes written (%02X %02X)\n", bus->data_pos, bus->command[0], bus->command[1]); */ - scsi_bus_log("Actually executing write command\n"); - scsi_device_command_phase1(bus->dev_id, lun); - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - bus->bus_out &= ~BUS_REQ; - bus->new_state = SCSI_PHASE_STATUS; - bus->change_state_delay = 4; - bus->new_req_delay = 8; - } else { - bus->bus_out |= BUS_REQ; - } - } - break; - - case STATE_STATUS: - scsi_bus_log("State Status\n"); - - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - /* scsi_bus_log("Preparing for message in\n"); */ - bus->bus_out &= ~BUS_REQ; - bus->new_state = SCSI_PHASE_MESSAGE_IN; - bus->change_state_delay = 4; - bus->new_req_delay = 8; - } - break; - - case STATE_MESSAGEIN: - scsi_bus_log("State Message In\n"); - - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - bus->bus_out &= ~BUS_REQ; - bus->new_state = BUS_IDLE; - bus->change_state_delay = 4; - } - break; - } - - bus->bus_in = bus_assert; - - return(bus->bus_out | bus->bus_in); -} - - -int -scsi_bus_read(scsi_bus_t *bus) -{ - scsi_device_t *dev; - uint8_t lun = 0; - - if (bus->clear_req) { - bus->clear_req--; - if (!bus->clear_req) { - scsi_bus_log("Clear REQ\n"); - - SET_BUS_STATE(bus, bus->new_state); - bus->bus_out |= BUS_REQ; - } - } - - if (bus->change_state_delay) { - bus->change_state_delay--; - if (!bus->change_state_delay) { - uint8_t val; - - scsi_bus_log("Change state delay\n"); - - SET_BUS_STATE(bus, bus->new_state); - - switch (bus->bus_out & SCSI_PHASE_MESSAGE_IN) { - case SCSI_PHASE_DATA_IN: - lun = (bus->command[1] >> 5) & 7; - dev = &SCSIDevices[bus->dev_id][lun]; - - scsi_bus_log("Phase data in\n"); - bus->state = STATE_DATAIN; - val = dev->CmdBuffer[bus->data_pos++]; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP; - break; - - case SCSI_PHASE_DATA_OUT: - scsi_bus_log("Phase data out\n"); - if (bus->new_state & BUS_IDLE) { - bus->state = STATE_IDLE; - bus->bus_out &= ~BUS_BSY; - } else { - bus->state = STATE_DATAOUT; - } - break; - - case SCSI_PHASE_STATUS: - lun = (bus->command[1] >> 5) & 7; - dev = &SCSIDevices[bus->dev_id][lun]; - - scsi_bus_log("Phase status\n"); - bus->state = STATE_STATUS; - bus->bus_out |= BUS_REQ; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->Status) | BUS_DBP; - /* scsi_bus_log("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], dev->Status, bus->bus_out); */ - break; - - case SCSI_PHASE_MESSAGE_IN: - scsi_bus_log("Phase message in\n"); - /* scsi_bus_log("Message in\n"); */ - bus->state = STATE_MESSAGEIN; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; - break; - - default: - fatal("change_state_delay bad state %x\n", bus->bus_out); - } - } - } - - if (bus->new_req_delay) { - bus->new_req_delay--; - if (!bus->new_req_delay) { - bus->bus_out |= BUS_REQ; - } - } - - return(bus->bus_out); -} - - -int -scsi_bus_match(scsi_bus_t *bus, int bus_assert) -{ - return((bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == - (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG))); -} diff --git a/src - Cópia/scsi/scsi_buslogic.c b/src - Cópia/scsi/scsi_buslogic.c deleted file mode 100644 index 6ce2fb2da..000000000 --- a/src - Cópia/scsi/scsi_buslogic.c +++ /dev/null @@ -1,1817 +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. - * - * Emulation of BusLogic ISA and PCI SCSI controllers. Boards - * supported: - * - * 0 - BT-542BH ISA; - * 1 - BT-545S ISA; - * 2 - BT-958D PCI - * - * Version: @(#)scsi_buslogic.c 1.0.38 2018/04/26 - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.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 "../timer.h" -#include "../plat.h" -#include "scsi.h" -#include "scsi_buslogic.h" -#include "scsi_device.h" -#include "scsi_x54x.h" - - -/* - * Auto SCSI structure which is located - * in host adapter RAM and contains several - * configuration parameters. - */ -#pragma pack(push,1) -typedef struct { - uint8_t aInternalSignature[2]; - uint8_t cbInformation; - uint8_t aHostAdaptertype[6]; - uint8_t uReserved1; - uint8_t fFloppyEnabled :1, - fFloppySecondary :1, - fLevelSensitiveInterrupt:1, - uReserved2 :2, - uSystemRAMAreForBIOS :3; - uint8_t uDMAChannel :7, - fDMAAutoConfiguration :1, - uIrqChannel :7, - fIrqAutoConfiguration :1; - uint8_t uDMATransferRate; - uint8_t uSCSIId; - uint8_t uSCSIConfiguration; - uint8_t uBusOnDelay; - uint8_t uBusOffDelay; - uint8_t uBIOSConfiguration; - uint16_t u16DeviceEnabledMask; - uint16_t u16WidePermittedMask; - uint16_t u16FastPermittedMask; - uint16_t u16SynchronousPermittedMask; - uint16_t u16DisconnectPermittedMask; - uint16_t u16SendStartUnitCommandMask; - uint16_t u16IgnoreInBIOSScanMask; - unsigned char uPCIInterruptPin : 2; - unsigned char uHostAdapterIoPortAddress : 2; - uint8_t fRoundRobinScheme : 1; - uint8_t fVesaBusSpeedGreaterThan33MHz : 1; - uint8_t fVesaBurstWrite : 1; - uint8_t fVesaBurstRead : 1; - uint16_t u16UltraPermittedMask; - uint32_t uReserved5; - uint8_t uReserved6; - uint8_t uAutoSCSIMaximumLUN; - uint8_t fReserved7 : 1; - uint8_t fSCAMDominant : 1; - uint8_t fSCAMenabled : 1; - uint8_t fSCAMLevel2 : 1; - unsigned char uReserved8 : 4; - uint8_t fInt13Extension : 1; - uint8_t fReserved9 : 1; - uint8_t fCDROMBoot : 1; - unsigned char uReserved10 : 2; - uint8_t fMultiBoot : 1; - unsigned char uReserved11 : 2; - unsigned char uBootTargetId : 4; - unsigned char uBootChannel : 4; - uint8_t fForceBusDeviceScanningOrder : 1; - unsigned char uReserved12 : 7; - uint16_t u16NonTaggedToAlternateLunPermittedMask; - uint16_t u16RenegotiateSyncAfterCheckConditionMask; - uint8_t aReserved14[10]; - uint8_t aManufacturingDiagnostic[2]; - uint16_t u16Checksum; -} AutoSCSIRam; -#pragma pack(pop) - -/* The local RAM. */ -#pragma pack(push,1) -typedef union { - uint8_t u8View[256]; /* byte view */ - struct { /* structured view */ - uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ - AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ - } structured; -} HALocalRAM; -#pragma pack(pop) - -/** Structure for the INQUIRE_SETUP_INFORMATION reply. */ -#pragma pack(push,1) -typedef struct { - uint8_t uSignature; - uint8_t uCharacterD; - uint8_t uHostBusType; - uint8_t uWideTransferPermittedId0To7; - uint8_t uWideTransfersActiveId0To7; - ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; - uint8_t uDisconnectPermittedId8To15; - uint8_t uReserved2; - uint8_t uWideTransferPermittedId8To15; - uint8_t uWideTransfersActiveId8To15; -} buslogic_setup_t; -#pragma pack(pop) - -/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ -#pragma pack(push,1) -typedef struct { - uint8_t uBusType; - uint8_t uBiosAddress; - uint16_t u16ScatterGatherLimit; - uint8_t cMailbox; - uint32_t uMailboxAddressBase; - uint8_t uReserved1 :2, - fFastEISA :1, - uReserved2 :3, - fLevelSensitiveInterrupt:1, - uReserved3 :1; - uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI :1, - fHostDifferentialSCSI :1, - fHostSupportsSCAM :1, - fHostUltraSCSI :1, - fHostSmartTermination :1, - uReserved4 :3; -} ReplyInquireExtendedSetupInformation; -#pragma pack(pop) - -/* Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ -#pragma pack(push,1) -typedef struct { - uint8_t IsaIOPort; - uint8_t IRQ; - uint8_t LowByteTerminated :1, - HighByteTerminated :1, - uReserved :2, /* Reserved. */ - JP1 :1, /* Whatever that means. */ - JP2 :1, /* Whatever that means. */ - JP3 :1, /* Whatever that means. */ - InformationIsValid :1; - uint8_t uReserved2; /* Reserved. */ -} BuslogicPCIInformation_t; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct -{ - /** Data length. */ - uint32_t DataLength; - /** Data pointer. */ - uint32_t DataPointer; - /** The device the request is sent to. */ - uint8_t TargetId; - /** The LUN in the device. */ - uint8_t LogicalUnit; - /** Reserved */ - unsigned char Reserved1 : 3; - /** Data direction for the request. */ - unsigned char DataDirection : 2; - /** Reserved */ - unsigned char Reserved2 : 3; - /** Length of the SCSI CDB. */ - uint8_t CDBLength; - /** The SCSI CDB. (A CDB can be 12 bytes long.) */ - uint8_t CDB[12]; -} ESCMD; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t Count; - uint32_t Address; -} MailboxInitExtended_t; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - rom_t bios; - int ExtendedLUNCCBFormat; - int fAggressiveRoundRobinMode; - HALocalRAM LocalRAM; - int PCIBase; - int MMIOBase; - int chip; - int has_bios; - uint32_t bios_addr, - bios_size, - bios_mask; - uint8_t AutoSCSIROM[32768]; - uint8_t SCAMData[65536]; -} buslogic_data_t; -#pragma pack(pop) - - -enum { - CHIP_BUSLOGIC_ISA_542, - CHIP_BUSLOGIC_ISA, - CHIP_BUSLOGIC_MCA, - CHIP_BUSLOGIC_EISA, - CHIP_BUSLOGIC_VLB, - CHIP_BUSLOGIC_PCI -}; - - -#ifdef ENABLE_BUSLOGIC_LOG -int buslogic_do_log = ENABLE_BUSLOGIC_LOG; -#endif - - -static void -buslogic_log(const char *fmt, ...) -{ -#ifdef ENABLE_BUSLOGIC_LOG - va_list ap; - - if (buslogic_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static wchar_t * -BuslogicGetNVRFileName(buslogic_data_t *bl) -{ - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542: - return L"bt542bh.nvr"; - case CHIP_BUSLOGIC_ISA: - return L"bt545s.nvr"; - case CHIP_BUSLOGIC_MCA: - return L"bt640a.nvr"; - case CHIP_BUSLOGIC_VLB: - return L"bt445s.nvr"; - case CHIP_BUSLOGIC_PCI: - return L"bt958d.nvr"; - default: - fatal("Unrecognized BusLogic chip: %i\n", bl->chip); - return NULL; - } -} - - -static void -BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) -{ - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; - - memset(&(HALR->structured.autoSCSIData), 0, sizeof(AutoSCSIRam)); - - HALR->structured.autoSCSIData.aInternalSignature[0] = 'F'; - HALR->structured.autoSCSIData.aInternalSignature[1] = 'A'; - - HALR->structured.autoSCSIData.cbInformation = 64; - - HALR->structured.autoSCSIData.uReserved1 = 6; - - HALR->structured.autoSCSIData.aHostAdaptertype[0] = ' '; - HALR->structured.autoSCSIData.aHostAdaptertype[5] = ' '; - switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542BH", 5); - break; - case CHIP_BUSLOGIC_ISA: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545S", 4); - break; - case CHIP_BUSLOGIC_MCA: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4); - break; - case CHIP_BUSLOGIC_VLB: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445S", 4); - break; - case CHIP_BUSLOGIC_PCI: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4); - break; - } - - HALR->structured.autoSCSIData.fLevelSensitiveInterrupt = (bl->chip == CHIP_BUSLOGIC_PCI) ? 1 : 0; - HALR->structured.autoSCSIData.uSystemRAMAreForBIOS = 6; - - if (bl->chip != CHIP_BUSLOGIC_PCI) { - switch(dev->DmaChannel) { - case 5: - HALR->structured.autoSCSIData.uDMAChannel = 1; - break; - case 6: - HALR->structured.autoSCSIData.uDMAChannel = 2; - break; - case 7: - HALR->structured.autoSCSIData.uDMAChannel = 3; - break; - default: - HALR->structured.autoSCSIData.uDMAChannel = 0; - break; - } - } - HALR->structured.autoSCSIData.fDMAAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; - - if (bl->chip != CHIP_BUSLOGIC_PCI) { - switch(dev->Irq) { - case 9: - HALR->structured.autoSCSIData.uIrqChannel = 1; - break; - case 10: - HALR->structured.autoSCSIData.uIrqChannel = 2; - break; - case 11: - HALR->structured.autoSCSIData.uIrqChannel = 3; - break; - case 12: - HALR->structured.autoSCSIData.uIrqChannel = 4; - break; - case 14: - HALR->structured.autoSCSIData.uIrqChannel = 5; - break; - case 15: - HALR->structured.autoSCSIData.uIrqChannel = 6; - break; - default: - HALR->structured.autoSCSIData.uIrqChannel = 0; - break; - } - } - HALR->structured.autoSCSIData.fIrqAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; - - HALR->structured.autoSCSIData.uDMATransferRate = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; - - HALR->structured.autoSCSIData.uSCSIId = 7; - HALR->structured.autoSCSIData.uSCSIConfiguration = 0x3F; - HALR->structured.autoSCSIData.uBusOnDelay = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 7; - HALR->structured.autoSCSIData.uBusOffDelay = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 4; - HALR->structured.autoSCSIData.uBIOSConfiguration = (bl->has_bios) ? 0x33 : 0x32; - if (!safe) - HALR->structured.autoSCSIData.uBIOSConfiguration |= 0x04; - - HALR->structured.autoSCSIData.u16DeviceEnabledMask = 0xffff; - HALR->structured.autoSCSIData.u16WidePermittedMask = 0xffff; - HALR->structured.autoSCSIData.u16FastPermittedMask = 0xffff; - HALR->structured.autoSCSIData.u16DisconnectPermittedMask = 0xffff; - - HALR->structured.autoSCSIData.uPCIInterruptPin = PCI_INTA; - HALR->structured.autoSCSIData.fVesaBusSpeedGreaterThan33MHz = 1; - - HALR->structured.autoSCSIData.uAutoSCSIMaximumLUN = 7; - - HALR->structured.autoSCSIData.fForceBusDeviceScanningOrder = 1; - HALR->structured.autoSCSIData.fInt13Extension = safe ? 0 : 1; - HALR->structured.autoSCSIData.fCDROMBoot = safe ? 0 : 1; - HALR->structured.autoSCSIData.fMultiBoot = safe ? 0 : 1; - HALR->structured.autoSCSIData.fRoundRobinScheme = safe ? 1 : 0; /* 1 = aggressive, 0 = strict */ - - HALR->structured.autoSCSIData.uHostAdapterIoPortAddress = 2; /* 0 = primary (330h), 1 = secondary (334h), 2 = disable, 3 = reserved */ -} - - -static void -BuslogicInitializeAutoSCSIRam(x54x_t *dev) -{ - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; - - FILE *f; - - f = nvr_fopen(BuslogicGetNVRFileName(bl), L"rb"); - if (f) - { - fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f); - fclose(f); - f = NULL; - if (bl->chip == CHIP_BUSLOGIC_PCI) { - x54x_io_remove(dev, dev->Base, 4); - switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { - case 0: - dev->Base = 0x330; - break; - case 1: - dev->Base = 0x334; - break; - default: - dev->Base = 0; - break; - } - x54x_io_set(dev, dev->Base, 4); - } - } - else - { - BuslogicAutoSCSIRamSetDefaults(dev, 0); - } -} - - -static void -buslogic_cmd_phase1(void *p) -{ - x54x_t *dev = (x54x_t *)p; - - if ((dev->CmdParam == 2) && (dev->Command == 0x90)) { - dev->CmdParamLeft = dev->CmdBuf[1]; - } - - if ((dev->CmdParam == 10) && ((dev->Command == 0x97) || (dev->Command == 0xA7))) { - dev->CmdParamLeft = dev->CmdBuf[6]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[7]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[8]; - } - - if ((dev->CmdParam == 4) && (dev->Command == 0xA9)) { - dev->CmdParamLeft = dev->CmdBuf[3]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[2]; - } -} - - -static uint8_t -buslogic_get_host_id(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - HALocalRAM *HALR = &bl->LocalRAM; - - if (bl->chip == CHIP_BUSLOGIC_ISA_542) - return dev->HostID; - else - return HALR->structured.autoSCSIData.uSCSIId; -} - - -static uint8_t -buslogic_get_irq(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - uint8_t bl_irq[7] = { 0, 9, 10, 11, 12, 14, 15 }; - - HALocalRAM *HALR = &bl->LocalRAM; - - if (bl->chip == CHIP_BUSLOGIC_PCI) - return dev->Irq; - else - return bl_irq[HALR->structured.autoSCSIData.uIrqChannel]; -} - - -static uint8_t -buslogic_get_dma(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - uint8_t bl_dma[4] = { 0, 5, 6, 7 }; - - HALocalRAM *HALR = &bl->LocalRAM; - - if (bl->chip == CHIP_BUSLOGIC_PCI) - return (dev->Base ? 7 : 0); - else - return bl_dma[HALR->structured.autoSCSIData.uDMAChannel]; -} - - -static uint8_t -buslogic_param_len(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - switch (dev->Command) { - case 0x21: - return 5; - case 0x25: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8F: - case 0x92: - case 0x96: - return 1; - case 0x81: - return sizeof(MailboxInitExtended_t); - case 0x83: - return 12; - case 0x90: - case 0x91: - return 2; - case 0x94: - case 0xFB: - return 3; - case 0x93: /* Valid only for VLB */ - return (bl->chip == CHIP_BUSLOGIC_VLB) ? 1 : 0; - case 0x95: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 1 : 0; - case 0x97: /* Valid only for PCI */ - case 0xA7: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 10 : 0; - case 0xA8: /* Valid only for PCI */ - case 0xA9: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 4 : 0; - default: - return 0; - } -} - - -static void -BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int dir) -{ - uint32_t DataPointer = ESCSICmd->DataPointer; - int DataLength = ESCSICmd->DataLength; - uint32_t Address; - uint32_t TransferLength; - - if (ESCSICmd->DataDirection == 0x03) { - /* Non-data command. */ - buslogic_log("BuslogicSCSIBIOSDMATransfer(): Non-data control byte\n"); - return; - } - - buslogic_log("BuslogicSCSIBIOSDMATransfer(): BIOS Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); - - /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without - checking its length, so do this procedure for both read/write commands. */ - if ((DataLength > 0) && (SCSIDevices[TargetID][LUN].BufferLength > 0)) { - Address = DataPointer; - TransferLength = MIN(DataLength, SCSIDevices[TargetID][LUN].BufferLength); - - if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) { - buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address); - DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength); - } else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) { - buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address); - DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength); - } - } -} - - -static void -BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, uint8_t DataReply) -{ - ESCMD *ESCSICmd = (ESCMD *)CmdBuf; - uint32_t i; - uint8_t temp_cdb[12]; - int target_cdb_len = 12; - uint8_t target_id = 0; - int phase; - - DataInBuf[0] = DataInBuf[1] = 0; - - if ((ESCSICmd->TargetId > 15) || (ESCSICmd->LogicalUnit > 7)) { - DataInBuf[2] = CCB_INVALID_CCB; - DataInBuf[3] = SCSI_STATUS_OK; - return; - } - - buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId); - - SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status = SCSI_STATUS_OK; - - if (!scsi_device_present(ESCSICmd->TargetId, 0)) { - buslogic_log("SCSI Target ID %i has no device attached\n",ESCSICmd->TargetId,ESCSICmd->LogicalUnit); - DataInBuf[2] = CCB_SELECTION_TIMEOUT; - DataInBuf[3] = SCSI_STATUS_OK; - } else { - buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - - buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection); - buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength); - if (ESCSICmd->DataDirection > 0x03) { - buslogic_log("Invalid control byte: %02X\n", - ESCSICmd->DataDirection); - } - } - - x54x_buf_alloc(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->DataLength); - - target_cdb_len = scsi_device_cdb_length(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - - if (!scsi_device_valid(ESCSICmd->TargetId, ESCSICmd->LogicalUnit)) fatal("SCSI target on %02i:%02i has disappeared\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - - buslogic_log("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id); - - buslogic_log("SCSI Cdb[0]=0x%02X\n", ESCSICmd->CDB[0]); - for (i = 1; i < ESCSICmd->CDBLength; i++) { - buslogic_log("SCSI Cdb[%i]=%i\n", i, ESCSICmd->CDB[i]); - } - - memset(temp_cdb, 0, target_cdb_len); - if (ESCSICmd->CDBLength <= target_cdb_len) { - memcpy(temp_cdb, ESCSICmd->CDB, ESCSICmd->CDBLength); - } else { - memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len); - } - - SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].BufferLength = ESCSICmd->DataLength; - scsi_device_command_phase0(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->CDBLength, temp_cdb); - - phase = SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Phase; - if (phase != SCSI_PHASE_STATUS) { - if (phase == SCSI_PHASE_DATA_IN) - scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit, (phase == SCSI_PHASE_DATA_OUT)); - if (phase == SCSI_PHASE_DATA_OUT) - scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - } - - x54x_buf_free(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - - buslogic_log("BIOS Request complete\n"); - - if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_OK) { - DataInBuf[2] = CCB_COMPLETE; - DataInBuf[3] = SCSI_STATUS_OK; - } else if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_CHECK_CONDITION) { - DataInBuf[2] = CCB_COMPLETE; - DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; - } - - dev->DataReplyLeft = DataReply; -} - - -static uint8_t -buslogic_cmds(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - HALocalRAM *HALR = &bl->LocalRAM; - - FILE *f; - uint16_t TargetsPresentMask = 0; - uint32_t Offset; - int i = 0; - int j = 0; - MailboxInitExtended_t *MailboxInitE; - ReplyInquireExtendedSetupInformation *ReplyIESI; - BuslogicPCIInformation_t *ReplyPI; - int cCharsToTransfer; - - switch (dev->Command) { - case 0x20: - dev->DataReplyLeft = 0; - x54x_reset_ctrl(dev, 1); - break; - case 0x21: - if (dev->CmdParam == 1) - dev->CmdParamLeft = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - break; - case 0x23: - memset(dev->DataBuf, 0, 8); - for (i = 8; i < 15; i++) { - dev->DataBuf[i-8] = 0; - for (j=0; j<8; j++) { - if (scsi_device_present(i, j) && (i != buslogic_get_host_id(dev))) - dev->DataBuf[i-8] |= (1<DataReplyLeft = 8; - break; - case 0x24: - for (i=0; i<15; i++) { - if (scsi_device_present(i, 0) && (i != buslogic_get_host_id(dev))) - TargetsPresentMask |= (1 << i); - } - dev->DataBuf[0] = TargetsPresentMask & 0xFF; - dev->DataBuf[1] = TargetsPresentMask >> 8; - dev->DataReplyLeft = 2; - break; - case 0x25: - if (dev->CmdBuf[0] == 0) - dev->IrqEnabled = 0; - else - dev->IrqEnabled = 1; - return 1; - case 0x81: - dev->Mbx24bit = 0; - - MailboxInitE = (MailboxInitExtended_t *)dev->CmdBuf; - - dev->MailboxInit = 1; - dev->MailboxCount = MailboxInitE->Count; - dev->MailboxOutAddr = MailboxInitE->Address; - dev->MailboxInAddr = MailboxInitE->Address + (dev->MailboxCount * sizeof(Mailbox32_t)); - - buslogic_log("Buslogic Extended Initialize Mailbox Command\n"); - buslogic_log("Mailbox Out Address=0x%08X\n", dev->MailboxOutAddr); - buslogic_log("Mailbox In Address=0x%08X\n", dev->MailboxInAddr); - buslogic_log("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); - - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - break; - case 0x83: - if (dev->CmdParam == 12) { - dev->CmdParamLeft = dev->CmdBuf[11]; - buslogic_log("Execute SCSI BIOS Command: %u more bytes follow\n", dev->CmdParamLeft); - } else { - buslogic_log("Execute SCSI BIOS Command: received %u bytes\n", dev->CmdBuf[0]); - BuslogicSCSIBIOSRequestSetup(dev, dev->CmdBuf, dev->DataBuf, 4); - } - break; - case 0x84: - dev->DataBuf[0] = dev->fw_rev[4]; - dev->DataReplyLeft = 1; - break; - case 0x85: - if (strlen(dev->fw_rev) == 6) - dev->DataBuf[0] = dev->fw_rev[5]; - else - dev->DataBuf[0] = ' '; - dev->DataReplyLeft = 1; - break; - case 0x86: - if (bl->chip == CHIP_BUSLOGIC_PCI) { - ReplyPI = (BuslogicPCIInformation_t *) dev->DataBuf; - memset(ReplyPI, 0, sizeof(BuslogicPCIInformation_t)); - ReplyPI->InformationIsValid = 0; - switch(dev->Base) { - case 0x330: - ReplyPI->IsaIOPort = 0; - break; - case 0x334: - ReplyPI->IsaIOPort = 1; - break; - case 0x230: - ReplyPI->IsaIOPort = 2; - break; - case 0x234: - ReplyPI->IsaIOPort = 3; - break; - case 0x130: - ReplyPI->IsaIOPort = 4; - break; - case 0x134: - ReplyPI->IsaIOPort = 5; - break; - default: - ReplyPI->IsaIOPort = 6; - break; - } - ReplyPI->IRQ = dev->Irq; - dev->DataReplyLeft = sizeof(BuslogicPCIInformation_t); - } else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - case 0x8B: - /* The reply length is set by the guest and is found in the first byte of the command buffer. */ - dev->DataReplyLeft = dev->CmdBuf[0]; - memset(dev->DataBuf, 0, dev->DataReplyLeft); - if (bl->chip == CHIP_BUSLOGIC_ISA_542) - i = 5; - else - i = 4; - cCharsToTransfer = MIN(dev->DataReplyLeft, i); - - memcpy(dev->DataBuf, &(bl->LocalRAM.structured.autoSCSIData.aHostAdaptertype[1]), cCharsToTransfer); - break; - case 0x8C: - dev->DataReplyLeft = dev->CmdBuf[0]; - memset(dev->DataBuf, 0, dev->DataReplyLeft); - break; - case 0x8D: - dev->DataReplyLeft = dev->CmdBuf[0]; - ReplyIESI = (ReplyInquireExtendedSetupInformation *)dev->DataBuf; - memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); - - switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542: - case CHIP_BUSLOGIC_ISA: - case CHIP_BUSLOGIC_VLB: - ReplyIESI->uBusType = 'A'; /* ISA style */ - break; - case CHIP_BUSLOGIC_MCA: - ReplyIESI->uBusType = 'M'; /* MCA style */ - break; - case CHIP_BUSLOGIC_PCI: - ReplyIESI->uBusType = 'E'; /* PCI style */ - break; - } - ReplyIESI->uBiosAddress = 0xd8; - ReplyIESI->u16ScatterGatherLimit = 8192; - ReplyIESI->cMailbox = dev->MailboxCount; - ReplyIESI->uMailboxAddressBase = dev->MailboxOutAddr; - ReplyIESI->fHostWideSCSI = 1; /* This should be set for the BT-542B as well. */ - if ((bl->chip != CHIP_BUSLOGIC_ISA_542) && (bl->chip != CHIP_BUSLOGIC_MCA)) - ReplyIESI->fLevelSensitiveInterrupt = bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; - if (bl->chip == CHIP_BUSLOGIC_PCI) - ReplyIESI->fHostUltraSCSI = 1; - memcpy(ReplyIESI->aFirmwareRevision, &(dev->fw_rev[strlen(dev->fw_rev) - 3]), sizeof(ReplyIESI->aFirmwareRevision)); - buslogic_log("Return Extended Setup Information: %d\n", dev->CmdBuf[0]); - break; - case 0x8F: - bl->fAggressiveRoundRobinMode = dev->CmdBuf[0] & 1; - - dev->DataReplyLeft = 0; - break; - case 0x90: - buslogic_log("Store Local RAM\n"); - Offset = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - memcpy(&(bl->LocalRAM.u8View[Offset]), &(dev->CmdBuf[2]), dev->CmdBuf[1]); - - dev->DataReply = 0; - break; - case 0x91: - buslogic_log("Fetch Local RAM\n"); - Offset = dev->CmdBuf[0]; - dev->DataReplyLeft = dev->CmdBuf[1]; - memcpy(dev->DataBuf, &(bl->LocalRAM.u8View[Offset]), dev->CmdBuf[1]); - - dev->DataReply = 0; - break; - case 0x93: - if (bl->chip != CHIP_BUSLOGIC_VLB) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - case 0x92: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_MCA)) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - - dev->DataReplyLeft = 0; - - switch (dev->CmdBuf[0]) { - case 0: - case 2: - BuslogicAutoSCSIRamSetDefaults(dev, 0); - break; - case 3: - BuslogicAutoSCSIRamSetDefaults(dev, 3); - break; - case 1: - f = nvr_fopen(BuslogicGetNVRFileName(bl), L"wb"); - if (f) { - fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f); - fclose(f); - f = NULL; - } - break; - default: - dev->Status |= STAT_INVCMD; - break; - } - - if ((bl->chip == CHIP_BUSLOGIC_PCI) && !(dev->Status & STAT_INVCMD)) { - x54x_io_remove(dev, dev->Base, 4); - switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { - case 0: - dev->Base = 0x330; - break; - case 1: - dev->Base = 0x334; - break; - default: - dev->Base = 0; - break; - } - x54x_io_set(dev, dev->Base, 4); - } - break; - case 0x94: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_MCA)) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - - if (dev->CmdBuf[0]) { - buslogic_log("Invalid AutoSCSI command mode %x\n", dev->CmdBuf[0]); - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } else { - dev->DataReplyLeft = dev->CmdBuf[2]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[1]; - memcpy(dev->DataBuf, bl->AutoSCSIROM, dev->DataReplyLeft); - buslogic_log("Returning AutoSCSI ROM (%04X %04X %04X %04X)\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2], dev->DataBuf[3]); - } - break; - case 0x95: - if (bl->chip == CHIP_BUSLOGIC_PCI) { - if (dev->Base != 0) - x54x_io_remove(dev, dev->Base, 4); - if (dev->CmdBuf[0] < 6) { - dev->Base = ((3 - (dev->CmdBuf[0] >> 1)) << 8) | ((dev->CmdBuf[0] & 1) ? 0x34 : 0x30); - x54x_io_set(dev, dev->Base, 4); - } else - dev->Base = 0; - dev->DataReplyLeft = 0; - return 1; - } else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - case 0x96: - if (dev->CmdBuf[0] == 0) - bl->ExtendedLUNCCBFormat = 0; - else if (dev->CmdBuf[0] == 1) - bl->ExtendedLUNCCBFormat = 1; - - dev->DataReplyLeft = 0; - break; - case 0x97: - case 0xA7: - /* TODO: Actually correctly implement this whole SCSI BIOS Flash stuff. */ - dev->DataReplyLeft = 0; - break; - case 0xA8: - if (bl->chip != CHIP_BUSLOGIC_PCI) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - - Offset = dev->CmdBuf[1]; - Offset <<= 8; - Offset |= dev->CmdBuf[0]; - - dev->DataReplyLeft = dev->CmdBuf[3]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[2]; - - memcpy(dev->DataBuf, &(bl->SCAMData[Offset]), dev->DataReplyLeft); - - dev->DataReply = 0; - break; - case 0xA9: - if (bl->chip != CHIP_BUSLOGIC_PCI) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - - Offset = dev->CmdBuf[1]; - Offset <<= 8; - Offset |= dev->CmdBuf[0]; - - dev->DataReplyLeft = dev->CmdBuf[3]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[2]; - - memcpy(&(bl->SCAMData[Offset]), &(dev->CmdBuf[4]), dev->DataReplyLeft); - dev->DataReplyLeft = 0; - - dev->DataReply = 0; - break; - case 0xFB: - dev->DataReplyLeft = dev->CmdBuf[2]; - break; - default: - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - return 0; -} - - -static void -buslogic_setup_data(void *p) -{ - x54x_t *dev = (x54x_t *)p; - ReplyInquireSetupInformation *ReplyISI; - buslogic_setup_t *bl_setup; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; - - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - bl_setup = (buslogic_setup_t *)ReplyISI->VendorSpecificData; - - ReplyISI->fSynchronousInitiationEnabled = HALR->structured.autoSCSIData.u16SynchronousPermittedMask ? 1 : 0; - ReplyISI->fParityCheckingEnabled = (HALR->structured.autoSCSIData.uSCSIConfiguration & 2) ? 1 : 0; - - bl_setup->uSignature = 'B'; - /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too - * friendly with Adaptec hardware and upsetting the HBA state. - */ - bl_setup->uCharacterD = 'D'; /* BusLogic model. */ - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542: - case CHIP_BUSLOGIC_ISA: - bl_setup->uHostBusType = 'A'; - break; - case CHIP_BUSLOGIC_MCA: - bl_setup->uHostBusType = 'B'; - break; - case CHIP_BUSLOGIC_VLB: - bl_setup->uHostBusType = 'E'; - break; - case CHIP_BUSLOGIC_PCI: - bl_setup->uHostBusType = 'F'; - break; - } -} - - -static uint8_t -buslogic_is_aggressive_mode(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - return bl->fAggressiveRoundRobinMode; -} - - -static uint8_t -buslogic_interrupt_type(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_MCA)) - return 0; - else - return !!bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; -} - - -static void -buslogic_reset(void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - bl->ExtendedLUNCCBFormat = 0; -} - - -uint8_t buslogic_pci_regs[256]; -bar_t buslogic_pci_bar[3]; - - -static void -BuslogicBIOSUpdate(buslogic_data_t *bl) -{ - int bios_enabled = buslogic_pci_bar[2].addr_regs[0] & 0x01; - - if (!bl->has_bios) { - return; - } - - /* PCI BIOS stuff, just enable_disable. */ - if ((bl->bios_addr > 0) && bios_enabled) { - mem_mapping_enable(&bl->bios.mapping); - mem_mapping_set_addr(&bl->bios.mapping, - bl->bios_addr, bl->bios_size); - buslogic_log("BT-958D: BIOS now at: %06X\n", bl->bios_addr); - } else { - buslogic_log("BT-958D: BIOS disabled\n"); - mem_mapping_disable(&bl->bios.mapping); - } -} - -static uint8_t -BuslogicPCIRead(int func, int addr, void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - buslogic_log("BT-958D: Reading register %02X\n", addr & 0xff); - - switch (addr) { - case 0x00: - return 0x4b; - case 0x01: - return 0x10; - case 0x02: - return 0x40; - case 0x03: - return 0x10; - case 0x04: - return buslogic_pci_regs[0x04] & 0x03; /*Respond to IO and memory accesses*/ - case 0x05: - return 0; - case 0x07: - return 2; - case 0x08: - return 1; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*Subclass*/ - case 0x0B: - return 1; /*Class code*/ - case 0x0E: - return 0; /*Header type */ - case 0x10: - return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ - case 0x11: - return buslogic_pci_bar[0].addr_regs[1]; - case 0x12: - return buslogic_pci_bar[0].addr_regs[2]; - case 0x13: - return buslogic_pci_bar[0].addr_regs[3]; - case 0x14: - return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ - case 0x15: - return buslogic_pci_bar[1].addr_regs[1]; - case 0x16: - return buslogic_pci_bar[1].addr_regs[2]; - case 0x17: - return buslogic_pci_bar[1].addr_regs[3]; - case 0x2C: - return 0x4b; - case 0x2D: - return 0x10; - case 0x2E: - return 0x40; - case 0x2F: - return 0x10; - case 0x30: /* PCI_ROMBAR */ - buslogic_log("BT-958D: BIOS BAR 00 = %02X\n", buslogic_pci_bar[2].addr_regs[0] & 0x01); - return buslogic_pci_bar[2].addr_regs[0] & 0x01; - case 0x31: /* PCI_ROMBAR 15:11 */ - buslogic_log("BT-958D: BIOS BAR 01 = %02X\n", (buslogic_pci_bar[2].addr_regs[1] & bl->bios_mask)); - return buslogic_pci_bar[2].addr_regs[1]; - break; - case 0x32: /* PCI_ROMBAR 23:16 */ - buslogic_log("BT-958D: BIOS BAR 02 = %02X\n", buslogic_pci_bar[2].addr_regs[2]); - return buslogic_pci_bar[2].addr_regs[2]; - break; - case 0x33: /* PCI_ROMBAR 31:24 */ - buslogic_log("BT-958D: BIOS BAR 03 = %02X\n", buslogic_pci_bar[2].addr_regs[3]); - return buslogic_pci_bar[2].addr_regs[3]; - break; - case 0x3C: - return dev->Irq; - case 0x3D: - return PCI_INTA; - } - - return(0); -} - - -static void -BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) -{ - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - uint8_t valxor; - - buslogic_log("BT-958D: Write value %02X to register %02X\n", val, addr & 0xff); - - switch (addr) { - case 0x04: - valxor = (val & 0x27) ^ buslogic_pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) { - x54x_io_remove(dev, bl->PCIBase, 32); - if ((bl->PCIBase != 0) && (val & PCI_COMMAND_IO)) { - x54x_io_set(dev, bl->PCIBase, 32); - } - } - if (valxor & PCI_COMMAND_MEM) { - x54x_mem_disable(dev); - if ((bl->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) { - x54x_mem_set_addr(dev, bl->MMIOBase); - } - } - buslogic_pci_regs[addr] = val & 0x27; - break; - - case 0x10: - val &= 0xe0; - val |= 1; - - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - x54x_io_remove(dev, bl->PCIBase, 32); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - bl->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; - /* Log the new base. */ - buslogic_log("BusLogic PCI: New I/O base is %04X\n" , bl->PCIBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_IO) { - if (bl->PCIBase != 0) { - x54x_io_set(dev, bl->PCIBase, 32); - } - } - return; - - case 0x14: - val &= 0xe0; - - case 0x15: case 0x16: case 0x17: - /* MMIO Base set. */ - /* First, remove the old I/O. */ - x54x_mem_disable(dev); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; - /* Log the new base. */ - buslogic_log("BusLogic PCI: New MMIO base is %04X\n" , bl->MMIOBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) { - if (bl->MMIOBase != 0) { - x54x_mem_set_addr(dev, bl->MMIOBase); - } - } - return; - - case 0x30: /* PCI_ROMBAR */ - case 0x31: /* PCI_ROMBAR */ - case 0x32: /* PCI_ROMBAR */ - case 0x33: /* PCI_ROMBAR */ - buslogic_pci_bar[2].addr_regs[addr & 3] = val; - buslogic_pci_bar[2].addr &= 0xffffc001; - bl->bios_addr = buslogic_pci_bar[2].addr & 0xffffc000; - buslogic_log("BT-958D: BIOS BAR %02X = NOW %02X (%02X)\n", addr & 3, buslogic_pci_bar[2].addr_regs[addr & 3], val); - BuslogicBIOSUpdate(bl); - return; - - case 0x3C: - buslogic_pci_regs[addr] = val; - if (val != 0xFF) { - buslogic_log("BusLogic IRQ now: %i\n", val); - dev->Irq = val; - } else - dev->Irq = 0; - return; - } -} - - -static void -BuslogicInitializeLocalRAM(buslogic_data_t *bl) -{ - memset(bl->LocalRAM.u8View, 0, sizeof(HALocalRAM)); - if (bl->chip == CHIP_BUSLOGIC_PCI) { - bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; - } else { - bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 0; - } - - bl->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16SynchronousPermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.fRoundRobinScheme = 0; - bl->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = ~0; -} - - -static uint8_t -buslogic_mca_read(int port, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - return(dev->pos_regs[port & 7]); -} - - -static void -buslogic_mca_write(int port, uint8_t val, void *priv) -{ - x54x_t *dev = (x54x_t *) priv; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - HALocalRAM *HALR = &bl->LocalRAM; - - /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; - - /* Save the MCA register value. */ - dev->pos_regs[port & 7] = val; - - /* This is always necessary so that the old handler doesn't remain. */ - x54x_io_remove(dev, dev->Base, 4); - - /* Get the new assigned I/O base address. */ - if (dev->pos_regs[3]) { - dev->Base = dev->pos_regs[3] << 8; - dev->Base |= ((dev->pos_regs[2] & 0x10) ? 0x34 : 0x30); - } else { - dev->Base = 0x0000; - } - - /* Save the new IRQ and DMA channel values. */ - dev->Irq = ((dev->pos_regs[2] >> 1) & 0x07) + 8; - dev->DmaChannel = dev->pos_regs[5] & 0x0f; - - /* Extract the BIOS ROM address info. */ - if (dev->pos_regs[2] & 0xe0) switch(dev->pos_regs[2] & 0xe0) { - case 0xe0: /* [0]=111x xxxx */ - bl->bios_addr = 0xDC000; - break; - - case 0x00: /* [0]=000x xxxx */ - bl->bios_addr = 0; - break; - - case 0xc0: /* [0]=110x xxxx */ - bl->bios_addr = 0xD8000; - break; - - case 0xa0: /* [0]=101x xxxx */ - bl->bios_addr = 0xD4000; - break; - - case 0x80: /* [0]=100x xxxx */ - bl->bios_addr = 0xD0000; - break; - - case 0x60: /* [0]=011x xxxx */ - bl->bios_addr = 0xCC000; - break; - - case 0x40: /* [0]=010x xxxx */ - bl->bios_addr = 0xC8000; - break; - - case 0x20: /* [0]=001x xxxx */ - bl->bios_addr = 0xC4000; - break; - } else { - /* Disabled. */ - bl->bios_addr = 0x000000; - } - - /* - * Get misc SCSI config stuff. For now, we are only - * interested in the configured HA target ID: - * - * pos[2]=111xxxxx = 7 - * pos[2]=000xxxxx = 0 - */ - dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; - - /* - * SYNC mode is pos[2]=xxxxxx1x. - * - * SCSI Parity is pos[2]=xxx1xxxx. - * - * DOS Disk Space > 1GBytes is pos[2] = xxxx1xxx. - */ - /* Parity. */ - HALR->structured.autoSCSIData.uSCSIConfiguration &= ~2; - HALR->structured.autoSCSIData.uSCSIConfiguration |= (dev->pos_regs[4] & 2); - - /* Sync. */ - HALR->structured.autoSCSIData.u16SynchronousPermittedMask = (dev->pos_regs[4] & 0x10) ? 0xffff : 0x0000; - - /* DOS Disk Space > 1GBytes */ - HALR->structured.autoSCSIData.uBIOSConfiguration &= ~4; - HALR->structured.autoSCSIData.uBIOSConfiguration |= (dev->pos_regs[4] & 8) ? 4 : 0; - - /* - * The PS/2 Model 80 BIOS always enables a card if it finds one, - * even if no resources were assigned yet (because we only added - * the card, but have not run AutoConfig yet...) - * - * So, remove current address, if any. - */ - mem_mapping_disable(&dev->bios.mapping); - - /* Initialize the device if fully configured. */ - if (dev->pos_regs[2] & 0x01) { - /* Card enabled; register (new) I/O handler. */ - x54x_io_set(dev, dev->Base, 4); - - /* Reset the device. */ - x54x_reset_ctrl(dev, CTRL_HRST); - - /* Enable or disable the BIOS ROM. */ - if (bl->has_bios && (bl->bios_addr != 0x000000)) { - mem_mapping_enable(&bl->bios.mapping); - mem_mapping_set_addr(&bl->bios.mapping, bl->bios_addr, ROM_SIZE); - } - - /* Say hello. */ - pclog("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", - dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID); - } -} - - -void -BuslogicDeviceReset(void *p) -{ - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - - x54x_device_reset(dev); - - BuslogicInitializeLocalRAM(bl); - BuslogicInitializeAutoSCSIRam(dev); -} - - -static void * -buslogic_init(const device_t *info) -{ - x54x_t *dev; - wchar_t *bios_rom_name; - uint16_t bios_rom_size; - uint16_t bios_rom_mask; - uint8_t has_autoscsi_rom; - wchar_t *autoscsi_rom_name; - uint16_t autoscsi_rom_size; - uint8_t has_scam_rom; - wchar_t *scam_rom_name; - uint16_t scam_rom_size; - FILE *f; - buslogic_data_t *bl; - uint32_t bios_rom_addr; - - /* Call common initializer. */ - dev = x54x_init(info); - - dev->ven_data = malloc(sizeof(buslogic_data_t)); - memset(dev->ven_data, 0x00, sizeof(buslogic_data_t)); - - bl = (buslogic_data_t *) dev->ven_data; - - dev->bus = info->flags; - if (!(info->flags & DEVICE_MCA) && !(info->flags & DEVICE_PCI)) { - dev->Base = device_get_config_hex16("base"); - dev->Irq = device_get_config_int("irq"); - dev->DmaChannel = device_get_config_int("dma"); - } - else if (info->flags & DEVICE_PCI) { - dev->Base = 0; - } - dev->HostID = 7; /* default HA ID */ - dev->setup_info_len = sizeof(buslogic_setup_t); - dev->max_id = 7; - dev->int_geom_writable = 1; - dev->cdrom_boot = 0; - dev->bit32 = 0; - dev->lba_bios = 0; - - bl->chip = info->local; - bl->PCIBase = 0; - bl->MMIOBase = 0; - if (info->flags & DEVICE_PCI) { - bios_rom_addr = 0xd8000; - bl->has_bios = device_get_config_int("bios"); - } else if (info->flags & DEVICE_MCA) { - bios_rom_addr = 0xd8000; - bl->has_bios = 1; - } else { - bios_rom_addr = device_get_config_hex20("bios_addr"); - bl->has_bios = !!bios_rom_addr; - } - - dev->ven_cmd_phase1 = buslogic_cmd_phase1; - dev->ven_get_host_id = buslogic_get_host_id; - dev->ven_get_irq = buslogic_get_irq; - dev->ven_get_dma = buslogic_get_dma; - dev->get_ven_param_len = buslogic_param_len; - dev->ven_cmds = buslogic_cmds; - dev->interrupt_type = buslogic_interrupt_type; - dev->is_aggressive_mode = buslogic_is_aggressive_mode; - dev->get_ven_data = buslogic_setup_data; - dev->ven_reset = buslogic_reset; - - strcpy(dev->vendor, "BusLogic"); - - bl->fAggressiveRoundRobinMode = 1; - - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542: - strcpy(dev->name, "BT-542BH"); - bios_rom_name = L"roms/scsi/buslogic/BT-542BH_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA335"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; - case CHIP_BUSLOGIC_ISA: - default: - strcpy(dev->name, "BT-545S"); - bios_rom_name = L"roms/scsi/buslogic/BT-545S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = L"roms/scsi/buslogic/BT-545S_AutoSCSI.rom"; - autoscsi_rom_size = 0x4000; - has_scam_rom = 0; - dev->fw_rev = "AA421E"; - dev->ha_bps = 10000000.0; /* fast SCSI */ - break; - case CHIP_BUSLOGIC_MCA: - strcpy(dev->name, "BT-640A"); - bios_rom_name = L"roms/scsi/buslogic/BT-640A_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "BA150"; - dev->bit32 = 1; - dev->pos_regs[0] = 0x08; /* MCA board ID */ - dev->pos_regs[1] = 0x07; - mca_add(buslogic_mca_read, buslogic_mca_write, dev); - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; - case CHIP_BUSLOGIC_VLB: - strcpy(dev->name, "BT-445S"); - bios_rom_name = L"roms/scsi/buslogic/BT-445S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = L"roms/scsi/buslogic/BT-445S_AutoSCSI.rom"; - autoscsi_rom_size = 0x4000; - has_scam_rom = 0; - dev->fw_rev = "AA421E"; - dev->bit32 = 1; - dev->ha_bps = 10000000.0; /* fast SCSI */ - break; - case CHIP_BUSLOGIC_PCI: - strcpy(dev->name, "BT-958D"); - bios_rom_name = L"roms/scsi/buslogic/BT-958D_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = L"roms/scsi/buslogic/BT-958D_AutoSCSI.rom"; - autoscsi_rom_size = 0x8000; - has_scam_rom = 1; - scam_rom_name = L"roms/scsi/buslogic/BT-958D_SCAM.rom"; - scam_rom_size = 0x0200; - dev->fw_rev = "AA507B"; - dev->cdrom_boot = 1; - dev->bit32 = 1; - dev->ha_bps = 20000000.0; /* ultra SCSI */ - dev->max_id = 15; /* wide SCSI */ - break; - } - - if ((dev->Base != 0) && !(dev->bus & DEVICE_MCA) && !(dev->bus & DEVICE_PCI)) { - x54x_io_set(dev, dev->Base, 4); - } - - memset(bl->AutoSCSIROM, 0xff, 32768); - - memset(bl->SCAMData, 0x00, 65536); - - if (bl->has_bios) - { - bl->bios_size = bios_rom_size; - - bl->bios_mask = 0xffffc000; - - rom_init(&bl->bios, bios_rom_name, bios_rom_addr, bios_rom_size, bios_rom_mask, 0, MEM_MAPPING_EXTERNAL); - - if (has_autoscsi_rom) { - f = rom_fopen(autoscsi_rom_name, L"rb"); - if (f) { - fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f); - fclose(f); - f = NULL; - } - } - - if (has_scam_rom) { - f = rom_fopen(scam_rom_name, L"rb"); - if (f) { - fread(bl->SCAMData, 1, scam_rom_size, f); - fclose(f); - f = NULL; - } - } - } - else { - bl->bios_size = 0; - - bl->bios_mask = 0; - } - - if (bl->chip == CHIP_BUSLOGIC_PCI) { - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); - - buslogic_pci_bar[0].addr_regs[0] = 1; - buslogic_pci_bar[1].addr_regs[0] = 0; - buslogic_pci_regs[0x04] = 3; - - /* Enable our BIOS space in PCI, if needed. */ - if (bl->has_bios) { - buslogic_pci_bar[2].addr = 0xFFFFC000; - } else { - buslogic_pci_bar[2].addr = 0; - } - - x54x_mem_init(dev, 0xfffd0000); - x54x_mem_disable(dev); - } - - if ((bl->chip == CHIP_BUSLOGIC_MCA) || (bl->chip == CHIP_BUSLOGIC_PCI)) - mem_mapping_disable(&bl->bios.mapping); - - buslogic_log("Buslogic on port 0x%04X\n", dev->Base); - - x54x_device_reset(dev); - - if ((bl->chip != CHIP_BUSLOGIC_ISA_542) && (bl->chip != CHIP_BUSLOGIC_MCA)) { - BuslogicInitializeLocalRAM(bl); - BuslogicInitializeAutoSCSIRam(dev); - } - - return(dev); -} - - -static const device_config_t BT_ISA_Config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x334, - { - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "", 0 - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "", 0 - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "", 0 - } - }, - }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "", 0 - } - }, - }, - { - "", "", -1 - } -}; - - -static const device_config_t BT958D_Config[] = { - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } -}; - - -const device_t buslogic_device = { - "Buslogic BT-542BH ISA", - DEVICE_ISA | DEVICE_AT, - CHIP_BUSLOGIC_ISA_542, - buslogic_init, x54x_close, NULL, - NULL, NULL, NULL, - BT_ISA_Config -}; - -const device_t buslogic_545s_device = { - "Buslogic BT-545S ISA", - DEVICE_ISA | DEVICE_AT, - CHIP_BUSLOGIC_ISA, - buslogic_init, x54x_close, NULL, - NULL, NULL, NULL, - BT_ISA_Config -}; - -const device_t buslogic_640a_device = { - "Buslogic BT-640A MCA", - DEVICE_MCA, - CHIP_BUSLOGIC_MCA, - buslogic_init, x54x_close, NULL, - NULL, NULL, NULL, - NULL -}; - -const device_t buslogic_445s_device = { - "Buslogic BT-445S VLB", - DEVICE_VLB, - CHIP_BUSLOGIC_VLB, - buslogic_init, x54x_close, NULL, - NULL, NULL, NULL, - BT_ISA_Config -}; - -const device_t buslogic_pci_device = { - "Buslogic BT-958D PCI", - DEVICE_PCI, - CHIP_BUSLOGIC_PCI, - buslogic_init, x54x_close, NULL, - NULL, NULL, NULL, - BT958D_Config -}; diff --git a/src - Cópia/scsi/scsi_buslogic.h b/src - Cópia/scsi/scsi_buslogic.h deleted file mode 100644 index 83ce417d9..000000000 --- a/src - Cópia/scsi/scsi_buslogic.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI - * controllers. - * - * Version: @(#)scsi_buslogic.h 1.0.3 2018/03/18 - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ - -#ifndef SCSI_BUSLOGIC_H -# define SCSI_BUSLOGIC_H - - -extern const device_t buslogic_device; -extern const device_t buslogic_545s_device; -extern const device_t buslogic_640a_device; -extern const device_t buslogic_445s_device; -extern const device_t buslogic_pci_device; - -extern void BuslogicDeviceReset(void *p); - - -#endif /*SCSI_BUSLOGIC_H*/ diff --git a/src - Cópia/scsi/scsi_device.c b/src - Cópia/scsi/scsi_device.c deleted file mode 100644 index 1a8d275e1..000000000 --- a/src - Cópia/scsi/scsi_device.c +++ /dev/null @@ -1,403 +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. - * - * The generic SCSI device command handler. - * - * Version: @(#)scsi_device.c 1.0.17 2018/06/02 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../disk/hdd.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "scsi_disk.h" - - -static uint8_t scsi_null_device_sense[14] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0 }; - - -static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) -{ - if (lun_type == SCSI_DISK) - { - scsi_disk_command(scsi_disk[id], cdb); - return scsi_disk_err_stat_to_scsi(scsi_disk[id]); - } - else if (lun_type == SCSI_CDROM) - { - cdrom_command(cdrom[id], cdb); - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_command(zip[id], cdb); - return zip_ZIP_PHASE_to_scsi(zip[id]); - } - else - { - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_phase_callback(int lun_type, uint8_t id) -{ - if (lun_type == SCSI_DISK) - { - scsi_disk_callback(scsi_disk[id]); - } - else if (lun_type == SCSI_CDROM) - { - cdrom_phase_callback(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_phase_callback(zip[id]); - } - else - { - return; - } -} - - -static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id) -{ - if (lun_type == SCSI_DISK) - { - return scsi_disk_err_stat_to_scsi(scsi_disk[id]); - } - else if (lun_type == SCSI_CDROM) - { - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - return zip_ZIP_PHASE_to_scsi(zip[id]); - } - else - { - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte) -{ - if (lun_type == SCSI_DISK) - { - scsi_disk[id]->request_length = cdb_byte; - } - else if (lun_type == SCSI_CDROM) - { - cdrom[id]->request_length = cdb_byte; - } - else if (lun_type == SCSI_ZIP) - { - zip[id]->request_length = cdb_byte; - } - else - { - return; - } -} - - -int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk[id]->callback; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->callback; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->callback; - break; - default: - return -1LL; - break; - } -} - - -uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk[id]->sense; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->sense; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->sense; - break; - default: - return scsi_null_device_sense; - break; - } -} - - -void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_request_sense_for_scsi(zip[id], buffer, alloc_length); - break; - default: - memcpy(buffer, scsi_null_device_sense, alloc_length); - break; - } -} - - -void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - scsi_disk_reset(scsi_disk[id]); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_reset(cdrom[id]); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_reset(zip[id]); - break; - } -} - - -void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_DISK: - *type = *rmb = 0x00; - break; - case SCSI_CDROM: - *type = 0x05; - *rmb = 0x80; - break; - case SCSI_ZIP: - *type = 0x00; - *rmb = 0x80; - break; - default: - *type = *rmb = 0xff; - break; - } -} - - -int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len); - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom_read_capacity(cdrom[id], cdb, buffer, len); - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip_read_capacity(zip[id], cdb, buffer, len); - default: - return 0; - } -} - - -int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_NONE: - return 0; - default: - return 1; - } -} - - -int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - break; - } - - return (id == 0xFF) ? 0 : 1; -} - - -int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) -{ - /* Right now, it's 12 for all devices. */ - return 12; -} - - -void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS; - SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION; - return; - } - - /* - * Since that field in the target struct is never used when - * the bus type is SCSI, let's use it for this scope. - */ - scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]); - - if (cdb_len != 12) { - /* - * Make sure the LUN field of the temporary CDB is always 0, - * otherwise Daemon Tools drives will misbehave when a command - * is passed through to them. - */ - cdb[1] &= 0x1f; - } - - /* Finally, execute the SCSI command immediately and get the transfer length. */ - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND; - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb); - - if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) { - /* Command completed (either OK or error) - call the phase callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); - } - /* If the phase is DATA IN or DATA OUT, finish this here. */ -} - -void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - return; - } - - /* Call the second phase. */ - scsi_device_target_phase_callback(lun_type, id); - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); - /* Command second phase complete - call the callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); -} - -int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun) -{ - return &SCSIDevices[scsi_id][scsi_lun].BufferLength; -} diff --git a/src - Cópia/scsi/scsi_device.h b/src - Cópia/scsi/scsi_device.h deleted file mode 100644 index 23d6cbc02..000000000 --- a/src - Cópia/scsi/scsi_device.h +++ /dev/null @@ -1,60 +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. - * - * Definitions for the generic SCSI device command handler. - * - * Version: @(#)scsi_device.h 1.0.7 2018/03/29 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - */ -#ifndef SCSI_DEVICE_H -# define SCSI_DEVICE_H - -typedef struct -{ - int state; - int new_state; - int clear_req; - uint32_t bus_in, bus_out; - int dev_id; - - int command_pos; - uint8_t command[20]; - int data_pos; - - int change_state_delay; - int new_req_delay; -} scsi_bus_t; - -extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun); -extern void scsi_device_type_data(uint8_t id, uint8_t lun, - uint8_t *type, uint8_t *rmb); -extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun); -extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, - uint8_t *buffer, - uint8_t alloc_length); -extern void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun); -extern int scsi_device_read_capacity(uint8_t id, uint8_t lun, - uint8_t *cdb, uint8_t *buffer, - uint32_t *len); -extern int scsi_device_present(uint8_t id, uint8_t lun); -extern int scsi_device_valid(uint8_t id, uint8_t lun); -extern int scsi_device_cdb_length(uint8_t id, uint8_t lun); -extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len, - uint8_t *cdb); -extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, - int cdb_len, uint8_t *cdb); -extern void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun); -extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun); - -extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert); -extern int scsi_bus_read(scsi_bus_t *bus); -extern int scsi_bus_match(scsi_bus_t *bus, int bus_assert); - -#endif /*SCSI_DEVICE_H*/ diff --git a/src - Cópia/scsi/scsi_disk.c b/src - Cópia/scsi/scsi_disk.c deleted file mode 100644 index 95243657a..000000000 --- a/src - Cópia/scsi/scsi_disk.c +++ /dev/null @@ -1,1331 +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. - * - * Emulation of SCSI fixed disks. - * - * Version: @(#)scsi_disk.c 1.0.20 2018/05/28 - * - * Author: Miran Grca, - * - * Copyright 2017,2018 Miran Grca. - */ -#include -#include -#include -#include -#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 "../disk/hdc_ide.h" -#include "../plat.h" -#include "../ui.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "scsi_disk.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define MAX_BLOCKS_AT_ONCE 340 - -#define scsi_disk_sense_error dev->sense[0] -#define scsi_disk_sense_key dev->sense[2] -#define scsi_disk_asc dev->sense[12] -#define scsi_disk_ascq dev->sense[13] - - -scsi_disk_t *scsi_disk[HDD_NUM]; - -uint8_t scsi_disks[16][8] = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } -}; - - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t scsi_disk_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - 0, 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -uint64_t scsi_disk_mode_sense_page_flags = (1LL << 0x03) | (1LL << 0x04) | (1LL << 0x30) | (1LL << 0x3F); - -/* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */ -static const mode_sense_pages_t scsi_disk_mode_sense_pages_default = -{ { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, - [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -} }; - -static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = -{ { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, - [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -} }; - - -#ifdef ENABLE_SCSI_DISK_LOG -int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; -#endif - - -static void -scsi_disk_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_DISK_LOG - va_list ap; - - if (scsi_disk_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -scsi_disk_err_stat_to_scsi(scsi_disk_t *dev) -{ - if (dev->status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -int -find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t i = 0; - - for (i = 0; i < HDD_NUM; i++) { - if (wcslen(hdd[i].fn) == 0) - continue; - if ((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0)) - continue; - if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id) && (hdd[i].scsi_lun == scsi_lun)) - return i; - } - return 0xff; -} - - -void -scsi_loadhd(int scsi_id, int scsi_lun, int id) -{ - if (! hdd_image_load(id)) - scsi_disks[scsi_id][scsi_lun] = 0xff; -} - - -void -build_scsi_disk_map(void) -{ - uint8_t i = 0, j = 0; - - for (i = 0; i < 16; i++) - memset(scsi_disks[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - scsi_disks[i][j] = find_hdd_for_scsi_id(i, j); - if (scsi_disks[i][j] != 0xff) { - if (wcslen(hdd[scsi_disks[i][j]].fn) > 0) - scsi_loadhd(i, j, scsi_disks[i][j]); - } - } - } -} - - -void -scsi_disk_mode_sense_load(scsi_disk_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - int i; - memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - for (i = 0; i < 0x3f; i++) { - if (scsi_disk_mode_sense_pages_default.pages[i][1] != 0) { - memcpy(dev->ms_pages_saved.pages[i], scsi_disk_mode_sense_pages_default.pages[i], - scsi_disk_mode_sense_pages_default.pages[i][1] + 2); - } - } - swprintf(file_name, 512, L"scsi_disk_%02i_mode_sense.bin", dev->id); - memset(file_name, 0, 512 * sizeof(wchar_t)); - f = plat_fopen(nvr_path(file_name), L"rb"); - if (f) { - fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); - fclose(f); - } -} - - -void -scsi_disk_mode_sense_save(scsi_disk_t *dev) -{ - FILE *f; - wchar_t file_name[512]; - memset(file_name, 0, 512 * sizeof(wchar_t)); - swprintf(file_name, 512, L"scsi_disk_%02i_mode_sense.bin", dev->id); - f = plat_fopen(nvr_path(file_name), L"wb"); - if (f) { - fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); - fclose(f); - } -} - - -int -scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - int size = 0; - - size = hdd_image_get_last_sector(dev->id); - memset(buffer, 0, 8); - buffer[0] = (size >> 24) & 0xff; - buffer[1] = (size >> 16) & 0xff; - buffer[2] = (size >> 8) & 0xff; - buffer[3] = size & 0xff; - buffer[6] = 2; /* 512 = 0x0200 */ - *len = 8; - - return 1; -} - - -/*SCSI Mode Sense 6/10*/ -uint8_t -scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) -{ - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - return scsi_disk_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - return scsi_disk_mode_sense_pages_default.pages[page][pos]; - break; - } - - return 0; -} - - -uint32_t -scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) -{ - uint8_t msplen, page_control = (type >> 6) & 3; - - int i = 0, j = 0; - int size = 0; - - type &= 0x3f; - - size = hdd_image_get_last_sector(dev->id); - - if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = (size >> 16) & 0xff; /* Number of blocks (0 = all). */ - buf[pos++] = (size >> 8) & 0xff; - buf[pos++] = size & 0xff; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; - } - - for (i = 0; i < 0x40; i++) { - if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (scsi_disk_mode_sense_page_flags & (1LL << dev->current_page_code)) { - buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 0); - msplen = scsi_disk_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - scsi_disk_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 2 + j); - } - } - } - - return pos; -} - - -static void -scsi_disk_command_common(scsi_disk_t *dev) -{ - dev->status = BUSY_STAT; - dev->phase = 1; - if (dev->packet_status == CDROM_PHASE_COMPLETE) { - scsi_disk_callback(dev); - dev->callback = 0LL; - } else - dev->callback = -1LL; /* Speed depends on SCSI controller */ -} - - -static void -scsi_disk_command_complete(scsi_disk_t *dev) -{ - dev->packet_status = CDROM_PHASE_COMPLETE; - scsi_disk_command_common(dev); -} - - -static void -scsi_disk_command_read_dma(scsi_disk_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_IN_DMA; - scsi_disk_command_common(dev); -} - - -static void -scsi_disk_command_write_dma(scsi_disk_t *dev) -{ - dev->packet_status = CDROM_PHASE_DATA_OUT_DMA; - scsi_disk_command_common(dev); -} - - -static void -scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int alloc_len, int direction) -{ - scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, - dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if (len == 0) - scsi_disk_command_complete(dev); - else { - if (direction == 0) - scsi_disk_command_read_dma(dev); - else - scsi_disk_command_write_dma(dev); - } -} - - -static void -scsi_disk_sense_clear(scsi_disk_t *dev, int command) -{ - scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; -} - - -static void -scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase) -{ - uint8_t scsi_id = dev->drv->scsi_id; - uint8_t scsi_lun = dev->drv->scsi_lun; - - if (dev->drv->bus != HDD_BUS_SCSI) - return; - - SCSIDevices[scsi_id][scsi_lun].Phase = phase; -} - - -static void -scsi_disk_cmd_error(scsi_disk_t *dev) -{ - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->packet_status = 0x80; - dev->callback = 50 * SCSI_TIME; - scsi_disk_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); -} - - -static void -scsi_disk_invalid_lun(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_LUN; - scsi_disk_ascq = 0; - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_cmd_error(dev); -} - - -static void -scsi_disk_illegal_opcode(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_ILLEGAL_OPCODE; - scsi_disk_ascq = 0; - scsi_disk_cmd_error(dev); -} - - -static void -scsi_disk_lba_out_of_range(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_LBA_OUT_OF_RANGE; - scsi_disk_ascq = 0; - scsi_disk_cmd_error(dev); -} - - -static void -scsi_disk_invalid_field(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_disk_ascq = 0; - scsi_disk_cmd_error(dev); - dev->status = 0x53; -} - - -static void -scsi_disk_invalid_field_pl(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - scsi_disk_ascq = 0; - scsi_disk_cmd_error(dev); - dev->status = 0x53; -} - - -static void -scsi_disk_data_phase_error(scsi_disk_t *dev) -{ - scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_DATA_PHASE_ERROR; - scsi_disk_ascq = 0; - scsi_disk_cmd_error(dev); -} - - -static int -scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) -{ - if (((dev->request_length >> 5) & 7) != dev->drv->scsi_lun) { - scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); - scsi_disk_invalid_lun(dev); - return 0; - } - - if (!(scsi_disk_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X\n", dev->id, cdb[0]); - scsi_disk_illegal_opcode(dev); - return 0; - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_disk_sense_clear(dev, cdb[0]); - - scsi_disk_log("SCSI HD %i: Continuing with command\n", dev->id); - - return 1; -} - - -static void -scsi_disk_seek(scsi_disk_t *dev, uint32_t pos) -{ - /* scsi_disk_log("SCSI HD %i: Seek %08X\n", dev->id, pos); */ - hdd_image_seek(dev->id, pos); -} - - -static void -scsi_disk_rezero(scsi_disk_t *dev) -{ - if (dev->id == 0xff) - return; - - dev->sector_pos = dev->sector_len = 0; - scsi_disk_seek(dev, 0); -} - - -void -scsi_disk_reset(scsi_disk_t *dev) -{ - scsi_disk_rezero(dev); - dev->status = 0; - dev->callback = 0; - dev->packet_status = 0xff; -} - - -void -scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) -{ - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = scsi_disk_sense_key; - buffer[2] = scsi_disk_asc; - buffer[3] = scsi_disk_ascq; - } - } else - return; - - buffer[0] = 0x70; - - scsi_disk_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); - - /* Clear the sense stuff as per the spec. */ - scsi_disk_sense_clear(dev, GPCMD_REQUEST_SENSE); -} - - -void -scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length) -{ - scsi_disk_request_sense(dev, buffer, alloc_length, 0); -} - - -void -scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb) -{ - uint8_t *hdbufferb; - int32_t *BufLen; - uint32_t len; - int max_len, pos = 0; - unsigned idx = 0; - unsigned size_idx, preamble_len; - uint32_t alloc_length, last_sector = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int block_desc = 0; - - hdbufferb = SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].CmdBuffer; - BufLen = &SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].BufferLength; - - last_sector = hdd_image_get_last_sector(dev->id); - - dev->status &= ~ERR_STAT; - dev->packet_len = 0; - - device_identify[6] = (dev->id / 10) + 0x30; - device_identify[7] = (dev->id % 10) + 0x30; - - device_identify_ex[6] = (dev->id / 10) + 0x30; - device_identify_ex[7] = (dev->id % 10) + 0x30; - device_identify_ex[10] = EMU_VERSION[0]; - device_identify_ex[12] = EMU_VERSION[2]; - device_identify_ex[13] = EMU_VERSION[3]; - - memcpy(dev->current_cdb, cdb, 12); - - if (cdb[0] != 0) { - scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", - dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); - scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->request_length); - - scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); - } - - dev->sector_len = 0; - - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (scsi_disk_pre_execution_check(dev, cdb) == 0) - return; - - switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - scsi_disk_invalid_field(dev); - return; - } - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - case GPCMD_FORMAT_UNIT: - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; - - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - scsi_disk_seek(dev, 0); - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - if ((*BufLen == -1) || (cdb[4] < *BufLen)) - *BufLen = cdb[4]; - - if (*BufLen < cdb[4]) - cdb[4] = *BufLen; - - len = (cdb[1] & 1) ? 8 : 18; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((dev->sector_pos > last_sector) || ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { - scsi_disk_lba_out_of_range(dev); - return; - } - - if ((!dev->sector_len) || (*BufLen == 0)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->callback = 20 * SCSI_TIME; - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; - - alloc_length = dev->packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - switch(cdb[0]) - { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((dev->sector_pos > last_sector) || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { - scsi_disk_lba_out_of_range(dev); - return; - } - - if ((!dev->sector_len) || (*BufLen == 0)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->callback = 20 * SCSI_TIME; - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; - - alloc_length = dev->packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); - return; - - case GPCMD_WRITE_SAME_10: - if ((cdb[1] & 6) == 6) { - scsi_disk_invalid_field(dev); - return; - } - - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - - if ((dev->sector_pos > last_sector) || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { - scsi_disk_lba_out_of_range(dev); - return; - } - - if ((!dev->sector_len) || (*BufLen == 0)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->callback = 20 * SCSI_TIME; - break; - } - - max_len = 1; - dev->requested_blocks = max_len; - - alloc_length = dev->packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - - if (cdb[0] == GPCMD_MODE_SENSE_6) - len = cdb[4]; - else - len = (cdb[8] | (cdb[7] << 8)); - - dev->current_page_code = cdb[2] & 0x3F; - - alloc_length = len; - - dev->temp_buffer = (uint8_t *) malloc(65536); - memset(dev->temp_buffer, 0, 65536); - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - dev->temp_buffer[0] = len - 1; - dev->temp_buffer[1] = 0; - if (block_desc) - dev->temp_buffer[3] = 8; - } else { - len = scsi_disk_mode_sense(dev, dev->temp_buffer, 8, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - dev->temp_buffer[0]=(len - 2) >> 8; - dev->temp_buffer[1]=(len - 2) & 255; - dev->temp_buffer[2] = 0; - if (block_desc) { - dev->temp_buffer[6] = 0; - dev->temp_buffer[7] = 8; - } - } - - if (len > alloc_length) - len = alloc_length; - else if (len < alloc_length) - alloc_length = len; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_disk_log("SCSI HDD %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - scsi_disk_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) - len = cdb[4]; - else - len = (cdb[7] << 8) | cdb[8]; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - scsi_disk_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_INQUIRY: - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - if ((!max_len) || (*BufLen == 0)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - /* scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); */ - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->callback = 20 * SCSI_TIME; - break; - } - - dev->temp_buffer = malloc(1024); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - dev->temp_buffer[idx++] = 05; - dev->temp_buffer[idx++] = cdb[2]; - dev->temp_buffer[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - free(dev->temp_buffer); - dev->temp_buffer = NULL; - scsi_disk_data_phase_error(dev); - return; - } - - dev->temp_buffer[idx++] = 0x02; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 20; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - dev->temp_buffer[idx++] = 0x02; - dev->temp_buffer[idx++] = 0x01; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 68; - ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); /* Vendor */ - idx += 8; - ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); /* Product */ - idx += 40; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - scsi_disk_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - free(dev->temp_buffer); - dev->temp_buffer = NULL; - scsi_disk_invalid_field(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ - dev->temp_buffer[1] = 0; /*Fixed*/ - dev->temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - dev->temp_buffer[3] = 0x02; - dev->temp_buffer[4] = 31; - dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ - dev->temp_buffer[7] = 0x20; /* Wide bus supported */ - - ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->temp_buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION); /* Revision */ - idx = 36; - - if (max_len == 96) { - dev->temp_buffer[4] = 91; - idx = 96; - } - } - -atapi_out: - dev->temp_buffer[size_idx] = idx - preamble_len; - len=idx; - - scsi_disk_log("scsi_disk_command(): Inquiry (%08X, %08X)\n", hdbufferb, dev->temp_buffer); - - if (len > max_len) - len = max_len; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - if (len > *BufLen) - len = *BufLen; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - scsi_disk_seek(dev, pos); - - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; - - case GPCMD_READ_CDROM_CAPACITY: - dev->temp_buffer = (uint8_t *) malloc(8); - - if (scsi_disk_read_capacity(dev, dev->current_cdb, dev->temp_buffer, &len) == 0) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - return; - } - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, len, 0); - break; - - default: - scsi_disk_illegal_opcode(dev); - break; - } - - /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ -} - - -static void -scsi_disk_phase_data_in(scsi_disk_t *dev) -{ - uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].CmdBuffer; - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].BufferLength; - - if (!*BufLen) { - scsi_disk_log("scsi_disk_phase_data_in(): Buffer length is 0\n"); - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - - return; - } - - switch (dev->current_cdb[0]) { - case GPCMD_REQUEST_SENSE: - scsi_disk_log("SCSI HDD %i: %08X, %08X\n", dev->id, hdbufferb, *BufLen); - scsi_disk_request_sense(dev, hdbufferb, *BufLen, dev->current_cdb[1] & 1); - break; - case GPCMD_MECHANISM_STATUS: - memset(hdbufferb, 0, *BufLen); - hdbufferb[5] = 1; - break; - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > *BufLen) - hdd_image_read(dev->id, dev->sector_pos, *BufLen >> 9, hdbufferb); - else - hdd_image_read(dev->id, dev->sector_pos, dev->requested_blocks, hdbufferb); - } - break; - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - case GPCMD_INQUIRY: - case GPCMD_READ_CDROM_CAPACITY: - scsi_disk_log("scsi_disk_phase_data_in(): Filling buffer (%08X, %08X)\n", hdbufferb, dev->temp_buffer); - memcpy(hdbufferb, dev->temp_buffer, *BufLen); - free(dev->temp_buffer); - dev->temp_buffer = NULL; - scsi_disk_log("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7], - hdbufferb[8], hdbufferb[9], hdbufferb[10], hdbufferb[11], hdbufferb[12], hdbufferb[13], hdbufferb[14], hdbufferb[15]); - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); - break; - } - - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); -} - - -static void -scsi_disk_phase_data_out(scsi_disk_t *dev) -{ - uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].CmdBuffer; - int i; - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id][dev->drv->scsi_lun].BufferLength; - uint32_t last_sector = hdd_image_get_last_sector(dev->id); - uint32_t c, h, s, last_to_write = 0; - uint16_t block_desc_len, pos; - uint8_t hdr_len, val, old_val, ch, error = 0; - uint8_t page, page_len; - - if (!*BufLen) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - - return; - } - - switch (dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > *BufLen) - hdd_image_write(dev->id, dev->sector_pos, *BufLen >> 9, hdbufferb); - else - hdd_image_write(dev->id, dev->sector_pos, dev->requested_blocks, hdbufferb); - } - break; - case GPCMD_WRITE_SAME_10: - if (!dev->current_cdb[7] && !dev->current_cdb[8]) - last_to_write = last_sector; - else - last_to_write = dev->sector_pos + dev->sector_len - 1; - - for (i = dev->sector_pos; i <= last_to_write; i++) { - if (dev->current_cdb[1] & 2) { - hdbufferb[0] = (i >> 24) & 0xff; - hdbufferb[1] = (i >> 16) & 0xff; - hdbufferb[2] = (i >> 8) & 0xff; - hdbufferb[3] = i & 0xff; - } else if (dev->current_cdb[1] & 4) { - s = (i % dev->drv->spt); - h = ((i - s) / dev->drv->spt) % dev->drv->hpc; - c = ((i - s) / dev->drv->spt) / dev->drv->hpc; - hdbufferb[0] = (c >> 16) & 0xff; - hdbufferb[1] = (c >> 8) & 0xff; - hdbufferb[2] = c & 0xff; - hdbufferb[3] = h & 0xff; - hdbufferb[4] = (s >> 24) & 0xff; - hdbufferb[5] = (s >> 16) & 0xff; - hdbufferb[6] = (s >> 8) & 0xff; - hdbufferb[7] = s & 0xff; - } - hdd_image_write(dev->id, i, 1, hdbufferb); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) - hdr_len = 8; - else - hdr_len = 4; - - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = hdbufferb[2]; - block_desc_len <<= 8; - block_desc_len |= hdbufferb[3]; - } else { - block_desc_len = hdbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= hdbufferb[7]; - } - - pos = hdr_len + block_desc_len; - - while(1) { - page = hdbufferb[pos] & 0x3F; - page_len = hdbufferb[pos + 1]; - - pos += 2; - - if (!(scsi_disk_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; - val = hdbufferb[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; - } - } - } - - pos += page_len; - - val = scsi_disk_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - scsi_disk_mode_sense_save(dev); - - if (pos >= dev->total_length) - break; - } - - if (error) - scsi_disk_invalid_field_pl(dev); - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); - break; - } - - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); -} - - -/* If the result is 1, issue an IRQ, otherwise not. */ -void -scsi_disk_callback(scsi_disk_t *dev) -{ - switch(dev->packet_status) { - case CDROM_PHASE_IDLE: - scsi_disk_log("SCSI HD %i: PHASE_IDLE\n", dev->id); - dev->phase = 1; - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - return; - case CDROM_PHASE_COMPLETE: - scsi_disk_log("SCSI HD %i: PHASE_COMPLETE\n", dev->id); - dev->status = READY_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - return; - case CDROM_PHASE_DATA_OUT_DMA: - scsi_disk_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", dev->id); - scsi_disk_phase_data_out(dev); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->status = READY_STAT; - dev->phase = 3; - return; - case CDROM_PHASE_DATA_IN_DMA: - scsi_disk_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", dev->id); - scsi_disk_phase_data_in(dev); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->status = READY_STAT; - dev->phase = 3; - return; - case CDROM_PHASE_ERROR: - scsi_disk_log("SCSI HD %i: PHASE_ERROR\n", dev->id); - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - return; - } -} - - -/* Peform a master init on the entire module. */ -void -scsi_disk_global_init(void) -{ - /* Clear the global data. */ - memset(scsi_disk, 0x00, sizeof(scsi_disk)); -} - - -void -scsi_disk_hard_reset(void) -{ - int c; - - for (c = 0; c < HDD_NUM; c++) { - if (hdd[c].bus == HDD_BUS_SCSI) { - scsi_disk_log("SCSI disk hard_reset drive=%d\n", c); - - if (!scsi_disk[c]) { - scsi_disk[c] = (scsi_disk_t *) malloc(sizeof(scsi_disk_t)); - memset(scsi_disk[c], 0, sizeof(scsi_disk_t)); - } - - scsi_disk[c]->id = c; - scsi_disk[c]->drv = &hdd[c]; - - scsi_disk_mode_sense_load(scsi_disk[c]); - } - } -} - - -void -scsi_disk_close(void) -{ - scsi_disk_t *dev; - int c; - - for (c = 0; c < HDD_NUM; c++) { - dev = scsi_disk[c]; - - if (dev) { - hdd_image_close(c); - - free(scsi_disk[c]); - scsi_disk[c] = NULL; - } - } -} diff --git a/src - Cópia/scsi/scsi_disk.h b/src - Cópia/scsi/scsi_disk.h deleted file mode 100644 index dc9749469..000000000 --- a/src - Cópia/scsi/scsi_disk.h +++ /dev/null @@ -1,60 +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. - * - * Emulation of SCSI fixed and removable disks. - * - * Version: @(#)scsi_disk.h 1.0.5 2018/06/02 - * - * Author: Miran Grca, - * Copyright 2017,2018 Miran Grca. - */ - - -typedef struct { - mode_sense_pages_t ms_pages_saved; - - hard_disk_t *drv; - - /* Stuff for SCSI hard disks. */ - uint8_t status, phase, - error, id, - current_cdb[16], - sense[256]; - - uint16_t request_length; - - int requested_blocks, block_total, - packet_status, callback, - block_descriptor_len, - total_length, do_page_save; - - uint32_t sector_pos, sector_len, - packet_len; - - uint64_t current_page_code; - - uint8_t *temp_buffer; -} scsi_disk_t; - - -extern scsi_disk_t *scsi_disk[HDD_NUM]; -extern uint8_t scsi_disks[16][8]; - - -extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); -extern void scsi_disk_global_init(void); -extern void scsi_disk_hard_reset(void); -extern void scsi_disk_close(void); - -extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); -extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev); -extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev); -extern int find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern void build_scsi_disk_map(void); -extern void scsi_disk_reset(scsi_disk_t *dev); -extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length); -extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb); -extern void scsi_disk_callback(scsi_disk_t *dev); diff --git a/src - Cópia/scsi/scsi_ncr5380.c b/src - Cópia/scsi/scsi_ncr5380.c deleted file mode 100644 index 0a23c893e..000000000 --- a/src - Cópia/scsi/scsi_ncr5380.c +++ /dev/null @@ -1,1090 +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. - * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for the ISA bus. - * - * Version: @(#)scsi_ncr5380.c 1.0.14 2018/04/26 - * - * Authors: Sarah Walker, - * TheCollector1995, - * Fred N. van Kempen, - * - * Copyright 2017,2018 Sarah Walker. - * Copyright 2017,2018 TheCollector1995. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../timer.h" -#include "../plat.h" -#include "scsi.h" -#include "scsi_device.h" -#include "scsi_ncr5380.h" - - -#define LCS6821N_ROM L"roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" -#define RT1000B_ROM L"roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" -#define T130B_ROM L"roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define SCSIAT_ROM L"roms/scsi/ncr5380/sumo_scsiat_bios_v6.3.bin" - - -#define NCR_CURDATA 0 /* current SCSI data (read only) */ -#define NCR_OUTDATA 0 /* output data (write only) */ -#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ -#define NCR_MODE 2 /* mode (read/write) */ -#define NCR_TARGETCMD 3 /* target command (read/write) */ -#define NCR_SELENABLE 4 /* select enable (write only) */ -#define NCR_BUSSTATUS 4 /* bus status (read only) */ -#define NCR_STARTDMA 5 /* start DMA send (write only) */ -#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ -#define NCR_DMATARGET 6 /* DMA target (write only) */ -#define NCR_INPUTDATA 6 /* input data (read only) */ -#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ -#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ - -#define POLL_TIME_US 10LL -#define MAX_BYTES_TRANSFERRED_PER_POLL 50 -/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/ - - -#define ICR_DBP 0x01 -#define ICR_ATN 0x02 -#define ICR_SEL 0x04 -#define ICR_BSY 0x08 -#define ICR_ACK 0x10 -#define ICR_ARB_LOST 0x20 -#define ICR_ARB_IN_PROGRESS 0x40 - -#define MODE_ARBITRATE 0x01 -#define MODE_DMA 0x02 -#define MODE_MONITOR_BUSY 0x04 -#define MODE_ENA_EOP_INT 0x08 - -#define STATUS_ACK 0x01 -#define STATUS_BUSY_ERROR 0x04 -#define STATUS_INT 0x10 -#define STATUS_DRQ 0x40 -#define STATUS_END_OF_DMA 0x80 - -#define TCR_IO 0x01 -#define TCR_CD 0x02 -#define TCR_MSG 0x04 -#define TCR_REQ 0x08 -#define TCR_LAST_BYTE_SENT 0x80 - -#define CTRL_DATA_DIR (1<<6) -#define STATUS_BUFFER_NOT_READY (1<<2) -#define STATUS_53C80_ACCESSIBLE (1<<7) - - -typedef struct { - uint8_t icr; - uint8_t mode; - uint8_t tcr; - uint8_t ser; - uint8_t isr; - uint8_t output_data; - - int target_bsy; - int target_req; - uint8_t target_id; - - uint8_t bus_status; - - int dma_mode; - - scsi_bus_t bus; -} ncr5380_t; - -typedef struct { - const char *name; - uint32_t rom_addr; - uint16_t base; - int8_t irq; - int8_t type; - - rom_t bios_rom; - mem_mapping_t mapping; - - uint8_t block_count; - int block_count_loaded; - - uint8_t status_ctrl; - - uint8_t buffer[0x80]; - int buffer_pos; - int buffer_host_pos; - - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; - - ncr5380_t ncr; - int ncr5380_dma_enabled; - - int64_t dma_timer; - int64_t dma_enabled; - - int ncr_busy; -} ncr_t; - - -enum { - DMA_IDLE = 0, - DMA_SEND, - DMA_TARGET_RECEIVE, - DMA_INITIATOR_RECEIVE -}; - - -#ifdef ENABLE_NCR5380_LOG -int ncr5380_do_log = ENABLE_NCR5380_LOG; -#endif - - -static void -ncr_log(const char *fmt, ...) -{ -#ifdef ENABLE_NCR5380_LOG - va_list ap; - - if (ncr5380_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -dma_changed(void *priv, int mode, int enable) -{ - ncr_t *scsi = (ncr_t *)priv; - - scsi->ncr5380_dma_enabled = (mode && enable); - - scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); -} - - -void -ncr5380_reset(ncr5380_t *ncr) -{ - memset(ncr, 0x00, sizeof(ncr5380_t)); -} - - -static uint32_t -get_bus_host(ncr5380_t *ncr) -{ - uint32_t bus_host = 0; - - if (ncr->icr & ICR_DBP) - bus_host |= BUS_DBP; - if (ncr->icr & ICR_SEL) - bus_host |= BUS_SEL; - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; - if (ncr->tcr & TCR_IO) - bus_host |= BUS_IO; - if (ncr->tcr & TCR_CD) - bus_host |= BUS_CD; - if (ncr->tcr & TCR_MSG) - bus_host |= BUS_MSG; - if (ncr->tcr & TCR_REQ) - bus_host |= BUS_REQ; - if (ncr->icr & ICR_BSY) - bus_host |= BUS_BSY; - if (ncr->icr & ICR_ACK) - bus_host |= BUS_ACK; - if (ncr->mode & MODE_ARBITRATE) - bus_host |= BUS_ARB; - - return(bus_host | BUS_SETDATA(ncr->output_data)); -} - - -static void -ncr_write(uint16_t port, uint8_t val, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - ncr5380_t *ncr = &scsi->ncr; - int bus_host = 0; - -#if ENABLE_NCR5380_LOG - ncr_log("NCR5380 write(%04x,%02x) @%04X:%04X\n",port,val,CS,cpu_state.pc); -#endif - switch (port & 7) { - case 0: /* Output data register */ - ncr->output_data = val; - break; - - case 1: /* Initiator Command Register */ - if ((val & (ICR_BSY | ICR_SEL)) == (ICR_BSY | ICR_SEL) && - (ncr->icr & (ICR_BSY | ICR_SEL)) == ICR_SEL) { - uint8_t temp = ncr->output_data & 0x7f; - - ncr->target_id = -1; - while (temp) { - temp >>= 1; - ncr->target_id++; - } - - ncr_log("Select - target ID = %i, temp data %x\n", ncr->target_id, temp); - } - ncr->icr = val; - break; - - case 2: /* Mode register */ - if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { - ncr->icr &= ~ICR_ARB_LOST; - ncr->icr |= ICR_ARB_IN_PROGRESS; - } - ncr->mode = val; - dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA); - if (! (ncr->mode & MODE_DMA)) { - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - break; - - case 3: /* Target Command Register */ - ncr->tcr = val; - break; - - case 4: /* Select Enable Register */ - ncr->ser = val; - break; - - case 5: /* start DMA Send */ - ncr->dma_mode = DMA_SEND; - dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA); - break; - - case 7: /* start DMA Initiator Receive */ - ncr->dma_mode = DMA_INITIATOR_RECEIVE; - dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA); - break; - - default: -#if 1 - pclog("NCR5380: bad write %04x %02x\n", port, val); -#endif - break; - } - - bus_host = get_bus_host(ncr); - - scsi_bus_update(&ncr->bus, bus_host); -} - - -static uint8_t -ncr_read(uint16_t port, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - ncr5380_t *ncr = &scsi->ncr; - uint32_t bus = 0; - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: /* current SCSI data */ - if (ncr->icr & ICR_DBP) { - ret = ncr->output_data; - } else { - bus = scsi_bus_read(&ncr->bus); - ret = BUS_GETDATA(bus); - } - break; - - case 1: /* Initiator Command Register */ - ret = ncr->icr; - break; - - case 2: /* Mode register */ - ret = ncr->mode; - break; - - case 3: /* Target Command Register */ - ret = ncr->tcr; - break; - - case 4: /* Current SCSI Bus status */ - ret = 0; - bus = scsi_bus_read(&ncr->bus); - ret |= (bus & 0xff); - break; - - case 5: /* Bus and Status register */ - ret = 0; - - bus = get_bus_host(ncr); - if (scsi_bus_match(&ncr->bus, bus)) - ret |= 0x08; - bus = scsi_bus_read(&ncr->bus); - - if (bus & BUS_ACK) - ret |= STATUS_ACK; - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - ret |= STATUS_DRQ; - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { - int bus_state = 0; - - if (bus & BUS_IO) - bus_state |= TCR_IO; - if (bus & BUS_CD) - bus_state |= TCR_CD; - if (bus & BUS_MSG) - bus_state |= TCR_MSG; - if ((ncr->tcr & 7) != bus_state) - ncr->isr |= STATUS_INT; - } - if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) - ret |= STATUS_BUSY_ERROR; - ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); - break; - - case 7: /* reset Parity/Interrupt */ - ncr->isr &= ~STATUS_INT; - break; - - default: - ncr_log("NCR5380: bad read %04x\n", port); - break; - } - -#if ENABLE_NCR5380_LOG - ncr_log("NCR5380 read(%04x)=%02x @%04X:%04X\n", port, ret, CS,cpu_state.pc); -#endif - return(ret); -} - - -static void -dma_callback(void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - ncr5380_t *ncr = &scsi->ncr; - int bytes_transferred = 0; - int c; - - scsi->dma_timer += POLL_TIME_US * TIMER_USEC; - - switch (scsi->ncr.dma_mode) { - case DMA_SEND: - if (scsi->status_ctrl & CTRL_DATA_DIR) { - ncr_log("DMA_SEND with DMA direction set wrong\n"); - break; - } - - if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) { - break; - } - - if (! scsi->block_count_loaded) break; - - while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus; - uint8_t data; - - for (c = 0; c < 10; c++) { - uint8_t status = scsi_bus_read(&ncr->bus); - - if (status & BUS_REQ) break; - } - if (c == 10) break; - - /* Data ready. */ - data = scsi->buffer[scsi->buffer_pos]; - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(data); - - scsi_bus_update(&ncr->bus, bus | BUS_ACK); - scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); - - bytes_transferred++; - if (++scsi->buffer_pos == 128) { - scsi->buffer_pos = 0; - scsi->buffer_host_pos = 0; - scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - scsi->block_count = (scsi->block_count - 1) & 255; - scsi->ncr_busy = 0; - if (! scsi->block_count) { - scsi->block_count_loaded = 0; - scsi->dma_enabled = 0; - - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - if (ncr->mode & MODE_ENA_EOP_INT) - ncr->isr |= STATUS_INT; - } - break; - } - } - break; - - case DMA_INITIATOR_RECEIVE: - if (!(scsi->status_ctrl & CTRL_DATA_DIR)) { - ncr_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); - break; - } - - if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) break; - - if (!scsi->block_count_loaded) break; - - while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus; - uint8_t temp; - - for (c = 0; c < 10; c++) { - uint8_t status = scsi_bus_read(&ncr->bus); - - if (status & BUS_REQ) break; - } - if (c == 10) break; - - /* Data ready. */ - bus = scsi_bus_read(&ncr->bus); - temp = BUS_GETDATA(bus); - bus = get_bus_host(ncr); - - scsi_bus_update(&ncr->bus, bus | BUS_ACK); - scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); - - bytes_transferred++; - scsi->buffer[scsi->buffer_pos++] = temp; - if (scsi->buffer_pos == 128) { - scsi->buffer_pos = 0; - scsi->buffer_host_pos = 0; - scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - scsi->block_count = (scsi->block_count - 1) & 255; - if (!scsi->block_count) { - scsi->block_count_loaded = 0; - scsi->dma_enabled = 0; - - ncr->isr |= STATUS_END_OF_DMA; - if (ncr->mode & MODE_ENA_EOP_INT) - ncr->isr |= STATUS_INT; - } - break; - } - } - break; - - default: -#if 1 - pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode); -#endif - break; - } - - c = scsi_bus_read(&ncr->bus); - if (!(c & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; - dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA); - } -} - - -/* Memory-mapped I/O READ handler. */ -static uint8_t -memio_read(uint32_t addr, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - uint8_t ret = 0xff; - - addr &= 0x3fff; -#if ENABLE_NCR5380_LOG - ncr_log("memio_read %08x\n", addr); -#endif - - if (addr < 0x2000) - ret = scsi->bios_rom.rom[addr & 0x1fff]; - else if (addr < 0x3800) - ret = 0xff; - else if (addr >= 0x3a00) - ret = scsi->ext_ram[addr - 0x3a00]; - else switch (addr & 0x3f80) { - case 0x3800: -#if ENABLE_NCR5380_LOG - ncr_log("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]); -#endif - ret = scsi->int_ram[addr & 0x3f]; - break; - - case 0x3880: -#if ENABLE_NCR5380_LOG - ncr_log("Read 53c80 %04x\n", addr); -#endif - ret = ncr_read(addr, scsi); - break; - - case 0x3900: -#if ENABLE_NCR5380_LOG - ncr_log(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl); -#endif - if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR)) - ret = 0xff; - else { - ret = scsi->buffer[scsi->buffer_host_pos++]; - - if (scsi->buffer_host_pos == 128) - scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* status */ - ret = scsi->status_ctrl;// | 0x80; - if (! scsi->ncr_busy) - ret |= STATUS_53C80_ACCESSIBLE; - break; - - case 0x3981: /* block counter register*/ - ret = scsi->block_count; - break; - - case 0x3982: /* switch register read */ - ret = 0xff; - break; - - case 0x3983: - ret = 0xff; - break; - } - break; - } - -#if ENABLE_NCR5380_LOG - if (addr >= 0x3880) - ncr_log("memio_read(%08x)=%02x\n", addr, ret); -#endif - - return(ret); -} - - -/* Memory-mapped I/O WRITE handler. */ -static void -memio_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - - addr &= 0x3fff; - -#if ENABLE_NCR5380_LOG - ncr_log("memio_write(%08x,%02x) @%04X:%04X %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); -#endif - - if (addr >= 0x3a00) - scsi->ext_ram[addr - 0x3a00] = val; - else switch (addr & 0x3f80) { - case 0x3800: -#if 0 - ncr_log("Write intram %02x %02x\n", addr & 0x3f, val); -#endif - scsi->int_ram[addr & 0x3f] = val; - break; - - case 0x3880: -#if ENABLE_NCR5380_LOG - ncr_log("Write 53c80 %04x %02x\n", addr, val); -#endif - ncr_write(addr, val, scsi); - break; - - case 0x3900: - if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128) { - scsi->buffer[scsi->buffer_host_pos++] = val; - if (scsi->buffer_host_pos == 128) { - scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - scsi->ncr_busy = 1; - } - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* Control */ - if ((val & CTRL_DATA_DIR) && !(scsi->status_ctrl & CTRL_DATA_DIR)) { - scsi->buffer_host_pos = 128; - scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - } - else if (!(val & CTRL_DATA_DIR) && (scsi->status_ctrl & CTRL_DATA_DIR)) { - scsi->buffer_host_pos = 0; - scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - scsi->status_ctrl = (scsi->status_ctrl & 0x87) | (val & 0x78); - break; - - case 0x3981: /* block counter register */ - scsi->block_count = val; - scsi->block_count_loaded = 1; - scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); - if (scsi->status_ctrl & CTRL_DATA_DIR) { - scsi->buffer_host_pos = 128; - scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - scsi->buffer_host_pos = 0; - scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - break; - } - break; - } -} - - -/* Memory-mapped I/O READ handler for the Trantor T130B. */ -static uint8_t -t130b_read(uint32_t addr, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - uint8_t ret = 0xff; - - addr &= 0x3fff; - if (addr < 0x1800) - ret = scsi->bios_rom.rom[addr & 0x1fff]; - else - if (addr < 0x1880) - ret = scsi->ext_ram[addr & 0x7f]; - - return(ret); -} - - -/* Memory-mapped I/O WRITE handler for the Trantor T130B. */ -static void -t130b_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - - addr &= 0x3fff; - if (addr >= 0x1800 && addr < 0x1880) - scsi->ext_ram[addr & 0x7f] = val; -} - - -static uint8_t -t130b_in(uint16_t port, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - uint8_t ret = 0xff; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - ret = memio_read((port & 7) | 0x3980, scsi); - break; - - case 0x04: - case 0x05: - ret = memio_read(0x3900, scsi); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ret = ncr_read(port, scsi); - break; - } - - return(ret); -} - - -static void -t130b_out(uint16_t port, uint8_t val, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - memio_write((port & 7) | 0x3980, val, scsi); - break; - - case 0x04: - case 0x05: - memio_write(0x3900, val, scsi); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ncr_write(port, val, scsi); - break; - } -} - - -static uint8_t -scsiat_in(uint16_t port, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - uint8_t ret = 0xff; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - ret = memio_read((port & 7) | 0x3980, scsi); - break; - - case 0x04: - case 0x05: - ret = memio_read(0x3900, scsi); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ret = ncr_read(port, scsi); - break; - } - - return(ret); -} - - -static void -scsiat_out(uint16_t port, uint8_t val, void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - memio_write((port & 7) | 0x3980, val, scsi); - break; - - case 0x04: - case 0x05: - memio_write(0x3900, val, scsi); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ncr_write(port, val, scsi); - break; - } -} - - -static void * -ncr_init(const device_t *info) -{ - char temp[128]; - ncr_t *scsi; - - scsi = malloc(sizeof(ncr_t)); - memset(scsi, 0x00, sizeof(ncr_t)); - scsi->name = info->name; - scsi->type = info->local; - - switch(scsi->type) { - case 0: /* Longshine LCS6821N */ - scsi->rom_addr = 0xDC000; - rom_init(&scsi->bios_rom, LCS6821N_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&scsi->bios_rom.mapping); - - mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); - break; - - case 1: /* Ranco RT1000B */ - scsi->rom_addr = 0xDC000; - rom_init(&scsi->bios_rom, RT1000B_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_disable(&scsi->bios_rom.mapping); - - mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); - break; - - case 2: /* Trantor T130B */ - scsi->rom_addr = 0xDC000; - scsi->base = 0x0350; - rom_init(&scsi->bios_rom, T130B_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); - - io_sethandler(scsi->base, 16, - t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi); - break; - - case 3: /* Sumo SCSI-AT */ - scsi->base = device_get_config_hex16("base"); - scsi->irq = device_get_config_int("irq"); - scsi->rom_addr = device_get_config_hex20("bios_addr"); - rom_init(&scsi->bios_rom, SCSIAT_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); - - io_sethandler(scsi->base, 16, - scsiat_in,NULL,NULL, scsiat_out,NULL,NULL, scsi); - break; - } - - sprintf(temp, "%s: BIOS=%05X", scsi->name, scsi->rom_addr); - if (scsi->base != 0) - sprintf(&temp[strlen(temp)], " I/O=%04x", scsi->base); - if (scsi->irq != 0) - sprintf(&temp[strlen(temp)], " IRQ=%d", scsi->irq); - pclog("%s\n", temp); - - ncr5380_reset(&scsi->ncr); - - scsi->status_ctrl = STATUS_BUFFER_NOT_READY; - scsi->buffer_host_pos = 128; - - timer_add(dma_callback, &scsi->dma_timer, &scsi->dma_enabled, scsi); - - return(scsi); -} - - -static void -ncr_close(void *priv) -{ - ncr_t *scsi = (ncr_t *)priv; - - free(scsi); -} - - -static int -lcs6821n_available(void) -{ - return(rom_present(LCS6821N_ROM)); -} - - -static int -rt1000b_available(void) -{ - return(rom_present(RT1000B_ROM)); -} - - -static int -t130b_available(void) -{ - return(rom_present(T130B_ROM)); -} - - -static int -scsiat_available(void) -{ - return(rom_present(SCSIAT_ROM)); -} - - -static const device_config_t scsiat_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x0310, - { - { - "None", 0 - }, - { - "300H", 0x0300 - }, - { - "310H", 0x0310 - }, - { - "320H", 0x0320 - }, - { - "330H", 0x0330 - }, - { - "340H", 0x0340 - }, - { - "350H", 0x0350 - }, - { - "360H", 0x0360 - }, - { - "370H", 0x0370 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, - { - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - - -const device_t scsi_lcs6821n_device = -{ - "Longshine LCS-6821N", - DEVICE_ISA, - 0, - ncr_init, ncr_close, NULL, - lcs6821n_available, - NULL, NULL, - NULL -}; - -const device_t scsi_rt1000b_device = -{ - "Ranco RT1000B", - DEVICE_ISA, - 1, - ncr_init, ncr_close, NULL, - rt1000b_available, - NULL, NULL, - NULL -}; - -const device_t scsi_t130b_device = -{ - "Trantor T130B", - DEVICE_ISA, - 2, - ncr_init, ncr_close, NULL, - t130b_available, - NULL, NULL, - NULL -}; - -const device_t scsi_scsiat_device = -{ - "Sumo SCSI-AT", - DEVICE_ISA, - 3, - ncr_init, ncr_close, NULL, - scsiat_available, - NULL, NULL, - scsiat_config -}; diff --git a/src - Cópia/scsi/scsi_ncr5380.h b/src - Cópia/scsi/scsi_ncr5380.h deleted file mode 100644 index 55b16f654..000000000 --- a/src - Cópia/scsi/scsi_ncr5380.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for - * the ISA bus. - * - * Version: @(#)scsi_ncr5380.c 1.0.2 2018/03/18 - * - * Authors: Sarah Walker, - * TheCollector1995, - * Fred N. van Kempen, - * - * Copyright 2017-2018 Sarah Walker. - * Copyright 2017-2018 TheCollector1995. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef SCSI_NCR5380_H -# define SCSI_NCR5380_H - - -extern const device_t scsi_lcs6821n_device; -extern const device_t scsi_rt1000b_device; -extern const device_t scsi_t130b_device; -extern const device_t scsi_scsiat_device; - - -#endif /*SCSI_NCR5380_H*/ diff --git a/src - Cópia/scsi/scsi_ncr53c810.c b/src - Cópia/scsi/scsi_ncr53c810.c deleted file mode 100644 index 5afc37b59..000000000 --- a/src - Cópia/scsi/scsi_ncr53c810.c +++ /dev/null @@ -1,2215 +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. - * - * Implementation of the NCR 53C810 SCSI Host Adapter made by - * NCR and later Symbios and LSI. This controller was designed - * for the PCI bus. - * - * Version: @(#)scsi_ncr53c810.c 1.0.14 2018/05/28 - * - * Authors: Paul Brook (QEMU) - * Artyom Tarasenko (QEMU) - * TheCollector1995, - * Miran Grca, - * - * Copyright 2006-2018 Paul Brook. - * Copyright 2009-2018 Artyom Tarasenko. - * Copyright 2017,2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../nvr.h" -#include "../timer.h" -#include "../plat.h" -#include "scsi.h" -#include "scsi_device.h" -#include "scsi_ncr53c810.h" - -#define NCR53C810_ROM L"roms/scsi/ncr53c810/NCR307.BIN" - -#define NCR_SCNTL0_TRG 0x01 -#define NCR_SCNTL0_AAP 0x02 -#define NCR_SCNTL0_EPC 0x08 -#define NCR_SCNTL0_WATN 0x10 -#define NCR_SCNTL0_START 0x20 - -#define NCR_SCNTL1_SST 0x01 -#define NCR_SCNTL1_IARB 0x02 -#define NCR_SCNTL1_AESP 0x04 -#define NCR_SCNTL1_RST 0x08 -#define NCR_SCNTL1_CON 0x10 -#define NCR_SCNTL1_DHP 0x20 -#define NCR_SCNTL1_ADB 0x40 -#define NCR_SCNTL1_EXC 0x80 - -#define NCR_SCNTL2_WSR 0x01 -#define NCR_SCNTL2_VUE0 0x02 -#define NCR_SCNTL2_VUE1 0x04 -#define NCR_SCNTL2_WSS 0x08 -#define NCR_SCNTL2_SLPHBEN 0x10 -#define NCR_SCNTL2_SLPMD 0x20 -#define NCR_SCNTL2_CHM 0x40 -#define NCR_SCNTL2_SDU 0x80 - -#define NCR_ISTAT_DIP 0x01 -#define NCR_ISTAT_SIP 0x02 -#define NCR_ISTAT_INTF 0x04 -#define NCR_ISTAT_CON 0x08 -#define NCR_ISTAT_SEM 0x10 -#define NCR_ISTAT_SIGP 0x20 -#define NCR_ISTAT_SRST 0x40 -#define NCR_ISTAT_ABRT 0x80 - -#define NCR_SSTAT0_SDP0 0x01 -#define NCR_SSTAT0_RST 0x02 -#define NCR_SSTAT0_WOA 0x04 -#define NCR_SSTAT0_LOA 0x08 -#define NCR_SSTAT0_AIP 0x10 -#define NCR_SSTAT0_OLF 0x20 -#define NCR_SSTAT0_ORF 0x40 -#define NCR_SSTAT0_ILF 0x80 - -#define NCR_SIST0_PAR 0x01 -#define NCR_SIST0_RST 0x02 -#define NCR_SIST0_UDC 0x04 -#define NCR_SIST0_SGE 0x08 -#define NCR_SIST0_RSL 0x10 -#define NCR_SIST0_SEL 0x20 -#define NCR_SIST0_CMP 0x40 -#define NCR_SIST0_MA 0x80 - -#define NCR_SIST1_HTH 0x01 -#define NCR_SIST1_GEN 0x02 -#define NCR_SIST1_STO 0x04 -#define NCR_SIST1_SBMC 0x10 - -#define NCR_SOCL_IO 0x01 -#define NCR_SOCL_CD 0x02 -#define NCR_SOCL_MSG 0x04 -#define NCR_SOCL_ATN 0x08 -#define NCR_SOCL_SEL 0x10 -#define NCR_SOCL_BSY 0x20 -#define NCR_SOCL_ACK 0x40 -#define NCR_SOCL_REQ 0x80 - -#define NCR_DSTAT_IID 0x01 -#define NCR_DSTAT_SIR 0x04 -#define NCR_DSTAT_SSI 0x08 -#define NCR_DSTAT_ABRT 0x10 -#define NCR_DSTAT_BF 0x20 -#define NCR_DSTAT_MDPE 0x40 -#define NCR_DSTAT_DFE 0x80 - -#define NCR_DCNTL_COM 0x01 -#define NCR_DCNTL_IRQD 0x02 -#define NCR_DCNTL_STD 0x04 -#define NCR_DCNTL_IRQM 0x08 -#define NCR_DCNTL_SSM 0x10 -#define NCR_DCNTL_PFEN 0x20 -#define NCR_DCNTL_PFF 0x40 -#define NCR_DCNTL_CLSE 0x80 - -#define NCR_DMODE_MAN 0x01 -#define NCR_DMODE_BOF 0x02 -#define NCR_DMODE_ERMP 0x04 -#define NCR_DMODE_ERL 0x08 -#define NCR_DMODE_DIOM 0x10 -#define NCR_DMODE_SIOM 0x20 - -#define NCR_CTEST2_DACK 0x01 -#define NCR_CTEST2_DREQ 0x02 -#define NCR_CTEST2_TEOP 0x04 -#define NCR_CTEST2_PCICIE 0x08 -#define NCR_CTEST2_CM 0x10 -#define NCR_CTEST2_CIO 0x20 -#define NCR_CTEST2_SIGP 0x40 -#define NCR_CTEST2_DDIR 0x80 - -#define NCR_CTEST5_BL2 0x04 -#define NCR_CTEST5_DDIR 0x08 -#define NCR_CTEST5_MASR 0x10 -#define NCR_CTEST5_DFSN 0x20 -#define NCR_CTEST5_BBCK 0x40 -#define NCR_CTEST5_ADCK 0x80 - -/* Enable Response to Reselection */ -#define NCR_SCID_RRE 0x60 - -#define PHASE_DO 0 -#define PHASE_DI 1 -#define PHASE_CMD 2 -#define PHASE_ST 3 -#define PHASE_MO 6 -#define PHASE_MI 7 -#define PHASE_MASK 7 - -/* Maximum length of MSG IN data. */ -#define NCR_MAX_MSGIN_LEN 8 - -/* Flag set if this is a tagged command. */ -#define NCR_TAG_VALID (1 << 16) - -#define NCR_BUF_SIZE 4096 - -typedef struct ncr53c810_request { - uint32_t tag; - uint32_t dma_len; - uint8_t *dma_buf; - uint32_t pending; - int out; -} ncr53c810_request; - -typedef enum -{ - SCSI_STATE_SEND_COMMAND, - SCSI_STATE_READ_DATA, - SCSI_STATE_WRITE_DATA, - SCSI_STATE_READ_STATUS, - SCSI_STATE_READ_MESSAGE, - SCSI_STATE_WRITE_MESSAGE -} scsi_state_t; - -typedef struct { - uint8_t pci_slot; - int has_bios; - rom_t bios; - int PCIBase; - int MMIOBase; - mem_mapping_t mmio_mapping; - int RAMBase; - mem_mapping_t ram_mapping; - - int carry; /* ??? Should this be an a visible register somewhere? */ - int status; - /* Action to take at the end of a MSG IN phase. - 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN. */ - int msg_action; - int msg_len; - uint8_t msg[NCR_MAX_MSGIN_LEN]; - /* 0 if SCRIPTS are running or stopped. - * 1 if a Wait Reselect instruction has been issued. - * 2 if processing DMA from ncr53c810_execute_script. - * 3 if a DMA operation is in progress. */ - int waiting; - - uint8_t current_lun; - uint8_t select_id; - int command_complete; - ncr53c810_request *current; - - int irq; - - uint32_t dsa; - uint32_t temp; - uint32_t dnad; - uint32_t dbc; - uint8_t istat; - uint8_t dcmd; - uint8_t dstat; - uint8_t dien; - uint8_t sist0; - uint8_t sist1; - uint8_t sien0; - uint8_t sien1; - uint8_t mbox0; - uint8_t mbox1; - uint8_t dfifo; - uint8_t ctest2; - uint8_t ctest3; - uint8_t ctest4; - uint8_t ctest5; - uint32_t dsp; - uint32_t dsps; - uint8_t dmode; - uint8_t dcntl; - uint8_t scntl0; - uint8_t scntl1; - uint8_t scntl2; - uint8_t scntl3; - uint8_t sstat0; - uint8_t sstat1; - uint8_t scid; - uint8_t sxfer; - uint8_t socl; - uint8_t sdid; - uint8_t ssid; - uint8_t sfbr; - uint8_t stest1; - uint8_t stest2; - uint8_t stest3; - uint8_t sidl; - uint8_t stime0; - uint8_t respid; - uint32_t scratcha; - uint32_t scratchb; - uint8_t sbr; - uint8_t chip_rev; - int last_level; - void *hba_private; - uint8_t gpreg0; - uint32_t buffer_pos; - int32_t temp_buf_len; - uint8_t last_command; - - uint8_t sstop; - - uint8_t regop; - uint32_t adder; - - int64_t timer_period; - int64_t timer_enabled; -} ncr53c810_t; - - -#ifdef ENABLE_NCR53C810_LOG -int ncr53c810_do_log = ENABLE_NCR53C810_LOG; -#endif - - -static void -ncr53c810_log(const char *fmt, ...) -{ -#ifdef ENABLE_NCR53C810_LOG - va_list ap; - - if (ncr53c810_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static uint8_t ncr53c810_reg_readb(ncr53c810_t *dev, uint32_t offset); -static void ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val); - - -static __inline__ int32_t -sextract32(uint32_t value, int start, int length) -{ - /* Note that this implementation relies on right shift of signed - * integers being an arithmetic shift. - */ - return ((int32_t)(value << (32 - length - start))) >> (32 - length); -} - - -static __inline__ uint32_t -deposit32(uint32_t value, int start, int length, - uint32_t fieldval) -{ - uint32_t mask; - mask = (~0U >> (32 - length)) << start; - return (value & ~mask) | ((fieldval << start) & mask); -} - - -static __inline__ int -ncr53c810_irq_on_rsl(ncr53c810_t *dev) -{ - return (dev->sien0 & NCR_SIST0_RSL) && (dev->scid & NCR_SCID_RRE); -} - - -static void -ncr53c810_soft_reset(ncr53c810_t *dev) -{ - int i, j; - - ncr53c810_log("LSI Reset\n"); - dev->timer_period = dev->timer_enabled = 0; - - dev->carry = 0; - - dev->msg_action = 0; - dev->msg_len = 0; - dev->waiting = 0; - dev->dsa = 0; - dev->dnad = 0; - dev->dbc = 0; - dev->temp = 0; - dev->scratcha = 0; - dev->scratchb = 0; - dev->istat = 0; - dev->dcmd = 0x40; - dev->dstat = NCR_DSTAT_DFE; - dev->dien = 0; - dev->sist0 = 0; - dev->sist1 = 0; - dev->sien0 = 0; - dev->sien1 = 0; - dev->mbox0 = 0; - dev->mbox1 = 0; - dev->dfifo = 0; - dev->ctest2 = NCR_CTEST2_DACK; - dev->ctest3 = 0; - dev->ctest4 = 0; - dev->ctest5 = 0; - dev->dsp = 0; - dev->dsps = 0; - dev->dmode = 0; - dev->dcntl = 0; - dev->scntl0 = 0xc0; - dev->scntl1 = 0; - dev->scntl2 = 0; - dev->scntl3 = 0; - dev->sstat0 = 0; - dev->sstat1 = 0; - dev->scid = 7; - dev->sxfer = 0; - dev->socl = 0; - dev->sdid = 0; - dev->ssid = 0; - dev->stest1 = 0; - dev->stest2 = 0; - dev->stest3 = 0; - dev->sidl = 0; - dev->stime0 = 0; - dev->respid = 0x80; - dev->sbr = 0; - dev->last_level = 0; - dev->gpreg0 = 0; - dev->sstop = 1; - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } -} - - -static void -ncr53c810_read(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len) -{ - uint32_t i = 0; - - ncr53c810_log("ncr53c810_read(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); - - if (dev->dmode & NCR_DMODE_SIOM) { - ncr53c810_log("NCR 810: Reading from I/O address %04X\n", (uint16_t) addr); - for (i = 0; i < len; i++) - buf[i] = inb((uint16_t) (addr + i)); - } else { - ncr53c810_log("NCR 810: Reading from memory address %08X\n", addr); - DMAPageRead(addr, buf, len); - } -} - - -static void -ncr53c810_write(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len) -{ - uint32_t i = 0; - - ncr53c810_log("ncr53c810_write(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); - - if (dev->dmode & NCR_DMODE_DIOM) { - ncr53c810_log("NCR 810: Writing to I/O address %04X\n", (uint16_t) addr); - for (i = 0; i < len; i++) - outb((uint16_t) (addr + i), buf[i]); - } else { - ncr53c810_log("NCR 810: Writing to memory address %08X\n", addr); - DMAPageWrite(addr, buf, len); - } -} - - -static __inline__ uint32_t -read_dword(ncr53c810_t *dev, uint32_t addr) -{ - uint32_t buf; - ncr53c810_log("Reading the next DWORD from memory (%08X)...\n", addr); - DMAPageRead(addr, (uint8_t *)&buf, 4); - return buf; -} - - -static -void do_irq(ncr53c810_t *dev, int level) -{ - if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); - ncr53c810_log("Raising IRQ...\n"); - } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); - ncr53c810_log("Lowering IRQ...\n"); - } -} - - -static void -ncr53c810_update_irq(ncr53c810_t *dev) -{ - int level; - - /* It's unclear whether the DIP/SIP bits should be cleared when the - Interrupt Status Registers are cleared or when istat is read. - We currently do the formwer, which seems to work. */ - level = 0; - if (dev->dstat & 0x7f) { - if ((dev->dstat & dev->dien) & 0x7f) - level = 1; - dev->istat |= NCR_ISTAT_DIP; - } else { - dev->istat &= ~NCR_ISTAT_DIP; - } - - if (dev->sist0 || dev->sist1) { - if ((dev->sist0 & dev->sien0) || (dev->sist1 & dev->sien1)) - level = 1; - dev->istat |= NCR_ISTAT_SIP; - } else { - dev->istat &= ~NCR_ISTAT_SIP; - } - if (dev->istat & NCR_ISTAT_INTF) { - level = 1; - } - - if (level != dev->last_level) { - ncr53c810_log("Update IRQ level %d dstat %02x sist %02x%02x\n", - level, dev->dstat, dev->sist1, dev->sist0); - dev->last_level = level; - do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */ - } -} - - -/* Stop SCRIPTS execution and raise a SCSI interrupt. */ -static void -ncr53c810_script_scsi_interrupt(ncr53c810_t *dev, int stat0, int stat1) -{ - uint32_t mask0; - uint32_t mask1; - - ncr53c810_log("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n", - stat1, stat0, dev->sist1, dev->sist0); - dev->sist0 |= stat0; - dev->sist1 |= stat1; - /* Stop processor on fatal or unmasked interrupt. As a special hack - we don't stop processing when raising STO. Instead continue - execution and stop at the next insn that accesses the SCSI bus. */ - mask0 = dev->sien0 | ~(NCR_SIST0_CMP | NCR_SIST0_SEL | NCR_SIST0_RSL); - mask1 = dev->sien1 | ~(NCR_SIST1_GEN | NCR_SIST1_HTH); - mask1 &= ~NCR_SIST1_STO; - if ((dev->sist0 & mask0) || (dev->sist1 & mask1)) { - ncr53c810_log("NCR 810: IRQ-mandated stop\n"); - dev->sstop = 1; - dev->timer_period = dev->timer_enabled = 0; - } - ncr53c810_update_irq(dev); -} - - -/* Stop SCRIPTS execution and raise a DMA interrupt. */ -static void -ncr53c810_script_dma_interrupt(ncr53c810_t *dev, int stat) -{ - ncr53c810_log("DMA Interrupt 0x%x prev 0x%x\n", stat, dev->dstat); - dev->dstat |= stat; - ncr53c810_update_irq(dev); - dev->sstop = 1; - dev->timer_period = dev->timer_enabled = 0; -} - - -static __inline__ void -ncr53c810_set_phase(ncr53c810_t *dev, int phase) -{ - dev->sstat1 = (dev->sstat1 & ~PHASE_MASK) | phase; -} - - -static void -ncr53c810_bad_phase(ncr53c810_t *dev, int out, int new_phase) -{ - /* Trigger a phase mismatch. */ - ncr53c810_log("Phase mismatch interrupt\n"); - ncr53c810_script_scsi_interrupt(dev, NCR_SIST0_MA, 0); - dev->sstop = 1; - dev->timer_period = dev->timer_enabled = 0; - ncr53c810_set_phase(dev, new_phase); -} - - -static void -ncr53c810_disconnect(ncr53c810_t *dev) -{ - dev->scntl1 &= ~NCR_SCNTL1_CON; - dev->sstat1 &= ~PHASE_MASK; - if (dev->dcmd & 0x01) /* Select with ATN */ - dev->sstat1 |= 0x07; -} - - -static void -ncr53c810_bad_selection(ncr53c810_t *dev, uint32_t id) -{ - ncr53c810_log("Selected absent target %d\n", id); - ncr53c810_script_scsi_interrupt(dev, 0, NCR_SIST1_STO); - ncr53c810_disconnect(dev); -} - - -/* Callback to indicate that the SCSI layer has completed a command. */ -static void -ncr53c810_command_complete(void *priv, uint32_t status) -{ - ncr53c810_t *dev = (ncr53c810_t *)priv; - int out; - - out = (dev->sstat1 & PHASE_MASK) == PHASE_DO; - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Command complete status=%d\n", dev->current->tag, dev->current_lun, dev->last_command, (int)status); - dev->status = status; - dev->command_complete = 2; - if (dev->waiting && dev->dbc != 0) { - /* Raise phase mismatch for short transfers. */ - ncr53c810_bad_phase(dev, out, PHASE_ST); - } else - ncr53c810_set_phase(dev, PHASE_ST); - - dev->sstop = 0; -} - - -static void -ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id) -{ - uint32_t addr, tdbc; - int count; - - scsi_device_t *sd; - - sd = &SCSIDevices[id][dev->current_lun]; - - if ((!scsi_device_present(id, dev->current_lun))) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command); - return; - } - - if (!dev->current->dma_len) { - /* Wait until data is available. */ - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DMA no data available\n", id, dev->current_lun, dev->last_command); - return; - } - - /* Make sure count is never bigger than BufferLength. */ - count = tdbc = dev->dbc; - if (count > dev->temp_buf_len) - count = dev->temp_buf_len; - - addr = dev->dnad; - - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DMA addr=0x%08x len=%d cur_len=%d dev->dbc=%d\n", id, dev->current_lun, dev->last_command, dev->dnad, dev->temp_buf_len, count, tdbc); - dev->dnad += count; - dev->dbc -= count; - - if (out) - ncr53c810_read(dev, addr, sd->CmdBuffer+dev->buffer_pos, count); - else { - if (!dev->buffer_pos) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command); - scsi_device_command_phase1(dev->current->tag, dev->current_lun); - } - ncr53c810_write(dev, addr, sd->CmdBuffer+dev->buffer_pos, count); - } - - dev->temp_buf_len -= count; - dev->buffer_pos += count; - - if (dev->temp_buf_len <= 0) { - if (out) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command); - scsi_device_command_phase1(id, dev->current_lun); - } - if (sd->CmdBuffer != NULL) { - free(sd->CmdBuffer); - sd->CmdBuffer = NULL; - } - ncr53c810_command_complete(dev, sd->Status); - } else { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command); - dev->sstop = 0; - } -} - - -/* Queue a byte for a MSG IN phase. */ -static void -ncr53c810_add_msg_byte(ncr53c810_t *dev, uint8_t data) -{ - if (dev->msg_len >= NCR_MAX_MSGIN_LEN) - ncr53c810_log("MSG IN data too long\n"); - else { - ncr53c810_log("MSG IN 0x%02x\n", data); - dev->msg[dev->msg_len++] = data; - } -} - - -static int -ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) -{ - scsi_device_t *sd; - uint8_t buf[12]; - - int64_t p; - - double period; - - memset(buf, 0, 12); - DMAPageRead(dev->dnad, buf, MIN(12, dev->dbc)); - if (dev->dbc > 12) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: CDB length %i too big\n", id, dev->current_lun, buf[0], dev->dbc); - dev->dbc = 12; - } - dev->sfbr = buf[0]; - dev->command_complete = 0; - - sd = &SCSIDevices[id][dev->current_lun]; - if (!scsi_device_present(id, dev->current_lun)) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]); - ncr53c810_bad_selection(dev, id); - return 0; - } - - dev->current = (ncr53c810_request*)malloc(sizeof(ncr53c810_request)); - dev->current->tag = id; - - sd->BufferLength = -1; - - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DBC=%i\n", id, dev->current_lun, buf[0], dev->dbc); - dev->last_command = buf[0]; - - scsi_device_command_phase0(dev->current->tag, dev->current_lun, dev->dbc, buf); - dev->hba_private = (void *)dev->current; - - dev->waiting = 0; - dev->buffer_pos = 0; - - dev->temp_buf_len = sd->BufferLength; - - if (sd->BufferLength > 0) { - sd->CmdBuffer = (uint8_t *)malloc(sd->BufferLength); - dev->current->dma_len = sd->BufferLength; - } - - if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); - ncr53c810_set_phase(dev, PHASE_DI); - p = scsi_device_get_callback(dev->current->tag, dev->current_lun); - if (p <= 0LL) { - period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ - dev->timer_period += (int64_t) period; - } else - dev->timer_period += p; - return 1; - } else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, dev->current_lun, buf[0]); - ncr53c810_set_phase(dev, PHASE_DO); - p = scsi_device_get_callback(dev->current->tag, dev->current_lun); - if (p <= 0LL) { - period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ - dev->timer_period += (int64_t) period; - } else - dev->timer_period += p; - return 1; - } else { - ncr53c810_command_complete(dev, sd->Status); - return 0; - } -} - - -static void -ncr53c810_do_status(ncr53c810_t *dev) -{ - uint8_t status; - ncr53c810_log("Get status len=%d status=%d\n", dev->dbc, dev->status); - if (dev->dbc != 1) - ncr53c810_log("Bad Status move\n"); - dev->dbc = 1; - status = dev->status; - dev->sfbr = status; - ncr53c810_write(dev, dev->dnad, &status, 1); - ncr53c810_set_phase(dev, PHASE_MI); - dev->msg_action = 1; - ncr53c810_add_msg_byte(dev, 0); /* COMMAND COMPLETE */ -} - - -static void -ncr53c810_do_msgin(ncr53c810_t *dev) -{ - uint32_t len; - ncr53c810_log("Message in len=%d/%d\n", dev->dbc, dev->msg_len); - dev->sfbr = dev->msg[0]; - len = dev->msg_len; - if (len > dev->dbc) - len = dev->dbc; - ncr53c810_write(dev, dev->dnad, dev->msg, len); - /* Linux drivers rely on the last byte being in the SIDL. */ - dev->sidl = dev->msg[len - 1]; - dev->msg_len -= len; - if (dev->msg_len) - memmove(dev->msg, dev->msg + len, dev->msg_len); - else { - /* ??? Check if ATN (not yet implemented) is asserted and maybe - switch to PHASE_MO. */ - switch (dev->msg_action) { - case 0: - ncr53c810_set_phase(dev, PHASE_CMD); - break; - case 1: - ncr53c810_disconnect(dev); - break; - case 2: - ncr53c810_set_phase(dev, PHASE_DO); - break; - case 3: - ncr53c810_set_phase(dev, PHASE_DI); - break; - default: - abort(); - } - } -} - - -/* Read the next byte during a MSGOUT phase. */ -static uint8_t -ncr53c810_get_msgbyte(ncr53c810_t *dev) -{ - uint8_t data; - DMAPageRead(dev->dnad, &data, 1); - dev->dnad++; - dev->dbc--; - return data; -} - - -/* Skip the next n bytes during a MSGOUT phase. */ -static void -ncr53c810_skip_msgbytes(ncr53c810_t *dev, unsigned int n) -{ - dev->dnad += n; - dev->dbc -= n; -} - - -static void -ncr53c810_bad_message(ncr53c810_t *dev, uint8_t msg) -{ - ncr53c810_log("Unimplemented message 0x%02x\n", msg); - ncr53c810_set_phase(dev, PHASE_MI); - ncr53c810_add_msg_byte(dev, 7); /* MESSAGE REJECT */ - dev->msg_action = 0; -} - - -static void -ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id) -{ - uint8_t msg; - int len; - uint32_t current_tag; - scsi_device_t *sd; - - sd = &SCSIDevices[id][dev->current_lun]; - - current_tag = id; - - ncr53c810_log("MSG out len=%d\n", dev->dbc); - while (dev->dbc) { - msg = ncr53c810_get_msgbyte(dev); - dev->sfbr = msg; - - switch (msg) { - case 0x04: - ncr53c810_log("MSG: Disconnect\n"); - ncr53c810_disconnect(dev); - break; - case 0x08: - ncr53c810_log("MSG: No Operation\n"); - ncr53c810_set_phase(dev, PHASE_CMD); - break; - case 0x01: - len = ncr53c810_get_msgbyte(dev); - msg = ncr53c810_get_msgbyte(dev); - (void) len; /* avoid a warning about unused variable*/ - ncr53c810_log("Extended message 0x%x (len %d)\n", msg, len); - switch (msg) { - case 1: - ncr53c810_log("SDTR (ignored)\n"); - ncr53c810_skip_msgbytes(dev, 2); - break; - case 3: - ncr53c810_log("WDTR (ignored)\n"); - ncr53c810_skip_msgbytes(dev, 1); - break; - default: - ncr53c810_bad_message(dev, msg); - return; - } - break; - case 0x20: /* SIMPLE queue */ - id |= ncr53c810_get_msgbyte(dev) | NCR_TAG_VALID; - ncr53c810_log("SIMPLE queue tag=0x%x\n", id & 0xff); - break; - case 0x21: /* HEAD of queue */ - ncr53c810_log("HEAD queue not implemented\n"); - id |= ncr53c810_get_msgbyte(dev) | NCR_TAG_VALID; - break; - case 0x22: /* ORDERED queue */ - ncr53c810_log("ORDERED queue not implemented\n"); - id |= ncr53c810_get_msgbyte(dev) | NCR_TAG_VALID; - break; - case 0x0d: - /* The ABORT TAG message clears the current I/O process only. */ - ncr53c810_log("MSG: ABORT TAG tag=0x%x\n", current_tag); - if (sd->CmdBuffer) { - free(sd->CmdBuffer); - sd->CmdBuffer = NULL; - } - ncr53c810_disconnect(dev); - break; - case 0x06: - case 0x0e: - case 0x0c: - /* The ABORT message clears all I/O processes for the selecting - initiator on the specified logical unit of the target. */ - if (msg == 0x06) - ncr53c810_log("MSG: ABORT tag=0x%x\n", current_tag); - /* The CLEAR QUEUE message clears all I/O processes for all - initiators on the specified logical unit of the target. */ - if (msg == 0x0e) - ncr53c810_log("MSG: CLEAR QUEUE tag=0x%x\n", current_tag); - /* The BUS DEVICE RESET message clears all I/O processes for all - initiators on all logical units of the target. */ - if (msg == 0x0c) - ncr53c810_log("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag); - - /* clear the current I/O process */ - if (sd->CmdBuffer) { - free(sd->CmdBuffer); - sd->CmdBuffer = NULL; - } - ncr53c810_disconnect(dev); - break; - default: - if ((msg & 0x80) == 0) { - ncr53c810_bad_message(dev, msg); - return; - } else { - dev->current_lun = msg & 7; - ncr53c810_log("Select LUN %d\n", dev->current_lun); - ncr53c810_set_phase(dev, PHASE_CMD); - } - break; - } - } -} - - -static void -ncr53c810_memcpy(ncr53c810_t *dev, uint32_t dest, uint32_t src, int count) -{ - int n; - uint8_t buf[NCR_BUF_SIZE]; - - ncr53c810_log("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count); - while (count) { - n = (count > NCR_BUF_SIZE) ? NCR_BUF_SIZE : count; - ncr53c810_read(dev, src, buf, n); - ncr53c810_write(dev, dest, buf, n); - src += n; - dest += n; - count -= n; - } -} - - -static void -ncr53c810_process_script(ncr53c810_t *dev) -{ - uint32_t insn, addr, id, buf[2], dest; - int opcode, insn_processed = 0, reg, operator, cond, jmp, n, i, c; - int32_t offset; - uint8_t op0, op1, data8, mask, data[7], *pp; - - dev->sstop = 0; -again: - insn_processed++; - insn = read_dword(dev, dev->dsp); - if (!insn) { - /* If we receive an empty opcode increment the DSP by 4 bytes - instead of 8 and execute the next opcode at that location */ - dev->dsp += 4; - dev->timer_period += (10LL * TIMER_USEC); - if (insn_processed < 100) - goto again; - else - return; - } - addr = read_dword(dev, dev->dsp + 4); - ncr53c810_log("SCRIPTS dsp=%08x opcode %08x arg %08x\n", dev->dsp, insn, addr); - dev->dsps = addr; - dev->dcmd = insn >> 24; - dev->dsp += 8; - - switch (insn >> 30) { - case 0: /* Block move. */ - ncr53c810_log("00: Block move\n"); - if (dev->sist1 & NCR_SIST1_STO) { - ncr53c810_log("Delayed select timeout\n"); - dev->sstop = 1; - break; - } - ncr53c810_log("Block Move DBC=%d\n", dev->dbc); - dev->dbc = insn & 0xffffff; - ncr53c810_log("Block Move DBC=%d now\n", dev->dbc); - /* ??? Set ESA. */ - if (insn & (1 << 29)) { - /* Indirect addressing. */ - /* Should this respect SIOM? */ - addr = read_dword(dev, addr); - ncr53c810_log("Indirect Block Move address: %08X\n", addr); - } else if (insn & (1 << 28)) { - /* Table indirect addressing. */ - - /* 32-bit Table indirect */ - offset = sextract32(addr, 0, 24); - DMAPageRead(dev->dsa + offset, (uint8_t *)buf, 8); - /* byte count is stored in bits 0:23 only */ - dev->dbc = buf[0] & 0xffffff; - addr = buf[1]; - - /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of - * table, bits [31:24] */ - } - if ((dev->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { - ncr53c810_log("Wrong phase got %d expected %d\n", - dev->sstat1 & PHASE_MASK, (insn >> 24) & 7); - ncr53c810_script_scsi_interrupt(dev, NCR_SIST0_MA, 0); - break; - } - dev->dnad = addr; - switch (dev->sstat1 & 0x7) { - case PHASE_DO: - ncr53c810_log("Data Out Phase\n"); - dev->waiting = 0; - ncr53c810_do_dma(dev, 1, dev->sdid); - break; - case PHASE_DI: - ncr53c810_log("Data In Phase\n"); - dev->waiting = 0; - ncr53c810_do_dma(dev, 0, dev->sdid); - break; - case PHASE_CMD: - ncr53c810_log("Command Phase\n"); - c = ncr53c810_do_command(dev, dev->sdid); - - if (!c || dev->sstop || dev->waiting || ((dev->sstat1 & 0x7) == PHASE_ST)) - break; - - dev->dfifo = dev->dbc & 0xff; - dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - - dev->timer_period += (40LL * TIMER_USEC); - - if (dev->dcntl & NCR_DCNTL_SSM) - ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_SSI); - return; - case PHASE_ST: - ncr53c810_log("Status Phase\n"); - ncr53c810_do_status(dev); - break; - case PHASE_MO: - ncr53c810_log("MSG Out Phase\n"); - ncr53c810_do_msgout(dev, dev->sdid); - break; - case PHASE_MI: - ncr53c810_log("MSG In Phase\n"); - ncr53c810_do_msgin(dev); - break; - default: - ncr53c810_log("Unimplemented phase %d\n", dev->sstat1 & PHASE_MASK); - } - dev->dfifo = dev->dbc & 0xff; - dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - break; - - case 1: /* IO or Read/Write instruction. */ - ncr53c810_log("01: I/O or Read/Write instruction\n"); - opcode = (insn >> 27) & 7; - if (opcode < 5) { - if (insn & (1 << 25)) - id = read_dword(dev, dev->dsa + sextract32(insn, 0, 24)); - else - id = insn; - id = (id >> 16) & 0xf; - if (insn & (1 << 26)) - addr = dev->dsp + sextract32(addr, 0, 24); - dev->dnad = addr; - switch (opcode) { - case 0: /* Select */ - dev->sdid = id; - if (dev->scntl1 & NCR_SCNTL1_CON) { - ncr53c810_log("Already reselected, jumping to alternative address\n"); - dev->dsp = dev->dnad; - break; - } - dev->sstat0 |= NCR_SSTAT0_WOA; - dev->scntl1 &= ~NCR_SCNTL1_IARB; - if (!scsi_device_present(id, 0)) { - ncr53c810_bad_selection(dev, id); - break; - } - ncr53c810_log("Selected target %d%s\n", - id, insn & (1 << 24) ? " ATN" : ""); - dev->select_id = id << 8; - dev->scntl1 |= NCR_SCNTL1_CON; - if (insn & (1 << 24)) - dev->socl |= NCR_SOCL_ATN; - ncr53c810_set_phase(dev, PHASE_MO); - dev->waiting = 0; - break; - case 1: /* Disconnect */ - ncr53c810_log("Wait Disconnect\n"); - dev->scntl1 &= ~NCR_SCNTL1_CON; - break; - case 2: /* Wait Reselect */ - ncr53c810_log("Wait Reselect\n"); - if (dev->istat & NCR_ISTAT_SIGP) - dev->dsp = dev->dnad; /* If SIGP is set, this command causes an immediate jump to DNAD. */ - else { - if (!ncr53c810_irq_on_rsl(dev)) - dev->waiting = 1; - } - break; - case 3: /* Set */ - ncr53c810_log("Set%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", - insn & (1 << 6) ? " ACK" : "", - insn & (1 << 9) ? " TM" : "", - insn & (1 << 10) ? " CC" : ""); - if (insn & (1 << 3)) { - dev->socl |= NCR_SOCL_ATN; - ncr53c810_set_phase(dev, PHASE_MO); - } - if (insn & (1 << 9)) - ncr53c810_log("Target mode not implemented\n"); - if (insn & (1 << 10)) - dev->carry = 1; - break; - case 4: /* Clear */ - ncr53c810_log("Clear%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", - insn & (1 << 6) ? " ACK" : "", - insn & (1 << 9) ? " TM" : "", - insn & (1 << 10) ? " CC" : ""); - if (insn & (1 << 3)) - dev->socl &= ~NCR_SOCL_ATN; - if (insn & (1 << 10)) - dev->carry = 0; - break; - } - } else { - reg = ((insn >> 16) & 0x7f) | (insn & 0x80); - data8 = (insn >> 8) & 0xff; - opcode = (insn >> 27) & 7; - operator = (insn >> 24) & 7; - op0 = op1 = 0; - switch (opcode) { - case 5: /* From SFBR */ - op0 = dev->sfbr; - op1 = data8; - break; - case 6: /* To SFBR */ - if (operator) - op0 = ncr53c810_reg_readb(dev, reg); - op1 = data8; - break; - case 7: /* Read-modify-write */ - if (operator) - op0 = ncr53c810_reg_readb(dev, reg); - if (insn & (1 << 23)) - op1 = dev->sfbr; - else - op1 = data8; - break; - } - - switch (operator) { - case 0: /* move */ - op0 = op1; - break; - case 1: /* Shift left */ - op1 = op0 >> 7; - op0 = (op0 << 1) | dev->carry; - dev->carry = op1; - break; - case 2: /* OR */ - op0 |= op1; - break; - case 3: /* XOR */ - op0 ^= op1; - break; - case 4: /* AND */ - op0 &= op1; - break; - case 5: /* SHR */ - op1 = op0 & 1; - op0 = (op0 >> 1) | (dev->carry << 7); - dev->carry = op1; - break; - case 6: /* ADD */ - op0 += op1; - dev->carry = op0 < op1; - break; - case 7: /* ADC */ - op0 += op1 + dev->carry; - if (dev->carry) - dev->carry = op0 <= op1; - else - dev->carry = op0 < op1; - break; - } - - switch (opcode) { - case 5: /* From SFBR */ - case 7: /* Read-modify-write */ - ncr53c810_reg_writeb(dev, reg, op0); - break; - case 6: /* To SFBR */ - dev->sfbr = op0; - break; - } - } - break; - - case 2: /* Transfer Control. */ - ncr53c810_log("02: Transfer Control\n"); - if ((insn & 0x002e0000) == 0) { - ncr53c810_log("NOP\n"); - break; - } - if (dev->sist1 & NCR_SIST1_STO) { - ncr53c810_log("Delayed select timeout\n"); - dev->sstop = 1; - break; - } - cond = jmp = (insn & (1 << 19)) != 0; - if (cond == jmp && (insn & (1 << 21))) { - ncr53c810_log("Compare carry %d\n", dev->carry == jmp); - cond = dev->carry != 0; - } - if (cond == jmp && (insn & (1 << 17))) { - ncr53c810_log("Compare phase %d %c= %d\n", (dev->sstat1 & PHASE_MASK), - jmp ? '=' : '!', ((insn >> 24) & 7)); - cond = (dev->sstat1 & PHASE_MASK) == ((insn >> 24) & 7); - } - if (cond == jmp && (insn & (1 << 18))) { - mask = (~insn >> 8) & 0xff; - ncr53c810_log("Compare data 0x%x & 0x%x %c= 0x%x\n", dev->sfbr, mask, - jmp ? '=' : '!', insn & mask); - cond = (dev->sfbr & mask) == (insn & mask); - } - if (cond == jmp) { - if (insn & (1 << 23)) { - /* Relative address. */ - addr = dev->dsp + sextract32(addr, 0, 24); - } - switch ((insn >> 27) & 7) { - case 0: /* Jump */ - ncr53c810_log("Jump to 0x%08x\n", addr); - dev->adder = addr; - dev->dsp = addr; - break; - case 1: /* Call */ - ncr53c810_log("Call 0x%08x\n", addr); - dev->temp = dev->dsp; - dev->dsp = addr; - break; - case 2: /* Return */ - ncr53c810_log("Return to 0x%08x\n", dev->temp); - dev->dsp = dev->temp; - break; - case 3: /* Interrupt */ - ncr53c810_log("Interrupt 0x%08x\n", dev->dsps); - if ((insn & (1 << 20)) != 0) { - dev->istat |= NCR_ISTAT_INTF; - ncr53c810_update_irq(dev); - } else - ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_SIR); - break; - default: - ncr53c810_log("Illegal transfer control\n"); - ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_IID); - break; - } - } else - ncr53c810_log("Control condition failed\n"); - break; - - case 3: - ncr53c810_log("00: Memory move\n"); - if ((insn & (1 << 29)) == 0) { - /* Memory move. */ - /* ??? The docs imply the destination address is loaded into - the TEMP register. However the Linux drivers rely on - the value being presrved. */ - dest = read_dword(dev, dev->dsp); - dev->dsp += 4; - ncr53c810_memcpy(dev, dest, addr, insn & 0xffffff); - } else { - pp = data; - - if (insn & (1 << 28)) - addr = dev->dsa + sextract32(addr, 0, 24); - n = (insn & 7); - reg = (insn >> 16) & 0xff; - if (insn & (1 << 24)) { - DMAPageRead(addr, data, n); - ncr53c810_log("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n, addr, - *(unsigned *)pp); - for (i = 0; i < n; i++) - ncr53c810_reg_writeb(dev, reg + i, data[i]); - } else { - ncr53c810_log("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr); - for (i = 0; i < n; i++) - data[i] = ncr53c810_reg_readb(dev, reg + i); - DMAPageWrite(addr, data, n); - } - } - break; - - default: - ncr53c810_log("%02X: Unknown command\n", (uint8_t) (insn >> 30)); - } - - dev->timer_period += (40LL * TIMER_USEC); - - ncr53c810_log("instructions processed %i\n", insn_processed); - if (insn_processed > 10000 && !dev->waiting) { - /* Some windows drivers make the device spin waiting for a memory - location to change. If we have been executed a lot of code then - assume this is the case and force an unexpected device disconnect. - This is apparently sufficient to beat the drivers into submission. - */ - ncr53c810_log("Some windows drivers make the device spin...\n"); - if (!(dev->sien0 & NCR_SIST0_UDC)) - ncr53c810_log("inf. loop with UDC masked\n"); - ncr53c810_script_scsi_interrupt(dev, NCR_SIST0_UDC, 0); - ncr53c810_disconnect(dev); - } else if (!dev->sstop && !dev->waiting) { - if (dev->dcntl & NCR_DCNTL_SSM) { - ncr53c810_log("NCR 810: SCRIPTS: Single-step mode\n"); - ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_SSI); - } else { - ncr53c810_log("NCR 810: SCRIPTS: Normal mode\n"); - if (insn_processed < 100) - goto again; - } - } else { - if (dev->sstop) - ncr53c810_log("NCR 810: SCRIPTS: Stopped\n"); - if (dev->waiting) - ncr53c810_log("NCR 810: SCRIPTS: Waiting\n"); - } - - ncr53c810_log("SCRIPTS execution stopped\n"); -} - - -static void -ncr53c810_execute_script(ncr53c810_t *dev) -{ - dev->sstop = 0; - dev->timer_period = 40LL * TIMER_USEC; - dev->timer_enabled = 1; -} - - -static void -ncr53c810_callback(void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *) p; - - dev->timer_period = 0; - if (!dev->sstop) { - if (dev->waiting) - dev->timer_period = 40LL * TIMER_USEC; - else - ncr53c810_process_script(dev); - } - - if (dev->sstop) { - dev->timer_enabled = 0; - dev->timer_period = 0; - } else - dev->timer_enabled = 1; -} - - -static void -ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val) -{ - uint8_t tmp = 0; - -#define CASE_SET_REG24(name, addr) \ - case addr : dev->name &= 0xffffff00; dev->name |= val; break; \ - case addr + 1: dev->name &= 0xffff00ff; dev->name |= val << 8; break; \ - case addr + 2: dev->name &= 0xff00ffff; dev->name |= val << 16; break; - -#define CASE_SET_REG32(name, addr) \ - case addr : dev->name &= 0xffffff00; dev->name |= val; break; \ - case addr + 1: dev->name &= 0xffff00ff; dev->name |= val << 8; break; \ - case addr + 2: dev->name &= 0xff00ffff; dev->name |= val << 16; break; \ - case addr + 3: dev->name &= 0x00ffffff; dev->name |= val << 24; break; - -#ifdef DEBUG_NCR_REG - ncr53c810_log("Write reg %02x = %02x\n", offset, val); -#endif - - dev->regop = 1; - - switch (offset) { - case 0x00: /* SCNTL0 */ - dev->scntl0 = val; - if (val & NCR_SCNTL0_START) { - /* Looks like this (turn on bit 4 of SSTAT0 to mark arbitration in progress) - is enough to make BIOS v4.x happy. */ - ncr53c810_log("NCR 810: Selecting SCSI ID %i\n", dev->sdid); - dev->select_id = dev->sdid; - dev->sstat0 |= 0x10; - } - break; - case 0x01: /* SCNTL1 */ - dev->scntl1 = val & ~NCR_SCNTL1_SST; - if (val & NCR_SCNTL1_IARB) { - dev->select_id = dev->sdid; - ncr53c810_log("Arbitration lost\n"); - dev->sstat0 |= 0x08; - dev->waiting = 0; - } - if (val & NCR_SCNTL1_RST) { - if (!(dev->sstat0 & NCR_SSTAT0_RST)) { - dev->sstat0 |= NCR_SSTAT0_RST; - ncr53c810_script_scsi_interrupt(dev, NCR_SIST0_RST, 0); - } - } else - dev->sstat0 &= ~NCR_SSTAT0_RST; - break; - case 0x02: /* SCNTL2 */ - val &= ~(NCR_SCNTL2_WSR | NCR_SCNTL2_WSS); - dev->scntl2 = val; - break; - case 0x03: /* SCNTL3 */ - dev->scntl3 = val; - break; - case 0x04: /* SCID */ - dev->scid = val; - break; - case 0x05: /* SXFER */ - dev->sxfer = val; - break; - case 0x06: /* SDID */ - if ((dev->ssid & 0x80) && (val & 0xf) != (dev->ssid & 0xf)) - ncr53c810_log("Destination ID does not match SSID\n"); - dev->sdid = val & 0xf; - break; - case 0x07: /* GPREG0 */ - ncr53c810_log("NCR 810: GPREG0 write %02X\n", val); - dev->gpreg0 = val & 0x03; - break; - case 0x08: /* SFBR */ - /* The CPU is not allowed to write to this register. However the - SCRIPTS register move instructions are. */ - dev->sfbr = val; - break; - case 0x09: /* SOCL */ - ncr53c810_log("NCR 810: SOCL write %02X\n", val); - dev->socl = val; - break; - case 0x0a: case 0x0b: - /* Openserver writes to these readonly registers on startup */ - return; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - /* Linux writes to these readonly registers on startup. */ - return; - CASE_SET_REG32(dsa, 0x10) - case 0x14: /* ISTAT */ - ncr53c810_log("ISTAT write: %02X\n", val); - tmp = dev->istat; - dev->istat = (dev->istat & 0x0f) | (val & 0xf0); - if ((val & NCR_ISTAT_ABRT) && !(val & NCR_ISTAT_SRST)) - ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_ABRT); - if (val & NCR_ISTAT_INTF) { - dev->istat &= ~NCR_ISTAT_INTF; - ncr53c810_update_irq(dev); - } - - if ((dev->waiting == 1) && (val & NCR_ISTAT_SIGP)) { - ncr53c810_log("Woken by SIGP\n"); - dev->waiting = 0; - dev->dsp = dev->dnad; - /* ncr53c810_execute_script(dev); */ - } - if ((val & NCR_ISTAT_SRST) && !(tmp & NCR_ISTAT_SRST)) { - ncr53c810_soft_reset(dev); - ncr53c810_update_irq(dev); - dev->istat = 0; - } - break; - case 0x16: /* MBOX0 */ - dev->mbox0 = val; - break; - case 0x17: /* MBOX1 */ - dev->mbox1 = val; - break; - case 0x18: /* CTEST0 */ - /* nothing to do */ - break; - case 0x19: /* CTEST1 */ - /* nothing to do */ - break; - case 0x1a: /* CTEST2 */ - dev->ctest2 = val & NCR_CTEST2_PCICIE; - break; - case 0x1b: /* CTEST3 */ - dev->ctest3 = val & 0x0f; - break; - CASE_SET_REG32(temp, 0x1c) - case 0x21: /* CTEST4 */ - if (val & 7) - ncr53c810_log("Unimplemented CTEST4-FBL 0x%x\n", val); - dev->ctest4 = val; - break; - case 0x22: /* CTEST5 */ - if (val & (NCR_CTEST5_ADCK | NCR_CTEST5_BBCK)) - ncr53c810_log("CTEST5 DMA increment not implemented\n"); - dev->ctest5 = val; - break; - CASE_SET_REG24(dbc, 0x24) - CASE_SET_REG32(dnad, 0x28) - case 0x2c: /* DSP[0:7] */ - dev->dsp &= 0xffffff00; - dev->dsp |= val; - break; - case 0x2d: /* DSP[8:15] */ - dev->dsp &= 0xffff00ff; - dev->dsp |= val << 8; - break; - case 0x2e: /* DSP[16:23] */ - dev->dsp &= 0xff00ffff; - dev->dsp |= val << 16; - break; - case 0x2f: /* DSP[24:31] */ - dev->dsp &= 0x00ffffff; - dev->dsp |= val << 24; - if (!(dev->dmode & NCR_DMODE_MAN) && dev->sstop) - ncr53c810_execute_script(dev); - break; - CASE_SET_REG32(dsps, 0x30) - CASE_SET_REG32(scratcha, 0x34) - case 0x38: /* DMODE */ - dev->dmode = val; - break; - case 0x39: /* DIEN */ - ncr53c810_log("DIEN write: %02X\n", val); - dev->dien = val; - ncr53c810_update_irq(dev); - break; - case 0x3a: /* SBR */ - dev->sbr = val; - break; - case 0x3b: /* DCNTL */ - dev->dcntl = val & ~(NCR_DCNTL_PFF | NCR_DCNTL_STD); - if ((val & NCR_DCNTL_STD) && dev->sstop) - ncr53c810_execute_script(dev); - break; - case 0x40: /* SIEN0 */ - dev->sien0 = val; - ncr53c810_update_irq(dev); - break; - case 0x41: /* SIEN1 */ - dev->sien1 = val; - ncr53c810_update_irq(dev); - break; - case 0x47: /* GPCNTL0 */ - break; - case 0x48: /* STIME0 */ - dev->stime0 = val; - break; - case 0x49: /* STIME1 */ - if (val & 0xf) { - ncr53c810_log("General purpose timer not implemented\n"); - /* ??? Raising the interrupt immediately seems to be sufficient - to keep the FreeBSD driver happy. */ - ncr53c810_script_scsi_interrupt(dev, 0, NCR_SIST1_GEN); - } - break; - case 0x4a: /* RESPID */ - dev->respid = val; - break; - case 0x4d: /* STEST1 */ - dev->stest1 = val; - break; - case 0x4e: /* STEST2 */ - if (val & 1) - ncr53c810_log("Low level mode not implemented\n"); - dev->stest2 = val; - break; - case 0x4f: /* STEST3 */ - if (val & 0x41) - ncr53c810_log("SCSI FIFO test mode not implemented\n"); - dev->stest3 = val; - break; - case 0x54: - break; - CASE_SET_REG32(scratchb, 0x5c) - default: - ncr53c810_log("Unhandled writeb 0x%x = 0x%x\n", offset, val); - } -#undef CASE_SET_REG24 -#undef CASE_SET_REG32 -} - - -static uint8_t -ncr53c810_reg_readb(ncr53c810_t *dev, uint32_t offset) -{ - uint8_t tmp; -#define CASE_GET_REG24(name, addr) \ - case addr: return dev->name & 0xff; \ - case addr + 1: return (dev->name >> 8) & 0xff; \ - case addr + 2: return (dev->name >> 16) & 0xff; - -#define CASE_GET_REG32(name, addr) \ - case addr: return dev->name & 0xff; \ - case addr + 1: return (dev->name >> 8) & 0xff; \ - case addr + 2: return (dev->name >> 16) & 0xff; \ - case addr + 3: return (dev->name >> 24) & 0xff; - - dev->regop = 1; - - switch (offset) { - case 0x00: /* SCNTL0 */ - ncr53c810_log("NCR 810: Read SCNTL0 %02X\n", dev->scntl0); - return dev->scntl0; - case 0x01: /* SCNTL1 */ - ncr53c810_log("NCR 810: Read SCNTL1 %02X\n", dev->scntl1); - return dev->scntl1; - case 0x02: /* SCNTL2 */ - ncr53c810_log("NCR 810: Read SCNTL2 %02X\n", dev->scntl2); - return dev->scntl2; - case 0x03: /* SCNTL3 */ - ncr53c810_log("NCR 810: Read SCNTL3 %02X\n", dev->scntl3); - return dev->scntl3; - case 0x04: /* SCID */ - ncr53c810_log("NCR 810: Read SCID %02X\n", dev->scid); - return dev->scid; - case 0x05: /* SXFER */ - ncr53c810_log("NCR 810: Read SXFER %02X\n", dev->sxfer); - return dev->sxfer; - case 0x06: /* SDID */ - ncr53c810_log("NCR 810: Read SDID %02X\n", dev->sdid); - return dev->sdid; - case 0x07: /* GPREG0 */ - ncr53c810_log("NCR 810: Read GPREG0 %02X\n", dev->gpreg0 & 3); - return dev->gpreg0 & 3; - case 0x08: /* Revision ID */ - ncr53c810_log("NCR 810: Read REVID 00\n"); - return 0x00; - case 0xa: /* SSID */ - ncr53c810_log("NCR 810: Read SSID %02X\n", dev->ssid); - return dev->ssid; - case 0xb: /* SBCL */ - /* Bit 7 = REQ (SREQ/ status) - Bit 6 = ACK (SACK/ status) - Bit 5 = BSY (SBSY/ status) - Bit 4 = SEL (SSEL/ status) - Bit 3 = ATN (SATN/ status) - Bit 2 = MSG (SMSG/ status) - Bit 1 = C/D (SC_D/ status) - Bit 0 = I/O (SI_O/ status) */ - tmp = (dev->sstat1 & 7); - ncr53c810_log("NCR 810: Read SBCL %02X\n", tmp); - return tmp; /* For now, return the MSG, C/D, and I/O bits from SSTAT1. */ - case 0xc: /* DSTAT */ - tmp = dev->dstat | NCR_DSTAT_DFE; - if ((dev->istat & NCR_ISTAT_INTF) == 0) - dev->dstat = 0; - ncr53c810_update_irq(dev); - ncr53c810_log("NCR 810: Read DSTAT %02X\n", tmp); - return tmp; - case 0x0d: /* SSTAT0 */ - ncr53c810_log("NCR 810: Read SSTAT0 %02X\n", dev->sstat0); - return dev->sstat0; - case 0x0e: /* SSTAT1 */ - ncr53c810_log("NCR 810: Read SSTAT1 %02X\n", dev->sstat1); - return dev->sstat1; - case 0x0f: /* SSTAT2 */ - ncr53c810_log("NCR 810: Read SSTAT2 %02X\n", dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2); - return dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2; - CASE_GET_REG32(dsa, 0x10) - case 0x14: /* ISTAT */ - ncr53c810_log("NCR 810: Read ISTAT %02X\n", dev->istat); - tmp = dev->istat; - return tmp; - case 0x16: /* MBOX0 */ - ncr53c810_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0); - return dev->mbox0; - case 0x17: /* MBOX1 */ - ncr53c810_log("NCR 810: Read MBOX1 %02X\n", dev->mbox1); - return dev->mbox1; - case 0x18: /* CTEST0 */ - ncr53c810_log("NCR 810: Read CTEST0 FF\n"); - return 0xff; - case 0x19: /* CTEST1 */ - ncr53c810_log("NCR 810: Read CTEST1 F0\n"); - return 0xf0; /* dma fifo empty */ - case 0x1a: /* CTEST2 */ - tmp = dev->ctest2 | NCR_CTEST2_DACK | NCR_CTEST2_CM; - if (dev->istat & NCR_ISTAT_SIGP) { - dev->istat &= ~NCR_ISTAT_SIGP; - tmp |= NCR_CTEST2_SIGP; - } - ncr53c810_log("NCR 810: Read CTEST2 %02X\n", tmp); - return tmp; - case 0x1b: /* CTEST3 */ - ncr53c810_log("NCR 810: Read CTEST3 %02X\n", - (dev->ctest3 & (0x08 | 0x02 | 0x01)) | dev->chip_rev); - return (dev->ctest3 & (0x08 | 0x02 | 0x01)) | dev->chip_rev; - CASE_GET_REG32(temp, 0x1c) - case 0x20: /* DFIFO */ - ncr53c810_log("NCR 810: Read DFIFO 00\n"); - return 0; - case 0x21: /* CTEST4 */ - ncr53c810_log("NCR 810: Read CTEST4 %02X\n", dev->ctest4); - return dev->ctest4; - case 0x22: /* CTEST5 */ - ncr53c810_log("NCR 810: Read CTEST5 %02X\n", dev->ctest5); - return dev->ctest5; - case 0x23: /* CTEST6 */ - ncr53c810_log("NCR 810: Read CTEST6 00\n"); - return 0; - CASE_GET_REG24(dbc, 0x24) - case 0x27: /* DCMD */ - ncr53c810_log("NCR 810: Read DCMD %02X\n", dev->dcmd); - return dev->dcmd; - CASE_GET_REG32(dnad, 0x28) - CASE_GET_REG32(dsp, 0x2c) - CASE_GET_REG32(dsps, 0x30) - CASE_GET_REG32(scratcha, 0x34) - case 0x38: /* DMODE */ - ncr53c810_log("NCR 810: Read DMODE %02X\n", dev->dmode); - return dev->dmode; - case 0x39: /* DIEN */ - ncr53c810_log("NCR 810: Read DIEN %02X\n", dev->dien); - return dev->dien; - case 0x3a: /* SBR */ - ncr53c810_log("NCR 810: Read SBR %02X\n", dev->sbr); - return dev->sbr; - case 0x3b: /* DCNTL */ - ncr53c810_log("NCR 810: Read DCNTL %02X\n", dev->dcntl); - return dev->dcntl; - CASE_GET_REG32(adder, 0x3c) /* ADDER Output (Debug of relative jump address) */ - case 0x40: /* SIEN0 */ - ncr53c810_log("NCR 810: Read SIEN0 %02X\n", dev->sien0); - return dev->sien0; - case 0x41: /* SIEN1 */ - ncr53c810_log("NCR 810: Read SIEN1 %02X\n", dev->sien1); - return dev->sien1; - case 0x42: /* SIST0 */ - tmp = dev->sist0; - dev->sist0 = 0; - ncr53c810_update_irq(dev); - ncr53c810_log("NCR 810: Read SIST0 %02X\n", tmp); - return tmp; - case 0x43: /* SIST1 */ - tmp = dev->sist1; - dev->sist1 = 0; - ncr53c810_update_irq(dev); - ncr53c810_log("NCR 810: Read SIST1 %02X\n", tmp); - return tmp; - case 0x46: /* MACNTL */ - ncr53c810_log("NCR 810: Read MACNTL 4F\n"); - return 0x4f; - case 0x47: /* GPCNTL0 */ - ncr53c810_log("NCR 810: Read GPCNTL0 0F\n"); - return 0x0f; - case 0x48: /* STIME0 */ - ncr53c810_log("NCR 810: Read STIME0 %02X\n", dev->stime0); - return dev->stime0; - case 0x4a: /* RESPID */ - ncr53c810_log("NCR 810: Read RESPID %02X\n", dev->respid); - return dev->respid; - case 0x4c: /* STEST0 */ - ncr53c810_log("NCR 810: Read STEST0 %02X\n", dev->stest1); - return 0x00; - case 0x4d: /* STEST1 */ - ncr53c810_log("NCR 810: Read STEST1 %02X\n", dev->stest1); - return dev->stest1; - case 0x4e: /* STEST2 */ - ncr53c810_log("NCR 810: Read STEST2 %02X\n", dev->stest2); - return dev->stest2; - case 0x4f: /* STEST3 */ - ncr53c810_log("NCR 810: Read STEST3 %02X\n", dev->stest3); - return dev->stest3; - case 0x50: /* SIDL */ - /* This is needed by the linux drivers. We currently only update it - during the MSG IN phase. */ - ncr53c810_log("NCR 810: Read SIDL %02X\n", dev->sidl); - return dev->sidl; - case 0x52: /* STEST4 */ - ncr53c810_log("NCR 810: Read STEST4 E0\n"); - return 0xe0; - case 0x58: /* SBDL */ - /* Some drivers peek at the data bus during the MSG IN phase. */ - if ((dev->sstat1 & PHASE_MASK) == PHASE_MI) { - ncr53c810_log("NCR 810: Read SBDL %02X\n", dev->msg[0]); - return dev->msg[0]; - } - ncr53c810_log("NCR 810: Read SBDL 00\n"); - return 0; - case 0x59: /* SBDL high */ - ncr53c810_log("NCR 810: Read SBDLH 00\n"); - return 0; - CASE_GET_REG32(scratchb, 0x5c) - } - ncr53c810_log("readb 0x%x\n", offset); - return 0; - -#undef CASE_GET_REG24 -#undef CASE_GET_REG32 -} - - -static uint8_t -ncr53c810_io_readb(uint16_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - return ncr53c810_reg_readb(dev, addr & 0xff); -} - - -static uint16_t -ncr53c810_io_readw(uint16_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - uint16_t val; - - addr &= 0xff; - val = ncr53c810_reg_readb(dev, addr); - val |= ncr53c810_reg_readb(dev, addr + 1) << 8; - return val; -} - - -static uint32_t -ncr53c810_io_readl(uint16_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - uint32_t val; - - addr &= 0xff; - val = ncr53c810_reg_readb(dev, addr); - val |= ncr53c810_reg_readb(dev, addr + 1) << 8; - val |= ncr53c810_reg_readb(dev, addr + 2) << 16; - val |= ncr53c810_reg_readb(dev, addr + 3) << 24; - return val; -} - - -static void -ncr53c810_io_writeb(uint16_t addr, uint8_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - ncr53c810_reg_writeb(dev, addr & 0xff, val); -} - - -static void -ncr53c810_io_writew(uint16_t addr, uint16_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - addr &= 0xff; - ncr53c810_reg_writeb(dev, addr, val & 0xff); - ncr53c810_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); -} - - -static void -ncr53c810_io_writel(uint16_t addr, uint32_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - addr &= 0xff; - ncr53c810_reg_writeb(dev, addr, val & 0xff); - ncr53c810_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); - ncr53c810_reg_writeb(dev, addr + 2, (val >> 16) & 0xff); - ncr53c810_reg_writeb(dev, addr + 3, (val >> 24) & 0xff); -} - - -static void -ncr53c810_mmio_writeb(uint32_t addr, uint8_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - - ncr53c810_reg_writeb(dev, addr & 0xff, val); -} - - -static void -ncr53c810_mmio_writew(uint32_t addr, uint16_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - - addr &= 0xff; - ncr53c810_reg_writeb(dev, addr, val & 0xff); - ncr53c810_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); -} - - -static void -ncr53c810_mmio_writel(uint32_t addr, uint32_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - - addr &= 0xff; - ncr53c810_reg_writeb(dev, addr, val & 0xff); - ncr53c810_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); - ncr53c810_reg_writeb(dev, addr + 2, (val >> 16) & 0xff); - ncr53c810_reg_writeb(dev, addr + 3, (val >> 24) & 0xff); -} - - -static uint8_t -ncr53c810_mmio_readb(uint32_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - - return ncr53c810_reg_readb(dev, addr & 0xff); -} - - -static uint16_t -ncr53c810_mmio_readw(uint32_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - uint16_t val; - - addr &= 0xff; - val = ncr53c810_reg_readb(dev, addr); - val |= ncr53c810_reg_readb(dev, addr + 1) << 8; - return val; -} - - -static uint32_t -ncr53c810_mmio_readl(uint32_t addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - uint32_t val; - - addr &= 0xff; - val = ncr53c810_reg_readb(dev, addr); - val |= ncr53c810_reg_readb(dev, addr + 1) << 8; - val |= ncr53c810_reg_readb(dev, addr + 2) << 16; - val |= ncr53c810_reg_readb(dev, addr + 3) << 24; - return val; -} - - -static void -ncr53c810_io_set(ncr53c810_t *dev, uint32_t base, uint16_t len) -{ - ncr53c810_log("NCR53c810: [PCI] Setting I/O handler at %04X\n", base); - io_sethandler(base, len, - ncr53c810_io_readb, ncr53c810_io_readw, ncr53c810_io_readl, - ncr53c810_io_writeb, ncr53c810_io_writew, ncr53c810_io_writel, dev); -} - - -static void -ncr53c810_io_remove(ncr53c810_t *dev, uint32_t base, uint16_t len) -{ - ncr53c810_log("NCR53c810: Removing I/O handler at %04X\n", base); - io_removehandler(base, len, - ncr53c810_io_readb, ncr53c810_io_readw, ncr53c810_io_readl, - ncr53c810_io_writeb, ncr53c810_io_writew, ncr53c810_io_writel, dev); -} - - -static void -ncr53c810_mem_init(ncr53c810_t *dev, uint32_t addr) -{ - mem_mapping_add(&dev->mmio_mapping, addr, 0x100, - ncr53c810_mmio_readb, ncr53c810_mmio_readw, ncr53c810_mmio_readl, - ncr53c810_mmio_writeb, ncr53c810_mmio_writew, ncr53c810_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); -} - - -static void -ncr53c810_mem_set_addr(ncr53c810_t *dev, uint32_t base) -{ - mem_mapping_set_addr(&dev->mmio_mapping, base, 0x100); -} - - -static void -ncr53c810_mem_disable(ncr53c810_t *dev) -{ - mem_mapping_disable(&dev->mmio_mapping); -} - - -uint8_t ncr53c810_pci_regs[256]; -bar_t ncr53c810_pci_bar[2]; - - -static uint8_t -ncr53c810_pci_read(int func, int addr, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - - ncr53c810_log("NCR53c810: Reading register %02X\n", addr & 0xff); - - if ((addr >= 0x80) && (addr <= 0xDF)) - return ncr53c810_reg_readb(dev, addr & 0x7F); - - switch (addr) { - case 0x00: - return 0x00; - case 0x01: - return 0x10; - case 0x02: - return 0x01; - case 0x03: - return 0x00; - case 0x04: - return ncr53c810_pci_regs[0x04] & 0x57; /*Respond to IO and memory accesses*/ - case 0x05: - return ncr53c810_pci_regs[0x05] & 0x01; - case 0x07: - return 2; - case 0x08: - return 0x10; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*devubclass*/ - case 0x0B: - return 1; /*Class code*/ - case 0x0C: - case 0x0D: - return ncr53c810_pci_regs[addr]; - case 0x0E: - return 0; /*Header type */ - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return ncr53c810_pci_bar[0].addr_regs[1]; - case 0x12: - return ncr53c810_pci_bar[0].addr_regs[2]; - case 0x13: - return ncr53c810_pci_bar[0].addr_regs[3]; - case 0x14: - return 0; /*Memory space*/ - case 0x15: - return ncr53c810_pci_bar[1].addr_regs[1]; - case 0x16: - return ncr53c810_pci_bar[1].addr_regs[2]; - case 0x17: - return ncr53c810_pci_bar[1].addr_regs[3]; - case 0x2C: - return 0x00; - case 0x2D: - return 0x10; - case 0x2E: - return 0x01; - case 0x2F: - return 0x00; - case 0x3C: - return dev->irq; - case 0x3D: - return PCI_INTA; - case 0x3E: - return 0x11; - case 0x3F: - return 0x40; - } - - return(0); -} - - -static void -ncr53c810_pci_write(int func, int addr, uint8_t val, void *p) -{ - ncr53c810_t *dev = (ncr53c810_t *)p; - uint8_t valxor; - - ncr53c810_log("NCR53c810: Write value %02X to register %02X\n", val, addr & 0xff); - - if ((addr >= 0x80) && (addr <= 0xDF)) { - ncr53c810_reg_writeb(dev, addr & 0x7F, val); - return; - } - - switch (addr) - { - case 0x04: - valxor = (val & 0x57) ^ ncr53c810_pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) { - ncr53c810_io_remove(dev, dev->PCIBase, 0x0100); - if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) { - ncr53c810_io_set(dev, dev->PCIBase, 0x0100); - } - } - if (valxor & PCI_COMMAND_MEM) { - ncr53c810_mem_disable(dev); - if ((dev->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) { - ncr53c810_mem_set_addr(dev, dev->MMIOBase); - } - } - ncr53c810_pci_regs[addr] = val & 0x57; - break; - - case 0x05: - ncr53c810_pci_regs[addr] = val & 0x01; - break; - - case 0x0C: - case 0x0D: - ncr53c810_pci_regs[addr] = val; - break; - - case 0x10: case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - ncr53c810_io_remove(dev, dev->PCIBase, 0x0100); - /* Then let's set the PCI regs. */ - ncr53c810_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ncr53c810_pci_bar[0].addr &= 0xff00; - dev->PCIBase = ncr53c810_pci_bar[0].addr; - /* Log the new base. */ - ncr53c810_log("NCR53c810: New I/O base is %04X\n" , dev->PCIBase); - /* We're done, so get out of the here. */ - if (ncr53c810_pci_regs[4] & PCI_COMMAND_IO) { - if (dev->PCIBase != 0) { - ncr53c810_io_set(dev, dev->PCIBase, 0x0100); - } - } - return; - - case 0x15: case 0x16: case 0x17: - /* MMIO Base set. */ - /* First, remove the old I/O. */ - ncr53c810_mem_disable(dev); - /* Then let's set the PCI regs. */ - ncr53c810_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - dev->MMIOBase = ncr53c810_pci_bar[1].addr & 0xffffff00; - /* Log the new base. */ - ncr53c810_log("NCR53c810: New MMIO base is %08X\n" , dev->MMIOBase); - /* We're done, so get out of the here. */ - if (ncr53c810_pci_regs[4] & PCI_COMMAND_MEM) { - if (dev->MMIOBase != 0) { - ncr53c810_mem_set_addr(dev, dev->MMIOBase); - } - } - return; - - case 0x3C: - ncr53c810_pci_regs[addr] = val; - dev->irq = val; - return; - } -} - - -static void * -ncr53c810_init(const device_t *info) -{ - ncr53c810_t *dev; - - dev = malloc(sizeof(ncr53c810_t)); - memset(dev, 0x00, sizeof(ncr53c810_t)); - - dev->chip_rev = 0; - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c810_pci_read, ncr53c810_pci_write, dev); - - ncr53c810_pci_bar[0].addr_regs[0] = 1; - ncr53c810_pci_bar[1].addr_regs[0] = 0; - ncr53c810_pci_regs[0x04] = 3; - - ncr53c810_mem_init(dev, 0x0fffff00); - ncr53c810_mem_disable(dev); - - ncr53c810_soft_reset(dev); - - timer_add(ncr53c810_callback, &dev->timer_period, &dev->timer_enabled, dev); - - dev->has_bios = device_get_config_int("bios"); - - /* Enable our BIOS space in PCI, if needed. */ - if (dev->has_bios) - rom_init(&dev->bios, NCR53C810_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - return(dev); -} - - -static void -ncr53c810_close(void *priv) -{ - ncr53c810_t *dev = (ncr53c810_t *)priv; - - if (dev) { - free(dev); - dev = NULL; - } -} - - -static const device_config_t ncr53c810_pci_config[] = { - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } -}; - - -const device_t ncr53c810_pci_device = -{ - "NCR 53c810 (SCSI)", - DEVICE_PCI, - 0, - ncr53c810_init, ncr53c810_close, NULL, - NULL, NULL, NULL, - ncr53c810_pci_config -}; diff --git a/src - Cópia/scsi/scsi_ncr53c810.h b/src - Cópia/scsi/scsi_ncr53c810.h deleted file mode 100644 index 29666e935..000000000 --- a/src - Cópia/scsi/scsi_ncr53c810.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the NCR 53C810 SCSI Host Adapter made by - * NCR and later Symbios and LSI. This controller was designed - * for the PCI bus. - * - * Version: @(#)scsi_ncr53c810.c 1.0.1 2018/03/18 - * - * Authors: TheCollector1995, - * Miran Grca, - * Paul Brook (QEMU), - * Artyom Tarasenko (QEMU), - * - * Copyright 2006-2018 Paul Brook. - * Copyright 2009-2018 Artyom Tarasenko. - * Copyright 2017,2018 Miran Grca. - */ -#ifndef SCSI_NCR5C3810_H -# define SCSI_NCR53C810_H - - -extern const device_t ncr53c810_pci_device; - - -#endif /*SCSI_NCR53C810_H*/ diff --git a/src - Cópia/scsi/scsi_x54x.c b/src - Cópia/scsi/scsi_x54x.c deleted file mode 100644 index 13f8e37f4..000000000 --- a/src - Cópia/scsi/scsi_x54x.c +++ /dev/null @@ -1,1986 +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. - * - * Implementation of the code common to the AHA-154x series of - * SCSI Host Adapters made by Adaptec, Inc. and the BusLogic - * series of SCSI Host Adapters made by Mylex. - * These controllers were designed for various buses. - * - * Version: @(#)scsi_x54x.c 1.0.21 2018/03/28 - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.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 "../timer.h" -#include "../plat.h" -#include "../cpu/cpu.h" -#include "scsi.h" -#include "scsi_device.h" -#include "scsi_aha154x.h" -#include "scsi_x54x.h" - - -#define X54X_RESET_DURATION_US UINT64_C(50000) - - -static void x54x_cmd_callback(void *priv); - -static volatile -x54x_t *x54x_dev; - - -#ifdef ENABLE_X54X_LOG -int x54x_do_log = ENABLE_X54X_LOG; -#endif - - -static void -x54x_log(const char *fmt, ...) -{ -#ifdef ENABLE_X54X_LOG - va_list ap; - - if (x54x_do_log) { - pclog("In %s mode: ",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -x54x_irq(x54x_t *dev, int set) -{ - int int_type = 0; - int irq; - - if (dev->ven_get_irq) - irq = dev->ven_get_irq(dev); - else - irq = dev->Irq; - - if (dev->bus & DEVICE_PCI) { - x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); - if (set) { - pci_set_irq(dev->pci_slot, PCI_INTA); - } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); - } - } else { - if (set) { - if (dev->interrupt_type) - int_type = dev->interrupt_type(dev); - - if (int_type) { - picintlevel(1 << irq); - } else { - picint(1 << irq); - } - } else { - picintc(1 << irq); - } - } -} - - -static void -raise_irq(x54x_t *dev, int suppress, uint8_t Interrupt) -{ - if (Interrupt & (INTR_MBIF | INTR_MBOA)) { - if (! (dev->Interrupt & INTR_HACC)) { - dev->Interrupt |= Interrupt; /* Report now. */ - } else { - dev->PendingInterrupt |= Interrupt; /* Report later. */ - } - } else if (Interrupt & INTR_HACC) { - if (dev->Interrupt == 0 || dev->Interrupt == (INTR_ANY | INTR_HACC)) { - x54x_log("%s: RaiseInterrupt(): Interrupt=%02X\n", - dev->name, dev->Interrupt); - } - dev->Interrupt |= Interrupt; - } else { - x54x_log("%s: RaiseInterrupt(): Invalid interrupt state!\n", dev->name); - } - - dev->Interrupt |= INTR_ANY; - - if (dev->IrqEnabled && !suppress) - x54x_irq(dev, 1); -} - - -static void -clear_irq(x54x_t *dev) -{ - dev->Interrupt = 0; - x54x_log("%s: lowering IRQ %i (stat 0x%02x)\n", - dev->name, dev->Irq, dev->Interrupt); - x54x_irq(dev, 0); - if (dev->PendingInterrupt) { - x54x_log("%s: Raising Interrupt 0x%02X (Pending)\n", - dev->name, dev->Interrupt); - if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { - raise_irq(dev, 0, dev->PendingInterrupt); - } - dev->PendingInterrupt = 0; - } -} - - -static void -target_check(uint8_t id, uint8_t lun) -{ - if (! scsi_device_valid(id, lun)) { - fatal("BIOS INT13 device on %02i:%02i has disappeared\n", id, lun); - } -} - - -static uint8_t -completion_code(uint8_t *sense) -{ - switch (sense[12]) { - case 0x00: - return(0x00); - - case 0x20: - return(0x01); - - case 0x12: - case 0x21: - return(0x02); - - case 0x27: - return(0x03); - - case 0x14: - case 0x16: - return(0x04); - - case 0x10: - case 0x11: - return(0x10); - - case 0x17: - case 0x18: - return(0x11); - - case 0x01: - case 0x03: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - return(0x20); - - case 0x15: - case 0x02: - return(0x40); - - case 0x04: - case 0x28: - case 0x29: - case 0x2a: - return(0xaa); - - default: - break; - }; - - return(0xff); -} - - -static uint8_t -x54x_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer) -{ - uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; - uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; - uint32_t len = 0; - int i, ret, sc; - - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = completion_code(scsi_device_sense(id, lun)); - if (ret == 0) return(sc); - - memset(buffer, 0x00, 6); - for (i=0; i<4; i++) - buffer[i] = rcbuf[i]; - for (i=4; i<6; i++) - buffer[i] = rcbuf[(i + 2) ^ 1]; - x54x_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n", - buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); - - return(0); -} - - -static int -x54x_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer) -{ - uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; - uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; - uint32_t len = 0; - int i, ret, sc; - - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = completion_code(scsi_device_sense(id, lun)); - - memset(buffer, 0x00, 6); - for (i=0; i<4; i++) - buffer[i] = (ret == 0) ? 0 : rcbuf[i]; - - scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5])); - - x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", - buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); - - return(sc); -} - - -/* This returns the completion code. */ -static uint8_t -x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) -{ - uint8_t cdb[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; - scsi_device_t *dev; - uint32_t dma_address; - uint32_t lba; - int sector_len = cmd->secount; - uint8_t ret; - - if (islba) - lba = lba32_blk(cmd); - else - lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec; - - x54x_log("BIOS Command = 0x%02X\n", cmd->command); - - if ((cmd->id > max_id) || (cmd->lun > 7)) { - x54x_log("BIOS Target ID %i or LUN %i are above maximum\n", - cmd->id, cmd->lun); - return(0x80); - } - - /* Get pointer to selected device. */ - dev = &SCSIDevices[cmd->id][cmd->lun]; - dev->BufferLength = 0; - - if (! scsi_device_present(cmd->id, cmd->lun)) { - x54x_log("BIOS Target ID %i and LUN %i have no device attached\n", - cmd->id, cmd->lun); - return(0x80); - } - - if ((dev->LunType == SCSI_CDROM) && !x54x->cdrom_boot) { - x54x_log("BIOS Target ID %i and LUN %i is CD-ROM on unsupported BIOS\n", - cmd->id, cmd->lun); - return(0x80); - } - - dma_address = ADDR_TO_U32(cmd->dma_address); - - x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", - sector_len, dma_address); - - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - switch(cmd->command) { - case 0x00: /* Reset Disk System, in practice it's a nop */ - return(0); - - case 0x01: /* Read Status of Last Operation */ - target_check(cmd->id, cmd->lun); - - /* - * Assuming 14 bytes because that is the default - * length for SCSI sense, and no command-specific - * indication is given. - */ - dev->BufferLength = 14; - dev->CmdBuffer = (uint8_t *)malloc(14); - memset(dev->CmdBuffer, 0x00, 14); - - if (sector_len > 0) { - x54x_log("BIOS DMA: Reading 14 bytes at %08X\n", - dma_address); - DMAPageWrite(dma_address, - scsi_device_sense(cmd->id, cmd->lun), 14); - } - - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - return(0); - - case 0x02: /* Read Desired Sectors to Memory */ - target_check(cmd->id, cmd->lun); - - dev->BufferLength = -1; - - cdb[0] = GPCMD_READ_10; - cdb[1] = (cmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = 0; - cdb[8] = sector_len; -#if 0 - x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount); -#endif - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - if (dev->Phase == SCSI_PHASE_STATUS) - goto skip_read_phase1; - - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - - scsi_device_command_phase1(cmd->id, cmd->lun); - if (sector_len > 0) { - x54x_log("BIOS DMA: Reading %i bytes at %08X\n", - dev->BufferLength, dma_address); - DMAPageWrite(dma_address, - dev->CmdBuffer, dev->BufferLength); - } - -skip_read_phase1: - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x03: /* Write Desired Sectors from Memory */ - target_check(cmd->id, cmd->lun); - - dev->BufferLength = -1; - - cdb[0] = GPCMD_WRITE_10; - cdb[1] = (cmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = 0; - cdb[8] = sector_len; -#if 0 - x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount); -#endif - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - if (dev->Phase == SCSI_PHASE_STATUS) - goto skip_write_phase1; - - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - - if (sector_len > 0) { - x54x_log("BIOS DMA: Reading %i bytes at %08X\n", - dev->BufferLength, dma_address); - DMAPageRead(dma_address, - dev->CmdBuffer, dev->BufferLength); - } - - scsi_device_command_phase1(cmd->id, cmd->lun); - -skip_write_phase1: - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x04: /* Verify Desired Sectors */ - target_check(cmd->id, cmd->lun); - - cdb[0] = GPCMD_VERIFY_10; - cdb[1] = (cmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = 0; - cdb[8] = sector_len; - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x05: /* Format Track, invalid since SCSI has no tracks */ -//FIXME: add a longer delay here --FvK - return(1); - - case 0x06: /* Identify SCSI Devices, in practice it's a nop */ -//FIXME: add a longer delay here --FvK - return(0); - - case 0x07: /* Format Unit */ - target_check(cmd->id, cmd->lun); - - cdb[0] = GPCMD_FORMAT_UNIT; - cdb[1] = (cmd->lun & 7) << 5; - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x08: /* Read Drive Parameters */ - target_check(cmd->id, cmd->lun); - - dev->BufferLength = 6; - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - memset(dev->CmdBuffer, 0x00, dev->BufferLength); - - ret = x54x_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer); - - x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); - DMAPageWrite(dma_address, - dev->CmdBuffer, 4 /* dev->BufferLength */); - - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - return(ret); - - case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ -//FIXME: add a longer delay here --FvK - return(0); - - case 0x0c: /* Seek */ - target_check(cmd->id, cmd->lun); - - cdb[0] = GPCMD_SEEK_10; - cdb[1] = (cmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - return((dev->Status == SCSI_STATUS_OK) ? 1 : 0); - - case 0x0d: /* Alternate Disk Reset, in practice it's a nop */ -//FIXME: add a longer delay here --FvK - return(0); - - case 0x10: /* Test Drive Ready */ - target_check(cmd->id, cmd->lun); - - cdb[0] = GPCMD_TEST_UNIT_READY; - cdb[1] = (cmd->lun & 7) << 5; - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x11: /* Recalibrate */ - target_check(cmd->id, cmd->lun); - - cdb[0] = GPCMD_REZERO_UNIT; - cdb[1] = (cmd->lun & 7) << 5; - - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - - case 0x14: /* Controller Diagnostic */ -//FIXME: add a longer delay here --FvK - return(0); - - case 0x15: /* Read DASD Type */ - target_check(cmd->id, cmd->lun); - - dev->BufferLength = 6; - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - memset(dev->CmdBuffer, 0x00, dev->BufferLength); - - ret = x54x_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer); - - x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); - DMAPageWrite(dma_address, - dev->CmdBuffer, 4 /* dev->BufferLength */); - - if (dev->CmdBuffer != NULL) { - free(dev->CmdBuffer); - dev->CmdBuffer = NULL; - } - - return(ret); - - default: - x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command); - return(1); - } - - x54x_log("BIOS Request complete\n"); -} - - -static void -x54x_cmd_done(x54x_t *dev, int suppress) -{ - int fast = 0; - - dev->DataReply = 0; - dev->Status |= STAT_IDLE; - - if (dev->ven_cmd_is_fast) { - fast = dev->ven_cmd_is_fast(dev); - } - - if ((dev->Command != CMD_START_SCSI) || fast) { - dev->Status &= ~STAT_DFULL; - x54x_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); - raise_irq(dev, suppress, INTR_HACC); - } - - dev->Command = 0xff; - dev->CmdParam = 0; -} - - -static void -x54x_add_to_period(int TransferLength) -{ - x54x_dev->temp_period += (int64_t) TransferLength; -} - - -static void -x54x_mbi_setup(x54x_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, - uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) -{ - Req_t *req = &dev->Req; - - req->CCBPointer = CCBPointer; - memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); - req->Is24bit = dev->Mbx24bit; - req->HostStatus = HostStatus; - req->TargetStatus = TargetStatus; - req->MailboxCompletionCode = mbcc; - - x54x_log("Mailbox in setup\n"); -} - - -static void -x54x_ccb(x54x_t *dev) -{ - Req_t *req = &dev->Req; - - /* Rewrite the CCB up to the CDB. */ - x54x_log("CCB completion code and statuses rewritten (pointer %08X)\n", req->CCBPointer); - DMAPageWrite(req->CCBPointer + 0x000D, &(req->MailboxCompletionCode), 1); - DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1); - DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1); - x54x_add_to_period(3); - - if (dev->MailboxOutInterrupts) - dev->ToRaise = INTR_MBOA | INTR_ANY; - else - dev->ToRaise = 0; -} - - -static void -x54x_mbi(x54x_t *dev) -{ - Req_t *req = &dev->Req; -// uint32_t CCBPointer = req->CCBPointer; - addr24 CCBPointer; - CCBU *CmdBlock = &(req->CmdBlock); - uint8_t HostStatus = req->HostStatus; - uint8_t TargetStatus = req->TargetStatus; - uint32_t MailboxCompletionCode = req->MailboxCompletionCode; - uint32_t Incoming; - - Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * (dev->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); - - if (MailboxCompletionCode != MBI_NOT_FOUND) { - CmdBlock->common.HostStatus = HostStatus; - CmdBlock->common.TargetStatus = TargetStatus; - - /* Rewrite the CCB up to the CDB. */ - x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer); - DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1); - DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1); - x54x_add_to_period(2); - } else { - x54x_log("Mailbox not found!\n"); - } - - x54x_log("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); - - if (dev->Mbx24bit) { - U32_TO_ADDR(CCBPointer, req->CCBPointer); - x54x_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); - DMAPageWrite(Incoming, &(req->MailboxCompletionCode), 1); - DMAPageWrite(Incoming + 1, (uint8_t *)&CCBPointer, 3); - x54x_add_to_period(4); - x54x_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); - } else { - x54x_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); - DMAPageWrite(Incoming, (uint8_t *)&(req->CCBPointer), 4); - DMAPageWrite(Incoming + 4, &(req->HostStatus), 1); - DMAPageWrite(Incoming + 5, &(req->TargetStatus), 1); - DMAPageWrite(Incoming + 7, &(req->MailboxCompletionCode), 1); - x54x_add_to_period(7); - x54x_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); - } - - dev->MailboxInPosCur++; - if (dev->MailboxInPosCur >= dev->MailboxCount) - dev->MailboxInPosCur = 0; - - dev->ToRaise = INTR_MBIF | INTR_ANY; - if (dev->MailboxOutInterrupts) - dev->ToRaise |= INTR_MBOA; -} - - -static void -x54x_rd_sge(int Is24bit, uint32_t Address, SGE32 *SG) -{ - SGE SGE24; - - if (Is24bit) { - DMAPageRead(Address, (uint8_t *)&SGE24, sizeof(SGE)); - x54x_add_to_period(sizeof(SGE)); - - /* Convert the 24-bit entries into 32-bit entries. */ - x54x_log("Read S/G block: %06X, %06X\n", SGE24.Segment, SGE24.SegmentPointer); - SG->Segment = ADDR_TO_U32(SGE24.Segment); - SG->SegmentPointer = ADDR_TO_U32(SGE24.SegmentPointer); - } else { - DMAPageRead(Address, (uint8_t *)SG, sizeof(SGE32)); - x54x_add_to_period(sizeof(SGE32)); - } -} - - -static int -x54x_get_length(Req_t *req, int Is24bit) -{ - uint32_t DataPointer, DataLength; - uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); - SGE32 SGBuffer; - uint32_t DataToTransfer = 0, i = 0; - - if (Is24bit) { - DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); - x54x_log("Data length: %08X\n", req->CmdBlock.old.DataLength); - } else { - DataPointer = req->CmdBlock.new.DataPointer; - DataLength = req->CmdBlock.new.DataLength; - } - x54x_log("Data Buffer write: length %d, pointer 0x%04X\n", - DataLength, DataPointer); - - if (!DataLength) - return(0); - - if (req->CmdBlock.common.ControlByte != 0x03) { - if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || - req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { - for (i = 0; i < DataLength; i += SGEntryLength) { - x54x_rd_sge(Is24bit, DataPointer + i, &SGBuffer); - - DataToTransfer += SGBuffer.Segment; - } - return(DataToTransfer); - } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || - req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { - return(DataLength); - } else { - return(0); - } - } else { - return(0); - } -} - - -static void -x54x_set_residue(Req_t *req, int32_t TransferLength) -{ - uint32_t Residue = 0; - addr24 Residue24; - int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength; - - if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || - (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { - - if ((TransferLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - TransferLength -= BufLen; - if (TransferLength > 0) - Residue = TransferLength; - } - - if (req->Is24bit) { - U32_TO_ADDR(Residue24, Residue); - DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue24, 3); - x54x_add_to_period(3); - x54x_log("24-bit Residual data length for reading: %d\n", Residue); - } else { - DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue, 4); - x54x_add_to_period(4); - x54x_log("32-bit Residual data length for reading: %d\n", Residue); - } - } -} - - -static void -x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) -{ - uint32_t DataPointer, DataLength; - uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); - uint32_t Address, i; - int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength; - uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00))); - uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00))); - int sg_pos = 0; - SGE32 SGBuffer; - uint32_t DataToTransfer = 0; - - if (Is24bit) { - DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); - } else { - DataPointer = req->CmdBlock.new.DataPointer; - DataLength = req->CmdBlock.new.DataLength; - } - x54x_log("Data Buffer %s: length %d, pointer 0x%04X\n", - dir ? "write" : "read", BufLen, DataPointer); - - if ((req->CmdBlock.common.ControlByte != 0x03) && TransferLength && BufLen) { - if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || - (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { - - /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without - checking its length, so do this procedure for both no read/write commands. */ - if ((DataLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - for (i = 0; i < DataLength; i += SGEntryLength) { - x54x_rd_sge(Is24bit, DataPointer + i, &SGBuffer); - - Address = SGBuffer.SegmentPointer; - DataToTransfer = MIN((int) SGBuffer.Segment, BufLen); - - if (read_from_host && DataToTransfer) { - x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - DMAPageRead(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer); - } - else if (write_to_host && DataToTransfer) { - x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - DMAPageWrite(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer); - } - else - x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - - sg_pos += SGBuffer.Segment; - - BufLen -= SGBuffer.Segment; - if (BufLen < 0) - BufLen = 0; - - x54x_log("After S/G segment done: %i, %i\n", sg_pos, BufLen); - } - } - } else if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND) || - (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)) { - Address = DataPointer; - - if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - if (read_from_host) - DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength)); - else if (write_to_host) - DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength)); - } - } - } -} - - -void -x54x_buf_alloc(uint8_t id, uint8_t lun, int length) -{ - if (SCSIDevices[id][lun].CmdBuffer != NULL) { - free(SCSIDevices[id][lun].CmdBuffer); - SCSIDevices[id][lun].CmdBuffer = NULL; - } - - x54x_log("Allocating data buffer (%i bytes)\n", length); - SCSIDevices[id][lun].CmdBuffer = (uint8_t *) malloc(length); - memset(SCSIDevices[id][lun].CmdBuffer, 0, length); -} - - -void -x54x_buf_free(uint8_t id, uint8_t lun) -{ - if (SCSIDevices[id][lun].CmdBuffer != NULL) { - free(SCSIDevices[id][lun].CmdBuffer); - SCSIDevices[id][lun].CmdBuffer = NULL; - } -} - - -static uint8_t -ConvertSenseLength(uint8_t RequestSenseLength) -{ - x54x_log("Unconverted Request Sense length %i\n", RequestSenseLength); - - if (RequestSenseLength == 0) - RequestSenseLength = 14; - else if (RequestSenseLength == 1) - RequestSenseLength = 0; - - x54x_log("Request Sense length %i\n", RequestSenseLength); - - return(RequestSenseLength); -} - - -uint32_t -SenseBufferPointer(Req_t *req) -{ - uint32_t SenseBufferAddress; - if (req->Is24bit) { - SenseBufferAddress = req->CCBPointer; - SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; - } else { - SenseBufferAddress = req->CmdBlock.new.SensePointer; - } - - return(SenseBufferAddress); -} - - -static void -SenseBufferFree(Req_t *req, int Copy) -{ - uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); - uint32_t SenseBufferAddress; - uint8_t temp_sense[256]; - - if (SenseLength && Copy) { - scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); - - /* - * The sense address, in 32-bit mode, is located in the - * Sense Pointer of the CCB, but in 24-bit mode, it is - * located at the end of the Command Descriptor Block. - */ - SenseBufferAddress = SenseBufferPointer(req); - - x54x_log("Request Sense address: %02X\n", SenseBufferAddress); - - x54x_log("SenseBufferFree(): Writing %i bytes at %08X\n", - SenseLength, SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); - x54x_add_to_period(SenseLength); - x54x_log("Sense data written to buffer: %02X %02X %02X\n", - temp_sense[2], temp_sense[12], temp_sense[13]); - } -} - - -static void -x54x_scsi_cmd(x54x_t *dev) -{ - Req_t *req = &dev->Req; - uint8_t id, lun; - uint8_t temp_cdb[12]; - uint32_t i; - int target_cdb_len = 12; - int target_data_len; - uint8_t bit24 = !!req->Is24bit; - int32_t *BufLen; - uint8_t phase; - uint32_t SenseBufferAddress; - int64_t p; - - id = req->TargetID; - lun = req->LUN; - - target_cdb_len = scsi_device_cdb_length(id, lun); - target_data_len = x54x_get_length(req, bit24); - - if (!scsi_device_valid(id, lun)) - fatal("SCSI target on %02i:%02i has disappeared\n", id, lun); - - x54x_log("target_data_len = %i\n", target_data_len); - - x54x_log("SCSI command being executed on ID %i, LUN %i\n", id, lun); - - x54x_log("SCSI CDB[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); - for (i=1; iCmdBlock.common.CdbLength; i++) - x54x_log("SCSI CDB[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); - - memset(temp_cdb, 0x00, target_cdb_len); - if (req->CmdBlock.common.CdbLength <= target_cdb_len) { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, - req->CmdBlock.common.CdbLength); - x54x_add_to_period(req->CmdBlock.common.CdbLength); - } else { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); - x54x_add_to_period(target_cdb_len); - } - - dev->Residue = 0; - - BufLen = scsi_device_get_buf_len(id, lun); - *BufLen = target_data_len; - - x54x_log("Command buffer: %08X\n", SCSIDevices[id][lun].CmdBuffer); - - scsi_device_command_phase0(id, lun, req->CmdBlock.common.CdbLength, temp_cdb); - - phase = SCSIDevices[id][lun].Phase; - - x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03)); - - if (phase != SCSI_PHASE_STATUS) { - if ((temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) { - /* Request sense in non-data mode - sense goes to sense buffer. */ - *BufLen = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); - x54x_buf_alloc(id, lun, *BufLen); - scsi_device_command_phase1(id, lun); - if ((SCSIDevices[id][lun].Status != SCSI_STATUS_OK) && (*BufLen > 0)) { - SenseBufferAddress = SenseBufferPointer(req); - DMAPageWrite(SenseBufferAddress, SCSIDevices[id][lun].CmdBuffer, *BufLen); - x54x_add_to_period(*BufLen); - } - } else { - p = scsi_device_get_callback(id, lun); - if (p <= 0LL) - x54x_add_to_period(*BufLen); - else - dev->media_period += p; - x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen)); - if (phase == SCSI_PHASE_DATA_OUT) - x54x_buf_dma_transfer(req, bit24, target_data_len, 1); - scsi_device_command_phase1(id, lun); - if (phase == SCSI_PHASE_DATA_IN) - x54x_buf_dma_transfer(req, bit24, target_data_len, 0); - - SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); - } - } else - SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); - - x54x_set_residue(req, target_data_len); - - x54x_buf_free(id, lun); - - x54x_log("Request complete\n"); - - if (SCSIDevices[id][lun].Status == SCSI_STATUS_OK) { - x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } else if (SCSIDevices[id][lun].Status == SCSI_STATUS_CHECK_CONDITION) { - x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - } - - x54x_log("SCSIDevices[%02i][%02i].Status = %02X\n", id, lun, SCSIDevices[id][lun].Status); -} - - -static void -x54x_notify(x54x_t *dev) -{ - if (dev->MailboxIsBIOS) - x54x_ccb(dev); - else - x54x_mbi(dev); -} - - -static void -x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) -{ - Req_t *req = &dev->Req; - uint8_t id, lun; - - /* Fetch data from the Command Control Block. */ - DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32)); - x54x_add_to_period(sizeof(CCB32)); - - req->Is24bit = dev->Mbx24bit; - req->CCBPointer = CCBPointer; - req->TargetID = dev->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; - req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; - - id = req->TargetID; - lun = req->LUN; - if ((id > dev->max_id) || (lun > 7)) { - x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, - CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - return; - } - - x54x_log("Scanning SCSI Target ID %i\n", id); - - SCSIDevices[id][lun].Status = SCSI_STATUS_OK; - - /* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */ - if (! scsi_device_present(id, 0)) { - x54x_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, - CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - } else { - x54x_log("SCSI Target ID %i detected and working\n", id); - - x54x_log("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); - x54x_log("CDB Length %i\n", req->CmdBlock.common.CdbLength); - x54x_log("CCB Opcode %x\n", req->CmdBlock.common.Opcode); - if ((req->CmdBlock.common.Opcode > 0x04) && (req->CmdBlock.common.Opcode != 0x81)) { - x54x_log("Invalid opcode: %02X\n", - req->CmdBlock.common.ControlByte); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_INVALID_OP_CODE, SCSI_STATUS_OK, MBI_ERROR); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - return; - } - if (req->CmdBlock.common.Opcode == 0x81) { - x54x_log("Bus reset opcode\n"); - scsi_device_reset(id, lun); - x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - return; - } - - if (req->CmdBlock.common.ControlByte > 0x03) { - x54x_log("Invalid control byte: %02X\n", - req->CmdBlock.common.ControlByte); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_INVALID_DIRECTION, SCSI_STATUS_OK, MBI_ERROR); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - return; - } - - x54x_log("%s: Callback: Process SCSI request\n", dev->name); - x54x_scsi_cmd(dev); - - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); - } -} - - -static void -x54x_req_abort(x54x_t *dev, uint32_t CCBPointer) -{ - CCBU CmdBlock; - - /* Fetch data from the Command Control Block. */ - DMAPageRead(CCBPointer, (uint8_t *)&CmdBlock, sizeof(CCB32)); - x54x_add_to_period(sizeof(CCB32)); - - x54x_mbi_setup(dev, CCBPointer, &CmdBlock, - 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); -} - - -static uint32_t -x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32) -{ - Mailbox_t MailboxOut; - uint32_t Outgoing; - uint32_t ccbp; - uint32_t Addr; - uint32_t Cur; - - if (dev->MailboxIsBIOS) { - Addr = dev->BIOSMailboxOutAddr; - Cur = dev->BIOSMailboxOutPosCur; - } else { - Addr = dev->MailboxOutAddr; - Cur = dev->MailboxOutPosCur; - } - - if (dev->Mbx24bit) { - Outgoing = Addr + (Cur * sizeof(Mailbox_t)); - DMAPageRead(Outgoing, (uint8_t *)&MailboxOut, sizeof(Mailbox_t)); - x54x_add_to_period(sizeof(Mailbox_t)); - - ccbp = *(uint32_t *) &MailboxOut; - Mailbox32->CCBPointer = (ccbp >> 24) | ((ccbp >> 8) & 0xff00) | ((ccbp << 8) & 0xff0000); - Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; - } else { - Outgoing = Addr + (Cur * sizeof(Mailbox32_t)); - - DMAPageRead(Outgoing, (uint8_t *)Mailbox32, sizeof(Mailbox32_t)); - x54x_add_to_period(sizeof(Mailbox32_t)); - } - - return(Outgoing); -} - - -uint8_t -x54x_mbo_process(x54x_t *dev) -{ - Mailbox32_t mb32; - uint32_t Outgoing; - uint8_t CmdStatus = MBO_FREE; - uint32_t CodeOffset = 0; - - CodeOffset = dev->Mbx24bit ? 0 : 7; - - Outgoing = x54x_mbo(dev, &mb32); - - if (mb32.u.out.ActionCode == MBO_START) { - x54x_log("Start Mailbox Command\n"); - x54x_req_setup(dev, mb32.CCBPointer, &mb32); - } else if (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT)) { - x54x_log("Abort Mailbox Command\n"); - x54x_req_abort(dev, mb32.CCBPointer); - } /* else { - x54x_log("Invalid action code: %02X\n", mb32.u.out.ActionCode); - } */ - - if ((mb32.u.out.ActionCode == MBO_START) || (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT))) { - /* We got the mailbox, mark it as free in the guest. */ - x54x_log("x54x_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); - DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, 1); - x54x_add_to_period(1); - - if (dev->ToRaise) - raise_irq(dev, 0, dev->ToRaise); - - if (dev->MailboxIsBIOS) - dev->BIOSMailboxReq--; - else - dev->MailboxReq--; - - return(1); - } - - return(0); -} - - -static void -x54x_do_mail(x54x_t *dev) -{ - int aggressive = 1; - - dev->MailboxIsBIOS = 0; - - if (dev->is_aggressive_mode) { - aggressive = dev->is_aggressive_mode(dev); - x54x_log("Processing mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); - }/* else { - x54x_log("Defaulting to process mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); - }*/ - - if (!dev->MailboxCount) { - x54x_log("x54x_do_mail(): No Mailboxes\n"); - return; - } - - if (aggressive) { - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - for (dev->MailboxOutPosCur = 0; dev->MailboxOutPosCur < dev->MailboxCount; dev->MailboxOutPosCur++) { - if (x54x_mbo_process(dev)) - break; - } - } else { - /* Strict round robin mode - only process the current mailbox and advance the pointer if successful. */ -x54x_do_mail_again: - if (x54x_mbo_process(dev)) { - dev->MailboxOutPosCur++; - dev->MailboxOutPosCur %= dev->MailboxCount; - goto x54x_do_mail_again; - } - } -} - - -static void -x54x_cmd_done(x54x_t *dev, int suppress); - - -static void -x54x_cmd_callback(void *priv) -{ - double period; - x54x_t *dev = (x54x_t *) x54x_dev; - - int mailboxes_present, bios_mailboxes_present; - - mailboxes_present = (!(dev->Status & STAT_INIT) && dev->MailboxInit && dev->MailboxReq); - bios_mailboxes_present = (dev->ven_callback && dev->BIOSMailboxInit && dev->BIOSMailboxReq); - - if (!mailboxes_present && !bios_mailboxes_present) { - /* If we did not get anything, do nothing and wait 10 us. */ - dev->timer_period = 10LL * TIMER_USEC; - return; - } - - dev->temp_period = dev->media_period = 0LL; - - if (!mailboxes_present) { - /* Do only BIOS mailboxes. */ - dev->ven_callback(dev); - } else if (!bios_mailboxes_present) { - /* Do only normal mailboxes. */ - x54x_do_mail(dev); - } else { - /* Do both kinds of mailboxes. */ - if (dev->callback_phase) - dev->ven_callback(dev); - else - x54x_do_mail(dev); - - dev->callback_phase = (dev->callback_phase + 1) & 0x01; - } - - period = (1000000.0 / x54x_dev->ha_bps) * ((double) TIMER_USEC) * ((double) dev->temp_period); - dev->timer_period = dev->media_period + ((int64_t) period) + (40LL * TIMER_USEC); - x54x_log("Temporary period: %" PRId64 " us (%" PRIi64 " periods)\n", dev->timer_period, dev->temp_period); -} - - -static uint8_t -x54x_in(uint16_t port, void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - uint8_t ret; - - switch (port & 3) { - case 0: - default: - ret = dev->Status; - break; - - case 1: - ret = dev->DataBuf[dev->DataReply]; - if (dev->DataReplyLeft) { - dev->DataReply++; - dev->DataReplyLeft--; - if (! dev->DataReplyLeft) - x54x_cmd_done(dev, 0); - } - break; - - case 2: - if (dev->int_geom_writable) - ret = dev->Interrupt; - else - ret = dev->Interrupt & ~0x70; - break; - - case 3: - /* Bits according to ASPI4DOS.SYS v3.36: - 0 Not checked - 1 Must be 0 - 2 Must be 0-0-0-1 - 3 Must be 0 - 4 Must be 0-1-0-0 - 5 Must be 0 - 6 Not checked - 7 Not checked - */ - if (dev->int_geom_writable) - ret = dev->Geometry; - else { - switch(dev->Geometry) { - case 0: default: ret = 'A'; break; - case 1: ret = 'D'; break; - case 2: ret = 'A'; break; - case 3: ret = 'P'; break; - } - ret ^= 1; - dev->Geometry++; - dev->Geometry &= 0x03; - break; - } - break; - } - -#if 0 - x54x_log("%s: Read Port 0x%02X, Value %02X\n", dev->name, port, ret); -#endif - return(ret); -} - - -static uint16_t -x54x_inw(uint16_t port, void *priv) -{ - return((uint16_t) x54x_in(port, priv)); -} - - -static uint32_t -x54x_inl(uint16_t port, void *priv) -{ - return((uint32_t) x54x_in(port, priv)); -} - - -static uint8_t -x54x_read(uint32_t port, void *priv) -{ - return(x54x_in(port & 3, priv)); -} - - -static uint16_t -x54x_readw(uint32_t port, void *priv) -{ - return(x54x_inw(port & 3, priv)); -} - - -static uint32_t -x54x_readl(uint32_t port, void *priv) -{ - return(x54x_inl(port & 3, priv)); -} - - -static void -x54x_reset_poll(void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - dev->Status = STAT_INIT | STAT_IDLE; - - dev->ResetCB = 0LL; -} - - -static void -x54x_reset(x54x_t *dev) -{ - int i, j; - - clear_irq(dev); - if (dev->int_geom_writable) - dev->Geometry = 0x80; - else - dev->Geometry = 0x00; - dev->callback_phase = 0; - dev->Command = 0xFF; - dev->CmdParam = 0; - dev->CmdParamLeft = 0; - dev->Mbx24bit = 1; - dev->MailboxInPosCur = 0; - dev->MailboxOutInterrupts = 0; - dev->PendingInterrupt = 0; - dev->IrqEnabled = 1; - dev->MailboxCount = 0; - dev->MailboxOutPosCur = 0; - - /* Reset all devices on controller reset. */ - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } - - if (dev->ven_reset) - dev->ven_reset(dev); -} - - -void -x54x_reset_ctrl(x54x_t *dev, uint8_t Reset) -{ - /* Say hello! */ - x54x_log("%s %s (IO=0x%04X, IRQ=%d, DMA=%d, BIOS @%05lX) ID=%d\n", - dev->vendor, dev->name, dev->Base, dev->Irq, dev->DmaChannel, - dev->rom_addr, dev->HostID); - - x54x_reset(dev); - - if (Reset) { - dev->Status = STAT_STST; - dev->ResetCB = X54X_RESET_DURATION_US * TIMER_USEC; - } else { - dev->Status = STAT_INIT | STAT_IDLE; - } -} - - -static void -x54x_out(uint16_t port, uint8_t val, void *priv) -{ - ReplyInquireSetupInformation *ReplyISI; - x54x_t *dev = (x54x_t *)priv; - MailboxInit_t *mbi; - int i = 0; - uint8_t j = 0; - BIOSCMD *cmd; - uint16_t cyl = 0; - int suppress = 0; - uint32_t FIFOBuf; - uint8_t reset; - addr24 Address; - uint8_t host_id = dev->HostID; - uint8_t irq = 0; - - x54x_log("%s: Write Port 0x%02X, Value %02X\n", dev->name, port, val); - - switch (port & 3) { - case 0: - if ((val & CTRL_HRST) || (val & CTRL_SRST)) { - reset = (val & CTRL_HRST); - x54x_log("Reset completed = %x\n", reset); - x54x_reset_ctrl(dev, reset); - x54x_log("Controller reset: "); - break; - } - - if (val & CTRL_SCRST) { - /* Reset all devices on SCSI bus reset. */ - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } - } - - if (val & CTRL_IRST) { - clear_irq(dev); - x54x_log("Interrupt reset: "); - } - break; - - case 1: - /* Fast path for the mailbox execution command. */ - if ((val == CMD_START_SCSI) && (dev->Command == 0xff)) { - dev->MailboxReq++; - x54x_log("Start SCSI command: "); - return; - } - if (dev->ven_fast_cmds) { - if (dev->Command == 0xff) { - if (dev->ven_fast_cmds(dev, val)) - return; - } - } - - if (dev->Command == 0xff) { - dev->Command = val; - dev->CmdParam = 0; - dev->CmdParamLeft = 0; - - dev->Status &= ~(STAT_INVCMD | STAT_IDLE); - x54x_log("%s: Operation Code 0x%02X\n", dev->name, val); - switch (dev->Command) { - case CMD_MBINIT: - dev->CmdParamLeft = sizeof(MailboxInit_t); - break; - - case CMD_BIOSCMD: - dev->CmdParamLeft = 10; - break; - - case CMD_EMBOI: - case CMD_BUSON_TIME: - case CMD_BUSOFF_TIME: - case CMD_DMASPEED: - case CMD_RETSETUP: - case CMD_ECHO: - case CMD_OPTIONS: - dev->CmdParamLeft = 1; - break; - - case CMD_SELTIMEOUT: - dev->CmdParamLeft = 4; - break; - - case CMD_WRITE_CH2: - case CMD_READ_CH2: - dev->CmdParamLeft = 3; - break; - - default: - if (dev->get_ven_param_len) - dev->CmdParamLeft = dev->get_ven_param_len(dev); - break; - } - } else { - dev->CmdBuf[dev->CmdParam] = val; - dev->CmdParam++; - dev->CmdParamLeft--; - - if (dev->ven_cmd_phase1) - dev->ven_cmd_phase1(dev); - } - - if (! dev->CmdParamLeft) { - x54x_log("Running Operation Code 0x%02X\n", dev->Command); - switch (dev->Command) { - case CMD_NOP: /* No Operation */ - dev->DataReplyLeft = 0; - break; - - case CMD_MBINIT: /* mailbox initialization */ - dev->Mbx24bit = 1; - - mbi = (MailboxInit_t *)dev->CmdBuf; - - dev->MailboxInit = 1; - dev->MailboxCount = mbi->Count; - dev->MailboxOutAddr = ADDR_TO_U32(mbi->Address); - dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); - - x54x_log("Initialize Mailbox: MBO=0x%08lx, MBI=0x%08lx, %d entries at 0x%08lx\n", - dev->MailboxOutAddr, - dev->MailboxInAddr, - mbi->Count, - ADDR_TO_U32(mbi->Address)); - - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - x54x_log("Mailbox init: "); - break; - - case CMD_BIOSCMD: /* execute BIOS */ - cmd = (BIOSCMD *)dev->CmdBuf; - if (!dev->lba_bios) { - /* 1640 uses LBA. */ - cyl = ((cmd->u.chs.cyl & 0xff) << 8) | ((cmd->u.chs.cyl >> 8) & 0xff); - cmd->u.chs.cyl = cyl; - } - if (dev->lba_bios) { - /* 1640 uses LBA. */ - x54x_log("BIOS LBA=%06lx (%lu)\n", - lba32_blk(cmd), - lba32_blk(cmd)); - } else { - cmd->u.chs.head &= 0xf; - cmd->u.chs.sec &= 0x1f; - x54x_log("BIOS CHS=%04X/%02X%02X\n", - cmd->u.chs.cyl, - cmd->u.chs.head, - cmd->u.chs.sec); - } - dev->DataBuf[0] = x54x_bios_command(dev, dev->max_id, cmd, (dev->lba_bios)?1:0); - x54x_log("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); - dev->DataReplyLeft = 1; - break; - - case CMD_INQUIRY: /* Inquiry */ - memcpy(dev->DataBuf, dev->fw_rev, 4); - x54x_log("Adapter inquiry: %c %c %c %c\n", dev->fw_rev[0], dev->fw_rev[1], dev->fw_rev[2], dev->fw_rev[3]); - dev->DataReplyLeft = 4; - break; - - case CMD_EMBOI: /* enable MBO Interrupt */ - if (dev->CmdBuf[0] <= 1) { - dev->MailboxOutInterrupts = dev->CmdBuf[0]; - x54x_log("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); - suppress = 1; - } else { - dev->Status |= STAT_INVCMD; - } - dev->DataReplyLeft = 0; - break; - - case CMD_SELTIMEOUT: /* Selection Time-out */ - dev->DataReplyLeft = 0; - break; - - case CMD_BUSON_TIME: /* bus-on time */ - dev->BusOnTime = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("Bus-on time: %d\n", dev->CmdBuf[0]); - break; - - case CMD_BUSOFF_TIME: /* bus-off time */ - dev->BusOffTime = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("Bus-off time: %d\n", dev->CmdBuf[0]); - break; - - case CMD_DMASPEED: /* DMA Transfer Rate */ - dev->ATBusSpeed = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("DMA transfer rate: %02X\n", dev->CmdBuf[0]); - break; - - case CMD_RETDEVS: /* return Installed Devices */ - memset(dev->DataBuf, 0x00, 8); - - if (dev->ven_get_host_id) - host_id = dev->ven_get_host_id(dev); - - for (i=0; i<8; i++) { - dev->DataBuf[i] = 0x00; - - /* Skip the HA .. */ - if (i == host_id) continue; - - for (j=0; jDataBuf[i] |= (1<DataReplyLeft = i; - break; - - case CMD_RETCONF: /* return Configuration */ - if (dev->ven_get_dma) - dev->DataBuf[0] = (1<ven_get_dma(dev)); - else - dev->DataBuf[0] = (1<DmaChannel); - - if (dev->ven_get_irq) - irq = dev->ven_get_irq(dev); - else - irq = dev->Irq; - - if (irq >= 9) - dev->DataBuf[1]=(1<<(irq-9)); - else - dev->DataBuf[1]=0; - if (dev->ven_get_host_id) - dev->DataBuf[2] = dev->ven_get_host_id(dev); - else - dev->DataBuf[2] = dev->HostID; - x54x_log("Configuration data: %02X %02X %02X\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2]); - dev->DataReplyLeft = 3; - break; - - case CMD_RETSETUP: /* return Setup */ - { - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - memset(ReplyISI, 0x00, sizeof(ReplyInquireSetupInformation)); - - ReplyISI->uBusTransferRate = dev->ATBusSpeed; - ReplyISI->uPreemptTimeOnBus = dev->BusOnTime; - ReplyISI->uTimeOffBus = dev->BusOffTime; - ReplyISI->cMailbox = dev->MailboxCount; - U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); - - if (dev->get_ven_data) { - dev->get_ven_data(dev); - } - - dev->DataReplyLeft = dev->CmdBuf[0]; - x54x_log("Return Setup Information: %d (length: %i)\n", dev->CmdBuf[0], sizeof(ReplyInquireSetupInformation)); - } - break; - - case CMD_ECHO: /* ECHO data */ - dev->DataBuf[0] = dev->CmdBuf[0]; - dev->DataReplyLeft = 1; - break; - - case CMD_WRITE_CH2: /* write channel 2 buffer */ - dev->DataReplyLeft = 0; - Address.hi = dev->CmdBuf[0]; - Address.mid = dev->CmdBuf[1]; - Address.lo = dev->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - x54x_log("Adaptec LocalRAM: Reading 64 bytes at %08X\n", FIFOBuf); - DMAPageRead(FIFOBuf, dev->dma_buffer, 64); - break; - - case CMD_READ_CH2: /* write channel 2 buffer */ - dev->DataReplyLeft = 0; - Address.hi = dev->CmdBuf[0]; - Address.mid = dev->CmdBuf[1]; - Address.lo = dev->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - x54x_log("Adaptec LocalRAM: Writing 64 bytes at %08X\n", FIFOBuf); - DMAPageWrite(FIFOBuf, dev->dma_buffer, 64); - break; - - case CMD_OPTIONS: /* Set adapter options */ - if (dev->CmdParam == 1) - dev->CmdParamLeft = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - break; - - default: - if (dev->ven_cmds) - suppress = dev->ven_cmds(dev); - else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - } - } - - if (dev->DataReplyLeft) - dev->Status |= STAT_DFULL; - else if (!dev->CmdParamLeft) - x54x_cmd_done(dev, suppress); - break; - - case 2: - if (dev->int_geom_writable) - dev->Interrupt = val; - break; - - case 3: - if (dev->int_geom_writable) - dev->Geometry = val; - break; - } -} - - -static void -x54x_outw(uint16_t port, uint16_t val, void *priv) -{ - x54x_out(port, val & 0xFF, priv); -} - - -static void -x54x_outl(uint16_t port, uint32_t val, void *priv) -{ - x54x_out(port, val & 0xFF, priv); -} - - -static void -x54x_write(uint32_t port, uint8_t val, void *priv) -{ - x54x_out(port & 3, val, priv); -} - - -static void -x54x_writew(uint32_t port, uint16_t val, void *priv) -{ - x54x_outw(port & 3, val, priv); -} - - -static void -x54x_writel(uint32_t port, uint32_t val, void *priv) -{ - x54x_outl(port & 3, val, priv); -} - - -void -x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len) -{ - int bit32 = 0; - - if (dev->bus & DEVICE_PCI) - bit32 = 1; - else if ((dev->bus & DEVICE_MCA) && dev->bit32) - bit32 = 1; - - if (bit32) { - x54x_log("x54x: [PCI] Setting I/O handler at %04X\n", base); - io_sethandler(base, len, - x54x_in, x54x_inw, x54x_inl, - x54x_out, x54x_outw, x54x_outl, dev); - } else { - x54x_log("x54x: [ISA] Setting I/O handler at %04X\n", base); - io_sethandler(base, len, - x54x_in, x54x_inw, NULL, - x54x_out, x54x_outw, NULL, dev); - } -} - - -void -x54x_io_remove(x54x_t *dev, uint32_t base, uint8_t len) -{ - int bit32 = 0; - - if (dev->bus & DEVICE_PCI) - bit32 = 1; - else if ((dev->bus & DEVICE_MCA) && dev->bit32) - bit32 = 1; - - x54x_log("x54x: Removing I/O handler at %04X\n", base); - - if (bit32) { - io_removehandler(base, len, - x54x_in, x54x_inw, x54x_inl, - x54x_out, x54x_outw, x54x_outl, dev); - } else { - io_removehandler(base, len, - x54x_in, x54x_inw, NULL, - x54x_out, x54x_outw, NULL, dev); - } -} - - -void -x54x_mem_init(x54x_t *dev, uint32_t addr) -{ - int bit32 = 0; - - if (dev->bus & DEVICE_PCI) - bit32 = 1; - else if ((dev->bus & DEVICE_MCA) && dev->bit32) - bit32 = 1; - - if (bit32) { - mem_mapping_add(&dev->mmio_mapping, addr, 0x20, - x54x_read, x54x_readw, x54x_readl, - x54x_write, x54x_writew, x54x_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); - } else { - mem_mapping_add(&dev->mmio_mapping, addr, 0x20, - x54x_read, x54x_readw, NULL, - x54x_write, x54x_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, dev); - } -} - - -void -x54x_mem_enable(x54x_t *dev) -{ - mem_mapping_enable(&dev->mmio_mapping); -} - - -void -x54x_mem_set_addr(x54x_t *dev, uint32_t base) -{ - mem_mapping_set_addr(&dev->mmio_mapping, base, 0x20); -} - - -void -x54x_mem_disable(x54x_t *dev) -{ - mem_mapping_disable(&dev->mmio_mapping); -} - - -/* General initialization routine for all boards. */ -void * -x54x_init(const device_t *info) -{ - x54x_t *dev; - - /* Allocate control block and set up basic stuff. */ - dev = malloc(sizeof(x54x_t)); - if (dev == NULL) return(dev); - memset(dev, 0x00, sizeof(x54x_t)); - dev->type = info->local; - - dev->bus = info->flags; - dev->callback_phase = 0; - - timer_add(x54x_reset_poll, &dev->ResetCB, &dev->ResetCB, dev); - dev->timer_period = 10LL * TIMER_USEC; - timer_add(x54x_cmd_callback, &dev->timer_period, TIMER_ALWAYS_ENABLED, dev); - - x54x_dev = dev; - - return(dev); -} - - -void -x54x_close(void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - if (dev) { - x54x_dev = NULL; - - /* Tell the timer to terminate. */ - dev->timer_period = 0LL; - - dev->MailboxInit = dev->BIOSMailboxInit = 0; - dev->MailboxCount = dev->BIOSMailboxCount = 0; - dev->MailboxReq = dev->BIOSMailboxReq = 0; - - if (dev->ven_data) - free(dev->ven_data); - - if (dev->nvr != NULL) - free(dev->nvr); - - free(dev); - dev = NULL; - } -} - - -void -x54x_device_reset(void *priv) -{ - x54x_t *dev = (x54x_t *)priv; - - x54x_reset_ctrl(dev, 1); - - dev->ResetCB = 0LL; - dev->Status = STAT_IDLE | STAT_INIT; -} diff --git a/src - Cópia/scsi/scsi_x54x.h b/src - Cópia/scsi/scsi_x54x.h deleted file mode 100644 index d2e7cb60b..000000000 --- a/src - Cópia/scsi/scsi_x54x.h +++ /dev/null @@ -1,510 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header of the code common to the AHA-154x series of SCSI - * Host Adapters made by Adaptec, Inc. and the BusLogic series - * of SCSI Host Adapters made by Mylex. - * These controllers were designed for various buses. - * - * Version: @(#)scsi_x54x.h 1.0.7 2018/04/06 - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef SCSI_X54X_H - -#define SCSI_X54X_H - -#define SCSI_DELAY_TM 1 /* was 50 */ - - -#define ROM_SIZE 16384 /* one ROM is 16K */ -#define NVR_SIZE 256 /* size of NVR */ - - -/* EEPROM map and bit definitions. */ -#define EE0_HOSTID 0x07 /* EE(0) [2:0] */ -#define EE0_ALTFLOP 0x80 /* EE(0) [7] FDC at 370h */ -#define EE1_IRQCH 0x07 /* EE(1) [3:0] */ -#define EE1_DMACH 0x70 /* EE(1) [7:4] */ -#define EE2_RMVOK 0x01 /* EE(2) [0] Support removable disks */ -#define EE2_HABIOS 0x02 /* EE(2) [1] HA Bios Space Reserved */ -#define EE2_INT19 0x04 /* EE(2) [2] HA Bios Controls INT19 */ -#define EE2_DYNSCAN 0x08 /* EE(2) [3] Dynamically scan bus */ -#define EE2_TWODRV 0x10 /* EE(2) [4] Allow more than 2 drives */ -#define EE2_SEEKRET 0x20 /* EE(2) [5] Immediate return on seek */ -#define EE2_EXT1G 0x80 /* EE(2) [7] Extended Translation >1GB */ -#define EE3_SPEED 0x00 /* EE(3) [7:0] DMA Speed */ -#define SPEED_33 0xFF -#define SPEED_50 0x00 -#define SPEED_56 0x04 -#define SPEED_67 0x01 -#define SPEED_80 0x02 -#define SPEED_10 0x03 -#define EE4_FLOPTOK 0x80 /* EE(4) [7] Support Flopticals */ -#define EE6_PARITY 0x01 /* EE(6) [0] parity check enable */ -#define EE6_TERM 0x02 /* EE(6) [1] host term enable */ -#define EE6_RSTBUS 0x04 /* EE(6) [2] reset SCSI bus on boot */ -#define EEE_SYNC 0x01 /* EE(E) [0] Enable Sync Negotiation */ -#define EEE_DISCON 0x02 /* EE(E) [1] Enable Disconnection */ -#define EEE_FAST 0x04 /* EE(E) [2] Enable FAST SCSI */ -#define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ - - -/* - * Host Adapter I/O ports. - * - * READ Port x+0: STATUS - * WRITE Port x+0: CONTROL - * - * READ Port x+1: DATA - * WRITE Port x+1: COMMAND - * - * READ Port x+2: INTERRUPT STATUS - * WRITE Port x+2: (undefined?) - * - * R/W Port x+3: (undefined) - */ - -/* WRITE CONTROL commands. */ -#define CTRL_HRST 0x80 /* Hard reset */ -#define CTRL_SRST 0x40 /* Soft reset */ -#define CTRL_IRST 0x20 /* interrupt reset */ -#define CTRL_SCRST 0x10 /* SCSI bus reset */ - -/* READ STATUS. */ -#define STAT_STST 0x80 /* self-test in progress */ -#define STAT_DFAIL 0x40 /* internal diagnostic failure */ -#define STAT_INIT 0x20 /* mailbox initialization required */ -#define STAT_IDLE 0x10 /* HBA is idle */ -#define STAT_CDFULL 0x08 /* Command/Data output port is full */ -#define STAT_DFULL 0x04 /* Data input port is full */ -#define STAT_INVCMD 0x01 /* Invalid command */ - -/* READ/WRITE DATA. */ -#define CMD_NOP 0x00 /* No operation */ -#define CMD_MBINIT 0x01 /* mailbox initialization */ -#define CMD_START_SCSI 0x02 /* Start SCSI command */ -#define CMD_BIOSCMD 0x03 /* Execute ROM BIOS command */ -#define CMD_INQUIRY 0x04 /* Adapter inquiry */ -#define CMD_EMBOI 0x05 /* enable Mailbox Out Interrupt */ -#define CMD_SELTIMEOUT 0x06 /* Set SEL timeout */ -#define CMD_BUSON_TIME 0x07 /* set bus-On time */ -#define CMD_BUSOFF_TIME 0x08 /* set bus-off time */ -#define CMD_DMASPEED 0x09 /* set ISA DMA speed */ -#define CMD_RETDEVS 0x0A /* return installed devices */ -#define CMD_RETCONF 0x0B /* return configuration data */ -#define CMD_TARGET 0x0C /* set HBA to target mode */ -#define CMD_RETSETUP 0x0D /* return setup data */ -#define CMD_WRITE_CH2 0x1A /* write channel 2 buffer */ -#define CMD_READ_CH2 0x1B /* read channel 2 buffer */ -#define CMD_ECHO 0x1F /* ECHO command data */ -#define CMD_OPTIONS 0x21 /* set adapter options */ - -/* READ INTERRUPT STATUS. */ -#define INTR_ANY 0x80 /* any interrupt */ -#define INTR_SRCD 0x08 /* SCSI reset detected */ -#define INTR_HACC 0x04 /* HA command complete */ -#define INTR_MBOA 0x02 /* MBO empty */ -#define INTR_MBIF 0x01 /* MBI full */ - - -/* Structure for the INQUIRE_SETUP_INFORMATION reply. */ -#pragma pack(push,1) -typedef struct { - uint8_t uOffset :4, - uTransferPeriod :3, - fSynchronous :1; -} ReplyInquireSetupInformationSynchronousValue; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t fSynchronousInitiationEnabled :1, - fParityCheckingEnabled :1, - uReserved1 :6; - uint8_t uBusTransferRate; - uint8_t uPreemptTimeOnBus; - uint8_t uTimeOffBus; - uint8_t cMailbox; - addr24 MailboxAddress; - ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; - uint8_t uDisconnectPermittedId0To7; - uint8_t VendorSpecificData[28]; -} ReplyInquireSetupInformation; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t Count; - addr24 Address; -} MailboxInit_t; -#pragma pack(pop) - -/* - * Mailbox Definitions. - * - * Mailbox Out (MBO) command values. - */ -#define MBO_FREE 0x00 -#define MBO_START 0x01 -#define MBO_ABORT 0x02 - -/* Mailbox In (MBI) status values. */ -#define MBI_FREE 0x00 -#define MBI_SUCCESS 0x01 -#define MBI_ABORT 0x02 -#define MBI_NOT_FOUND 0x03 -#define MBI_ERROR 0x04 - -#pragma pack(push,1) -typedef struct { - uint8_t CmdStatus; - addr24 CCBPointer; -} Mailbox_t; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint32_t CCBPointer; - union { - struct { - uint8_t Reserved[3]; - uint8_t ActionCode; - } out; - struct { - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved; - uint8_t CompletionCode; - } in; - } u; -} Mailbox32_t; -#pragma pack(pop) - -/* - * - * CCB - SCSI Command Control Block - * - * The CCB is a superset of the CDB (Command Descriptor Block) - * and specifies detailed information about a SCSI command. - * - */ -/* Byte 0 Command Control Block Operation Code */ -#define SCSI_INITIATOR_COMMAND 0x00 -#define TARGET_MODE_COMMAND 0x01 -#define SCATTER_GATHER_COMMAND 0x02 -#define SCSI_INITIATOR_COMMAND_RES 0x03 -#define SCATTER_GATHER_COMMAND_RES 0x04 -#define BUS_RESET 0x81 - -/* Byte 1 Address and Direction Control */ -#define CCB_TARGET_ID_SHIFT 0x06 /* CCB Op Code = 00, 02 */ -#define CCB_INITIATOR_ID_SHIFT 0x06 /* CCB Op Code = 01 */ -#define CCB_DATA_XFER_IN 0x01 -#define CCB_DATA_XFER_OUT 0x02 -#define CCB_LUN_MASK 0x07 /* Logical Unit Number */ - -/* Byte 2 SCSI_Command_Length - Length of SCSI CDB - Byte 3 Request Sense Allocation Length */ -#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ -#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ - -/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ -/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ -/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ -/* Byte 13 Command Link ID - TBD (I don't know yet) */ -/* Byte 14 Host Status - Host Adapter status */ -#define CCB_COMPLETE 0x00 /* CCB completed without error */ -#define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */ -#define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */ -#define CCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ -#define CCB_DATA_OVER_UNDER_RUN 0x12 -#define CCB_UNEXPECTED_BUS_FREE 0x13 /* Trg dropped SCSI BSY */ -#define CCB_PHASE_SEQUENCE_FAIL 0x14 /* Trg bus phase sequence fail */ -#define CCB_BAD_MBO_COMMAND 0x15 /* MBO command not 0, 1 or 2 */ -#define CCB_INVALID_OP_CODE 0x16 /* CCB invalid operation code */ -#define CCB_BAD_LINKED_LUN 0x17 /* Linked CCB LUN diff from 1st */ -#define CCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ -#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */ -#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */ - -/* Byte 15 Target Status - - See scsi.h files for these statuses. - Bytes 16 and 17 Reserved (must be 0) - Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ - -#pragma pack(push,1) -typedef struct { - uint8_t Opcode; - uint8_t Reserved1 :3, - ControlByte :2, - TagQueued :1, - QueueTag :2; - uint8_t CdbLength; - uint8_t RequestSenseLength; - uint32_t DataLength; - uint32_t DataPointer; - uint8_t Reserved2[2]; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Id; - uint8_t Lun :5, - LegacyTagEnable :1, - LegacyQueueTag :2; - uint8_t Cdb[12]; - uint8_t Reserved3[6]; - uint32_t SensePointer; -} CCB32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t Opcode; - uint8_t Lun :3, - ControlByte :2, - Id :3; - uint8_t CdbLength; - uint8_t RequestSenseLength; - addr24 DataLength; - addr24 DataPointer; - addr24 LinkPointer; - uint8_t LinkId; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved[2]; - uint8_t Cdb[12]; -} CCB; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t Opcode; - uint8_t Pad1 :3, - ControlByte :2, - Pad2 :3; - uint8_t CdbLength; - uint8_t RequestSenseLength; - uint8_t Pad3[9]; - uint8_t CompletionCode; /* Only used by the 1542C/CF(/CP?) BIOS mailboxes */ - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Pad4[2]; - uint8_t Cdb[12]; -} CCBC; -#pragma pack(pop) - -#pragma pack(push,1) -typedef union { - CCB32 new; - CCB old; - CCBC common; -} CCBU; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - CCBU CmdBlock; - uint8_t *RequestSenseBuffer; - uint32_t CCBPointer; - int Is24bit; - uint8_t TargetID, - LUN, - HostStatus, - TargetStatus, - MailboxCompletionCode; -} Req_t; -#pragma pack(pop) - -typedef struct { - int8_t type; /* type of device */ - - char vendor[16]; /* name of device vendor */ - char name[16]; /* name of device */ - - int64_t timer_period, temp_period; - uint8_t callback_phase; - int64_t media_period; - double ha_bps; /* bytes per second */ - - int8_t Irq; - uint8_t IrqEnabled; - - int8_t DmaChannel; - int8_t HostID; - uint32_t Base; - uint8_t pos_regs[8]; /* MCA */ - - wchar_t *bios_path; /* path to BIOS image file */ - uint32_t rom_addr; /* address of BIOS ROM */ - uint16_t rom_ioaddr; /* offset in BIOS of I/O addr */ - uint16_t rom_shram; /* index to shared RAM */ - uint16_t rom_shramsz; /* size of shared RAM */ - uint16_t rom_fwhigh; /* offset in BIOS of ver ID */ - rom_t bios; /* BIOS memory descriptor */ - rom_t uppersck; /* BIOS memory descriptor */ - uint8_t *rom1; /* main BIOS image */ - uint8_t *rom2; /* SCSI-Select image */ - - wchar_t *nvr_path; /* path to NVR image file */ - uint8_t *nvr; /* EEPROM buffer */ - - int64_t ResetCB; - - volatile uint8_t /* for multi-threading, keep */ - Status, /* these volatile */ - Interrupt; - - Req_t Req; - uint8_t Geometry; - uint8_t Control; - uint8_t Command; - uint8_t CmdBuf[128]; - uint8_t CmdParam; - uint32_t CmdParamLeft; - uint8_t DataBuf[65536]; - uint16_t DataReply; - uint16_t DataReplyLeft; - - volatile uint32_t - MailboxInit, - MailboxCount, - MailboxOutAddr, - MailboxOutPosCur, - MailboxInAddr, - MailboxInPosCur, - MailboxReq; - - volatile int - Mbx24bit, - MailboxOutInterrupts; - - volatile int - PendingInterrupt, - Lock; - - uint8_t shadow_ram[128]; - - volatile uint8_t - MailboxIsBIOS, - ToRaise; - - uint8_t shram_mode; - - uint8_t sync; - uint8_t parity; - - uint8_t dma_buffer[128]; - - volatile - uint32_t BIOSMailboxInit, - BIOSMailboxCount, - BIOSMailboxOutAddr, - BIOSMailboxOutPosCur, - BIOSMailboxReq, - Residue; - - uint8_t BusOnTime, - BusOffTime, - ATBusSpeed; - - char *fw_rev; /* The 4 bytes of the revision command information + 2 extra bytes for BusLogic */ - uint16_t bus; /* Basically a copy of device flags */ - uint8_t setup_info_len; - uint8_t max_id; - uint8_t pci_slot; - uint8_t bit32; - uint8_t lba_bios; - - mem_mapping_t mmio_mapping; - - uint8_t int_geom_writable; - uint8_t cdrom_boot; - - /* Pointer to a structure of vendor-specific data that only the vendor-specific code can understand */ - void *ven_data; - - /* Pointer to a function that performs vendor-specific operation during the timer callback */ - void (*ven_callback)(void *p); - /* Pointer to a function that executes the second parameter phase of the vendor-specific command */ - void (*ven_cmd_phase1)(void *p); - /* Pointer to a function that gets the host adapter ID in case it has to be read from a non-standard location */ - uint8_t (*ven_get_host_id)(void *p); - /* Pointer to a function that updates the IRQ in the vendor-specific space */ - uint8_t (*ven_get_irq)(void *p); - /* Pointer to a function that updates the DMA channel in the vendor-specific space */ - uint8_t (*ven_get_dma)(void *p); - /* Pointer to a function that returns whether command is fast */ - uint8_t (*ven_cmd_is_fast)(void *p); - /* Pointer to a function that executes vendor-specific fast path commands */ - uint8_t (*ven_fast_cmds)(void *p, uint8_t cmd); - /* Pointer to a function that gets the parameter length for vendor-specific commands */ - uint8_t (*get_ven_param_len)(void *p); - /* Pointer to a function that executes vendor-specific commands and returns whether or not to suppress the IRQ */ - uint8_t (*ven_cmds)(void *p); - /* Pointer to a function that fills in the vendor-specific setup data */ - void (*get_ven_data)(void *p); - /* Pointer to a function that determines if the mode is aggressive */ - uint8_t (*is_aggressive_mode)(void *p); - /* Pointer to a function that returns interrupt type (0 = edge, 1 = level) */ - uint8_t (*interrupt_type)(void *p); - /* Pointer to a function that resets vendor-specific data */ - void (*ven_reset)(void *p); -} x54x_t; - - -#pragma pack(push,1) -typedef struct -{ - uint8_t command; - uint8_t lun:3, - reserved:2, - id:3; - union { - struct { - uint16_t cyl; - uint8_t head; - uint8_t sec; - } chs; - struct { - uint8_t lba0; /* MSB */ - uint8_t lba1; - uint8_t lba2; - uint8_t lba3; /* LSB */ - } lba; - } u; - uint8_t secount; - addr24 dma_address; -} BIOSCMD; -#pragma pack(pop) -#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \ - (p->u.lba.lba2<<8) | p->u.lba.lba3) - - -extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset); -extern void x54x_buf_alloc(uint8_t id, uint8_t lun, int length); -extern void x54x_buf_free(uint8_t id, uint8_t lun); -extern uint8_t x54x_mbo_process(x54x_t *dev); -extern void x54x_wait_for_poll(void); -extern void x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len); -extern void x54x_io_remove(x54x_t *dev, uint32_t base, uint8_t len); -extern void x54x_mem_init(x54x_t *dev, uint32_t addr); -extern void x54x_mem_enable(x54x_t *dev); -extern void x54x_mem_set_addr(x54x_t *dev, uint32_t base); -extern void x54x_mem_disable(x54x_t *dev); -extern void *x54x_init(const device_t *info); -extern void x54x_close(void *priv); -extern void x54x_device_reset(void *priv); - - -#endif diff --git a/src - Cópia/serial.c b/src - Cópia/serial.c deleted file mode 100644 index 920f381c3..000000000 --- a/src - Cópia/serial.c +++ /dev/null @@ -1,386 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "machine/machine.h" -#include "io.h" -#include "pic.h" -#include "mem.h" -#include "rom.h" -#include "serial.h" -#include "timer.h" -#include "mouse.h" - - -enum -{ - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8 -}; - -SERIAL serial1, serial2; -int serial_do_log = 0; - - -#ifdef ENABLE_SERIAL_LOG -int serial_do_log = ENABLE_SERIAL_LOG; -#endif - - -static void -serial_log(const char *format, ...) -{ -#ifdef ENABLE_SERIAL_LOG - va_list ap; - - if (serial_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -void serial_reset() -{ - serial1.iir = serial1.ier = serial1.lcr = 0; - serial2.iir = serial2.ier = serial2.lcr = 0; - serial1.fifo_read = serial1.fifo_write = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} - -void serial_update_ints(SERIAL *serial) -{ - int stat = 0; - - serial->iir = 1; - - if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ - { - stat = 1; - serial->iir = 6; - } - else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ - { - stat = 1; - serial->iir = 4; - } - else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ - { - stat = 1; - serial->iir = 2; - } - else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ - { - stat = 1; - serial->iir = 0; - } - - if (stat && ((serial->mctrl & 8) || PCJR)) { - picintlevel(1 << serial->irq); - } else - picintc(1 << serial->irq); -} - -void serial_clear_fifo(SERIAL *serial) -{ - memset(serial->fifo, 0, 256); - serial->fifo_read = serial->fifo_write = 0; -} - -void serial_write_fifo(SERIAL *serial, uint8_t dat) -{ - serial->fifo[serial->fifo_write] = dat; - serial->fifo_write = (serial->fifo_write + 1) & 0xFF; - if (!(serial->lsr & 1)) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } -} - -uint8_t serial_read_fifo(SERIAL *serial) -{ - if (serial->fifo_read != serial->fifo_write) - { - serial->dat = serial->fifo[serial->fifo_read]; - serial->fifo_read = (serial->fifo_read + 1) & 0xFF; - } - return serial->dat; -} - -void serial_write(uint16_t addr, uint8_t val, void *p) -{ - SERIAL *serial = (SERIAL *)p; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - serial->dlab1 = val; - return; - } - serial->thr = val; - serial->lsr |= 0x20; - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - if (serial->mctrl & 0x10) - { - serial_write_fifo(serial, val); - } - break; - case 1: - if (serial->lcr & 0x80) - { - serial->dlab2 = val; - return; - } - serial->ier = val & 0xf; - serial_update_ints(serial); - break; - case 2: - serial->fcr = val; - break; - case 3: - serial->lcr = val; - break; - case 4: - if ((val & 2) && !(serial->mctrl & 2)) - { - if (serial->rcr_callback) - serial->rcr_callback((struct SERIAL *)serial, serial->rcr_callback_p); - } - serial->mctrl = val; - if (val & 0x10) - { - uint8_t new_msr; - - new_msr = (val & 0x0c) << 4; - new_msr |= (val & 0x02) ? 0x10: 0; - new_msr |= (val & 0x01) ? 0x20: 0; - - if ((serial->msr ^ new_msr) & 0x10) - new_msr |= 0x01; - if ((serial->msr ^ new_msr) & 0x20) - new_msr |= 0x02; - if ((serial->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((serial->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - serial->msr = new_msr; - } - break; - case 5: - serial->lsr = val; - if (serial->lsr & 0x01) - serial->int_status |= SERIAL_INT_RECEIVE; - if (serial->lsr & 0x1e) - serial->int_status |= SERIAL_INT_LSR; - if (serial->lsr & 0x20) - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - break; - case 6: - serial->msr = val; - if (serial->msr & 0x0f) - serial->int_status |= SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - serial->scratch = val; - break; - } -} - -uint8_t serial_read(uint16_t addr, void *p) -{ - SERIAL *serial = (SERIAL *)p; - uint8_t temp = 0; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - temp = serial->dlab1; - break; - } - - serial->lsr &= ~1; - serial->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(serial); - temp = serial_read_fifo(serial); - if (serial->fifo_read != serial->fifo_write) { - serial->recieve_delay = 1000LL * TIMER_USEC; - } - break; - case 1: - if (serial->lcr & 0x80) - temp = serial->dlab2; - else - temp = serial->ier; - break; - case 2: - temp = serial->iir; - if ((temp & 0xe) == 2) - { - serial->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - } - if (serial->fcr & 1) - temp |= 0xc0; - break; - case 3: - temp = serial->lcr; - break; - case 4: - temp = serial->mctrl; - break; - case 5: - if (serial->lsr & 0x20) - serial->lsr |= 0x40; - serial->lsr |= 0x20; - temp = serial->lsr; - if (serial->lsr & 0x1f) - serial->lsr &= ~0x1e; - serial->int_status &= ~SERIAL_INT_LSR; - serial_update_ints(serial); - break; - case 6: - temp = serial->msr; - serial->msr &= ~0x0f; - serial->int_status &= ~SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - temp = serial->scratch; - break; - } - return temp; -} - -void serial_recieve_callback(void *p) -{ - SERIAL *serial = (SERIAL *)p; - - serial->recieve_delay = 0; - - if (serial->fifo_read != serial->fifo_write) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } -} - -uint16_t base_address[2] = { 0x0000, 0x0000 }; - -void serial_remove(int port) -{ - if ((port < 1) || (port > 2)) - { - fatal("serial_remove(): Invalid serial port: %i\n", port); - exit(-1); - } - - if (!serial_enabled[port - 1]) - { - return; - } - - if (!base_address[port - 1]) - { - return; - } - - serial_log("Removing serial port %i at %04X...\n", port, base_address[port - 1]); - - switch(port) - { - case 1: - io_removehandler(base_address[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - base_address[0] = 0x0000; - break; - case 2: - io_removehandler(base_address[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - base_address[1] = 0x0000; - break; - } -} - -void serial_setup(int port, uint16_t addr, int irq) -{ - serial_log("Adding serial port %i at %04X...\n", port, addr); - - switch(port) - { - case 1: - if (!serial_enabled[0]) - { - return; - } - if (base_address[0] != 0x0000) - { - serial_remove(port); - } - if (addr != 0x0000) - { - base_address[0] = addr; - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - } - serial1.irq = irq; - break; - case 2: - if (!serial_enabled[1]) - { - return; - } - if (base_address[1] != 0x0000) - { - serial_remove(port); - } - if (addr != 0x0000) - { - base_address[1] = addr; - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - } - serial2.irq = irq; - break; - default: - fatal("serial_setup(): Invalid serial port: %i\n", port); - break; - } -} - -void serial_init(void) -{ - base_address[0] = 0x03f8; - base_address[1] = 0x02f8; - - if (serial_enabled[0]) - { - serial_log("Adding serial port 1...\n"); - memset(&serial1, 0, sizeof(serial1)); - io_sethandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = 4; - serial1.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); - } - if (serial_enabled[1]) - { - serial_log("Adding serial port 2...\n"); - memset(&serial2, 0, sizeof(serial2)); - io_sethandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = 3; - serial2.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); - } -} diff --git a/src - Cópia/serial.h b/src - Cópia/serial.h deleted file mode 100644 index 47eafdbd3..000000000 --- a/src - Cópia/serial.h +++ /dev/null @@ -1,119 +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. - * - * Definitions for the SERIAL card. - * - * Version: @(#)serial.h 1.0.7 2018/01/12 - * - * Author: Fred N. van Kempen, - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_SERIAL_H -# define EMU_SERIAL_H - - -#ifdef WALTJE_SERIAL -/* Default settings for the standard ports. */ -#define SERIAL1_ADDR 0x03f8 -#define SERIAL1_IRQ 4 -#define SERIAL2_ADDR 0x02f8 -#define SERIAL2_IRQ 3 - - -/* Supported UART types. */ -#define UART_TYPE_8250 0 /* standard NS8250 */ -#define UART_TYPE_8250A 1 /* updated NS8250(A) */ -#define UART_TYPE_16450 2 /* 16450 */ -#define UART_TYPE_16550 3 /* 16550 (broken fifo) */ -#define UART_TYPE_16550A 4 /* 16550a (working fifo) */ -#define UART_TYPE_16670 5 /* 16670 (64b fifo) */ - - -typedef struct _serial_ { - int8_t port; /* port number (1,2,..) */ - int8_t irq; /* IRQ channel used */ - uint16_t addr; /* I/O address used */ - int8_t type; /* UART type */ - uint8_t int_status; - - uint8_t lsr, thr, mctrl, rcr, /* UART registers */ - iir, ier, lcr, msr; - uint8_t dlab1, dlab2; - uint8_t dat, - hold; - uint8_t scratch; - uint8_t fcr; - - /* Data for the RTS-toggle callback. */ - void (*rts_callback)(void *); - void *rts_callback_p; - - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int64_t receive_delay; - - void *bh; /* BottomHalf handler */ -} SERIAL; - - -/* Functions. */ -extern void serial_init(void); -extern void serial_reset(void); -extern void serial_setup(int port, uint16_t addr, int irq); -extern void serial_remove(int port); -extern SERIAL *serial_attach(int, void *, void *); -extern int serial_link(int, char *); - -extern void serial_clear_fifo(SERIAL *); -extern void serial_write_fifo(SERIAL *, uint8_t, int); - - -#else - - -void serial_remove(int port); -void serial_setup(int port, uint16_t addr, int irq); -void serial_init(void); -void serial_reset(); - -struct SERIAL; - -typedef struct -{ - uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; - uint8_t dlab1,dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - int irq; - - void (*rcr_callback)(struct SERIAL *serial, void *p); - void *rcr_callback_p; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int64_t recieve_delay; -} SERIAL; - -void serial_clear_fifo(SERIAL *); -void serial_write_fifo(SERIAL *serial, uint8_t dat); - -extern SERIAL serial1, serial2; - -/* Default settings for the standard ports. */ -#define SERIAL1_ADDR 0x03f8 -#define SERIAL1_IRQ 4 -#define SERIAL2_ADDR 0x02f8 -#define SERIAL2_IRQ 3 -#endif - - -#endif /*EMU_SERIAL_H*/ diff --git a/src - Cópia/sio.h b/src - Cópia/sio.h deleted file mode 100644 index 233a9a57e..000000000 --- a/src - Cópia/sio.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Super I/O chips. - * - * Version: @(#)sio.h 1.0.2 2017/10/26 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef EMU_SIO_H -# define EMU_SIO_H - - -extern void superio_detect_init(void); -extern void fdc37c663_init(void); -extern void fdc37c665_init(void); -extern void fdc37c669_init(void); -extern void fdc37c932fr_init(void); -extern void fdc37c935_init(void); -extern void pc87306_init(void); -extern void um8669f_init(void); -extern void w83877f_init(void); - - -#endif /*EMU_SIO_H*/ diff --git a/src - Cópia/sio_detect.c b/src - Cópia/sio_detect.c deleted file mode 100644 index 275a9e643..000000000 --- a/src - Cópia/sio_detect.c +++ /dev/null @@ -1,64 +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. - * - * Super I/O chip detection code. - * - * Version: @(#)sio_detect.c 1.0.0 2018/01/16 - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "device.h" -#include "io.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "sio.h" - - -static uint8_t detect_regs[2]; - - -static void superio_detect_write(uint16_t port, uint8_t val, void *priv) -{ - pclog("superio_detect_write : port=%04x = %02X\n", port, val); - - detect_regs[port & 1] = val; - - return; -} - - -static uint8_t superio_detect_read(uint16_t port, void *priv) -{ - pclog("superio_detect_read : port=%04x = %02X\n", port, detect_regs[port & 1]); - - return detect_regs[port & 1]; -} - - -void superio_detect_init(void) -{ - device_add(&fdc_at_smc_device); - - io_sethandler(0x24, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x26, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x2e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x44, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x46, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x4e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x108, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x250, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x370, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); - io_sethandler(0x3f0, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); -} diff --git a/src - Cópia/sio_fdc37c669.c b/src - Cópia/sio_fdc37c669.c deleted file mode 100644 index 58547c55c..000000000 --- a/src - Cópia/sio_fdc37c669.c +++ /dev/null @@ -1,328 +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. - * - * Implementation of the SMC FDC37C669 Super I/O Chip. - * - * Version: @(#)sio_fdc37c669.c 1.0.9 2018/04/29 - * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "io.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 "sio.h" - - -static int fdc37c669_locked; -static int fdc37c669_rw_locked = 0; -static int fdc37c669_curreg = 0; -static uint8_t fdc37c669_regs[42]; -static uint8_t tries; -static fdc_t *fdc37c669_fdc; - -static uint16_t make_port(uint8_t reg) -{ - uint16_t p = 0; - - uint16_t mask = 0; - - switch(reg) - { - case 0x20: - case 0x21: - case 0x22: - mask = 0xfc; - break; - case 0x23: - mask = 0xff; - break; - case 0x24: - case 0x25: - mask = 0xfe; - break; - } - - p = ((uint16_t) (fdc37c669_regs[reg] & mask)) << 2; - if (reg == 0x22) - { - p |= 6; - } - - return p; -} - -void fdc37c669_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - uint8_t max = 42; - - if (index) - { - if ((val == 0x55) && !fdc37c669_locked) - { - if (tries) - { - fdc37c669_locked = 1; - tries = 0; - } - else - { - tries++; - } - } - else - { - if (fdc37c669_locked) - { - if (val < max) fdc37c669_curreg = val; - if (val == 0xaa) fdc37c669_locked = 0; - } - else - { - if (tries) - tries = 0; - } - } - } - else - { - if (fdc37c669_locked) - { - if ((fdc37c669_curreg < 0x18) && (fdc37c669_rw_locked)) return; - if ((fdc37c669_curreg >= 0x26) && (fdc37c669_curreg <= 0x27)) return; - if (fdc37c669_curreg == 0x29) return; - valxor = val ^ fdc37c669_regs[fdc37c669_curreg]; - fdc37c669_regs[fdc37c669_curreg] = val; - goto process_value; - } - } - return; - -process_value: - switch(fdc37c669_curreg) - { - case 0: -#if 0 - if (valxor & 3) - { - ide_pri_disable(); - if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable(); - break; - } -#endif - if (valxor & 8) - { - fdc_remove(fdc37c669_fdc); - if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(fdc37c669_fdc, make_port(0x20)); - } - break; - case 1: - if (valxor & 4) - { - lpt1_remove(); - if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] >= 0x40)) - { - lpt1_init(make_port(0x23)); - } - } - if (valxor & 7) - { - fdc37c669_rw_locked = (val & 8) ? 0 : 1; - } - break; - case 2: - if (valxor & 8) - { - serial_remove(1); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40)) - { - serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); - } - } - if (valxor & 0x80) - { - serial_remove(2); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40)) - { - serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F); - } - } - break; - case 3: - if (valxor & 2) fdc_update_enh_mode(fdc37c669_fdc, (val & 2) ? 1 : 0); - break; - case 5: - if (valxor & 0x18) fdc_update_densel_force(fdc37c669_fdc, (val & 0x18) >> 3); - if (valxor & 0x20) fdc_set_swap(fdc37c669_fdc, (val & 0x20) >> 5); - break; - case 0xB: - if (valxor & 3) fdc_update_rwc(fdc37c669_fdc, 0, val & 3); - if (valxor & 0xC) fdc_update_rwc(fdc37c669_fdc, 1, (val & 0xC) >> 2); - break; - case 0x20: - if (valxor & 0xfc) - { - fdc_remove(fdc37c669_fdc); - if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(fdc37c669_fdc, make_port(0x20)); - } - break; - case 0x21: - case 0x22: -#if 0 - if (valxor & 0xfc) - { - ide_pri_disable(); - switch (fdc37c669_curreg) - { - case 0x21: - ide_set_base(0, make_port(0x21)); - break; - case 0x22: - ide_set_side(0, make_port(0x22)); - break; - } - if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable(); - } -#endif - break; - case 0x23: - if (valxor) - { - lpt1_remove(); - if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] >= 0x40)) - { - lpt1_init(make_port(0x23)); - } - } - break; - case 0x24: - if (valxor & 0xfe) - { - serial_remove(1); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40)) - { - serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); - } - } - break; - case 0x25: - if (valxor & 0xfe) - { - serial_remove(2); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40)) - { - serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F); - } - } - break; - case 0x28: - if (valxor & 0xf) - { - serial_remove(2); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40)) - { - serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F); - } - } - if (valxor & 0xf0) - { - serial_remove(1); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40)) - { - serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); - } - } - break; - } -} - -uint8_t fdc37c669_read(uint16_t port, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - - if (!fdc37c669_locked) - { - return 0xFF; - } - - if (index) - return fdc37c669_curreg; - else - { - if ((fdc37c669_curreg < 0x18) && (fdc37c669_rw_locked)) return 0xff; - return fdc37c669_regs[fdc37c669_curreg]; - } -} - -void fdc37c669_reset(void) -{ - fdc_reset(fdc37c669_fdc); - - serial_remove(1); - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - - serial_remove(2); - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - - lpt2_remove(); - - lpt1_remove(); - lpt1_init(0x378); - - memset(fdc37c669_regs, 0, 42); - fdc37c669_regs[0] = 0x28; - fdc37c669_regs[1] = 0x9C; - fdc37c669_regs[2] = 0x88; - fdc37c669_regs[3] = 0x78; - fdc37c669_regs[4] = 0; - fdc37c669_regs[5] = 0; - fdc37c669_regs[6] = 0xFF; - fdc37c669_regs[7] = 0; - fdc37c669_regs[8] = 0; - fdc37c669_regs[9] = 0; - fdc37c669_regs[0xA] = 0; - fdc37c669_regs[0xB] = 0; - fdc37c669_regs[0xC] = 0; - fdc37c669_regs[0xD] = 3; - fdc37c669_regs[0xE] = 2; - fdc37c669_regs[0x1E] = 0x80; /* Gameport controller. */ - fdc37c669_regs[0x20] = (0x3f0 >> 2) & 0xfc; - fdc37c669_regs[0x21] = (0x1f0 >> 2) & 0xfc; - fdc37c669_regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; - fdc37c669_regs[0x23] = (0x378 >> 2); - fdc37c669_regs[0x24] = (0x3f8 >> 2) & 0xfe; - fdc37c669_regs[0x25] = (0x2f8 >> 2) & 0xfe; - fdc37c669_regs[0x26] = (2 << 4) | 3; - fdc37c669_regs[0x27] = (6 << 4) | 7; - fdc37c669_regs[0x28] = (4 << 4) | 3; - - fdc37c669_locked = 0; - fdc37c669_rw_locked = 0; -} - -void fdc37c669_init() -{ - fdc37c669_fdc = device_add(&fdc_at_smc_device); - - io_sethandler(0x3f0, 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, NULL); - - fdc37c669_reset(); -} diff --git a/src - Cópia/sio_fdc37c66x.c b/src - Cópia/sio_fdc37c66x.c deleted file mode 100644 index a97ee26e9..000000000 --- a/src - Cópia/sio_fdc37c66x.c +++ /dev/null @@ -1,331 +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. - * - * Implementation of the SMC FDC37C663 and FDC37C665 Super - * I/O Chips. - * - * Version: @(#)sio_fdc37c66x.c 1.0.11 2018/04/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "io.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 "sio.h" - - -static uint8_t fdc37c66x_lock[2]; -static int fdc37c66x_curreg; -static uint8_t fdc37c66x_regs[16]; -static int com3_addr, com4_addr; -static fdc_t *fdc37c66x_fdc; - - -static void write_lock(uint8_t val) -{ - if (val == 0x55 && fdc37c66x_lock[1] == 0x55) - fdc_3f1_enable(fdc37c66x_fdc, 0); - if (fdc37c66x_lock[0] == 0x55 && fdc37c66x_lock[1] == 0x55 && val != 0x55) - fdc_3f1_enable(fdc37c66x_fdc, 1); - - fdc37c66x_lock[0] = fdc37c66x_lock[1]; - fdc37c66x_lock[1] = val; -} - -static void ide_handler() -{ -#if 0 - uint16_t or_value = 0; - if ((romset == ROM_440FX) || (romset == ROM_R418) || (romset == ROM_MB500N)) - { - return; - } - ide_pri_disable(); - if (fdc37c66x_regs[0] & 1) - { - if (fdc37c66x_regs[5] & 2) - { - or_value = 0; - } - else - { - or_value = 0x800; - } - ide_set_base(0, 0x170 | or_value); - ide_set_side(0, 0x376 | or_value); - ide_pri_enable(); - } -#endif -} - -static void set_com34_addr() -{ - switch (fdc37c66x_regs[1] & 0x60) - { - case 0x00: - com3_addr = 0x338; - com4_addr = 0x238; - break; - case 0x20: - com3_addr = 0x3e8; - com4_addr = 0x2e8; - break; - case 0x40: - com3_addr = 0x3e8; - com4_addr = 0x2e0; - break; - case 0x60: - com3_addr = 0x220; - com4_addr = 0x228; - break; - } -} - -static void set_serial1_addr() -{ - if (fdc37c66x_regs[2] & 4) - { - switch (fdc37c66x_regs[2] & 3) - { - case 0: - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - break; - - case 1: - serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); - break; - - case 2: - serial_setup(1, com3_addr, 4); - break; - - case 3: - serial_setup(1, com4_addr, 3); - break; - } - } -} - -static void set_serial2_addr() -{ - if (fdc37c66x_regs[2] & 0x40) - { - switch (fdc37c66x_regs[2] & 0x30) - { - case 0: - serial_setup(2, SERIAL1_ADDR, SERIAL1_IRQ); - break; - - case 1: - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - break; - - case 2: - serial_setup(2, com3_addr, 4); - break; - - case 3: - serial_setup(2, com4_addr, 3); - break; - } - } -} - -static void lpt1_handler() -{ - lpt1_remove(); - switch (fdc37c66x_regs[1] & 3) - { - case 1: - lpt1_init(0x3bc); - break; - case 2: - lpt1_init(0x378); - break; - case 3: - lpt1_init(0x278); - break; - } -} - -static void fdc37c66x_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t valxor = 0; - if (fdc37c66x_lock[0] == 0x55 && fdc37c66x_lock[1] == 0x55) - { - if (port == 0x3f0) - { - if (val == 0xaa) - write_lock(val); - else - fdc37c66x_curreg = val; -#if 0 - if (fdc37c66x_curreg != 0) - { - fdc37c66x_curreg = val & 0xf; - } - else - { - /* Hardcode the IDE to AT type. */ - fdc37c66x_curreg = (val & 0xf) | 2; - } -#endif - } - else - { - if (fdc37c66x_curreg > 15) - return; - - valxor = val ^ fdc37c66x_regs[fdc37c66x_curreg]; - fdc37c66x_regs[fdc37c66x_curreg] = val; - - switch(fdc37c66x_curreg) - { - case 0: - if (valxor & 1) - { - ide_handler(); - } - break; - case 1: - if (valxor & 3) - { - lpt1_handler(); - } - if (valxor & 0x60) - { - serial_remove(1); - set_com34_addr(); - set_serial1_addr(); - set_serial2_addr(); - } - break; - case 2: - if (valxor & 7) - { - serial_remove(1); - set_serial1_addr(); - } - if (valxor & 0x70) - { - serial_remove(2); - set_serial2_addr(); - } - break; - case 3: - if (valxor & 2) - { - fdc_update_enh_mode(fdc37c66x_fdc, (fdc37c66x_regs[3] & 2) ? 1 : 0); - } - break; - case 5: - if (valxor & 2) - { - ide_handler(); - } - if (valxor & 0x18) - { - fdc_update_densel_force(fdc37c66x_fdc, (fdc37c66x_regs[5] & 0x18) >> 3); - } - if (valxor & 0x20) - { - fdc_set_swap(fdc37c66x_fdc, (fdc37c66x_regs[5] & 0x20) >> 5); - } - break; - } - } - } - else - { - if (port == 0x3f0) - write_lock(val); - } -} - -static uint8_t fdc37c66x_read(uint16_t port, void *priv) -{ - if (fdc37c66x_lock[0] == 0x55 && fdc37c66x_lock[1] == 0x55) - { - if (port == 0x3f1) - return fdc37c66x_regs[fdc37c66x_curreg]; - } - return 0xff; -} - -static void fdc37c66x_reset(void) -{ - com3_addr = 0x338; - com4_addr = 0x238; - - serial_remove(1); - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - - serial_remove(2); - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - - lpt2_remove(); - - lpt1_remove(); - lpt1_init(0x378); - - fdc_reset(fdc37c66x_fdc); - - memset(fdc37c66x_lock, 0, 2); - memset(fdc37c66x_regs, 0, 16); - fdc37c66x_regs[0x0] = 0x3a; - fdc37c66x_regs[0x1] = 0x9f; - fdc37c66x_regs[0x2] = 0xdc; - fdc37c66x_regs[0x3] = 0x78; - fdc37c66x_regs[0x6] = 0xff; - fdc37c66x_regs[0xe] = 0x01; -} - -static void fdc37c663_reset(void) -{ - fdc37c66x_reset(); - fdc37c66x_regs[0xd] = 0x63; -} - -static void fdc37c665_reset(void) -{ - fdc37c66x_reset(); - fdc37c66x_regs[0xd] = 0x65; -} - -void fdc37c663_init() -{ - fdc37c66x_fdc = device_add(&fdc_at_smc_device); - - io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL); - - fdc37c663_reset(); -} - -void fdc37c665_init() -{ - fdc37c66x_fdc = device_add(&fdc_at_smc_device); - - io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL); - - fdc37c665_reset(); -} diff --git a/src - Cópia/sio_fdc37c93x.c b/src - Cópia/sio_fdc37c93x.c deleted file mode 100644 index 5d2f7816d..000000000 --- a/src - Cópia/sio_fdc37c93x.c +++ /dev/null @@ -1,567 +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. - * - * Implementation of the SMC FDC37C932FR and FDC37C935 Super - * I/O Chips. - * - * Version: @(#)sio_fdc37c93x.c 1.0.13 2018/04/29 - * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "io.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 "sio.h" - - -static int fdc37c93x_locked; -static int fdc37c93x_curreg = 0; -static int fdc37c93x_gpio_reg = 0; -static uint8_t fdc37c93x_regs[48]; -static uint8_t fdc37c93x_ld_regs[10][256]; -static uint16_t fdc37c93x_gpio_base = 0x00EA; -static fdc_t *fdc37c93x_fdc; - -static uint8_t tries; - -static uint16_t make_port(uint8_t ld) -{ - uint16_t r0 = fdc37c93x_ld_regs[ld][0x60]; - uint16_t r1 = fdc37c93x_ld_regs[ld][0x61]; - - uint16_t p = (r0 << 8) + r1; - - return p; -} - -static uint8_t fdc37c93x_gpio_read(uint16_t port, void *priv) -{ - return fdc37c93x_gpio_reg; -} - -static void fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) -{ - fdc37c93x_gpio_reg = val; -} - -static void fdc37c93x_fdc_handler(void) -{ - uint16_t ld_port = 0; - - uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << 0)); - uint8_t local_enable = !!fdc37c93x_ld_regs[0][0x30]; - - fdc_remove(fdc37c93x_fdc); - if (global_enable && local_enable) - { - ld_port = make_port(0); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) { - fdc_set_base(fdc37c93x_fdc, ld_port); - } - } -} - -static void fdc37c93x_lpt_handler(void) -{ - uint16_t ld_port = 0; - - uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << 3)); - uint8_t local_enable = !!fdc37c93x_ld_regs[3][0x30]; - - lpt1_remove(); - if (global_enable && local_enable) - { - ld_port = make_port(3); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - lpt1_init(ld_port); - } -} - -static void fdc37c93x_serial_handler(int uart) -{ - uint16_t ld_port = 0; - - uint8_t uart_no = 3 + uart; - - uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << uart_no)); - uint8_t local_enable = !!fdc37c93x_ld_regs[uart_no][0x30]; - - serial_remove(uart); - if (global_enable && local_enable) - { - ld_port = make_port(uart_no); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) - serial_setup(uart, ld_port, fdc37c93x_ld_regs[uart_no][0x70]); - } -} - -static void fdc37c93x_auxio_handler(void) -{ - uint16_t ld_port = 0; - - uint8_t local_enable = !!fdc37c93x_ld_regs[8][0x30]; - - io_removehandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL); - if (local_enable) - { - fdc37c93x_gpio_base = ld_port = make_port(8); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFF)) - io_sethandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL); - } -} - -#define AB_RST 0x80 - -typedef struct { - uint8_t control; - uint8_t status; - uint8_t own_addr; - uint8_t data; - uint8_t clock; - uint16_t base; -} access_bus_t; - -static access_bus_t access_bus; - -static uint8_t fdc37c932fr_access_bus_read(uint16_t port, void *priv) -{ - switch(port & 3) { - case 0: - return (access_bus.status & 0xBF); - break; - case 1: - return (access_bus.own_addr & 0x7F); - break; - case 2: - return access_bus.data; - break; - case 3: - return (access_bus.clock & 0x87); - break; - default: - return 0xFF; - } -} - -static void fdc37c932fr_access_bus_write(uint16_t port, uint8_t val, void *priv) -{ - switch(port & 3) { - case 0: - access_bus.control = (val & 0xCF); - break; - case 1: - access_bus.own_addr = (val & 0x7F); - break; - case 2: - access_bus.data = val; - break; - case 3: - access_bus.clock &= 0x80; - access_bus.clock |= (val & 0x07); - break; - } -} - - -static void fdc37c932fr_access_bus_handler(void) -{ - uint16_t ld_port = 0; - - uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << 6)); - uint8_t local_enable = !!fdc37c93x_ld_regs[9][0x30]; - - io_removehandler(access_bus.base, 0x0004, fdc37c932fr_access_bus_read, NULL, NULL, fdc37c932fr_access_bus_write, NULL, NULL, NULL); - if (global_enable && local_enable) - { - access_bus.base = ld_port = make_port(9); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - io_sethandler(access_bus.base, 0x0004, fdc37c932fr_access_bus_read, NULL, NULL, fdc37c932fr_access_bus_write, NULL, NULL, NULL); - } -} - -static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - - if (index) - { - if ((val == 0x55) && !fdc37c93x_locked) - { - if (tries) - { - fdc37c93x_locked = 1; - fdc_3f1_enable(fdc37c93x_fdc, 0); - tries = 0; - } - else - { - tries++; - } - } - else - { - if (fdc37c93x_locked) - { - if (val == 0xaa) - { - fdc37c93x_locked = 0; - fdc_3f1_enable(fdc37c93x_fdc, 1); - return; - } - fdc37c93x_curreg = val; - } - else - { - if (tries) - tries = 0; - } - } - } - else - { - if (fdc37c93x_locked) - { - if (fdc37c93x_curreg < 48) - { - valxor = val ^ fdc37c93x_regs[fdc37c93x_curreg]; - if ((val == 0x20) || (val == 0x21)) - return; - fdc37c93x_regs[fdc37c93x_curreg] = val; - goto process_value; - } - else - { - valxor = val ^ fdc37c93x_ld_regs[fdc37c93x_regs[7]][fdc37c93x_curreg]; - if (((fdc37c93x_curreg & 0xF0) == 0x70) && (fdc37c93x_regs[7] < 4)) return; - /* Block writes to IDE configuration. */ - if (fdc37c93x_regs[7] == 1) return; - if (fdc37c93x_regs[7] == 2) return; - if ((fdc37c93x_regs[7] > 5) && (fdc37c93x_regs[7] != 8) && (fdc37c93x_regs[7] != 9)) return; - if ((fdc37c93x_regs[7] == 9) && (fdc37c93x_regs[0x20] != 3)) return; - fdc37c93x_ld_regs[fdc37c93x_regs[7]][fdc37c93x_curreg] = val; - goto process_value; - } - } - } - return; - -process_value: - if (fdc37c93x_curreg < 48) - { - switch(fdc37c93x_curreg) - { - case 0x22: - if (valxor & 0x01) - fdc37c93x_fdc_handler(); - if (valxor & 0x08) - fdc37c93x_lpt_handler(); - if (valxor & 0x10) - fdc37c93x_serial_handler(1); - if (valxor & 0x20) - fdc37c93x_serial_handler(2); - break; - } - - return; - } - - switch(fdc37c93x_regs[7]) - { - case 0: - /* FDD */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - if (valxor) - { - fdc37c93x_fdc_handler(); - } - break; - case 0xF0: - if (valxor & 0x01) fdc_update_enh_mode(fdc37c93x_fdc, val & 0x01); - if (valxor & 0x10) fdc_set_swap(fdc37c93x_fdc, (val & 0x10) >> 4); - break; - case 0xF1: - if (valxor & 0xC) fdc_update_densel_force(fdc37c93x_fdc, (val & 0xC) >> 2); - break; - case 0xF2: - if (valxor & 0xC0) fdc_update_rwc(fdc37c93x_fdc, 3, (valxor & 0xC0) >> 6); - if (valxor & 0x30) fdc_update_rwc(fdc37c93x_fdc, 2, (valxor & 0x30) >> 4); - if (valxor & 0x0C) fdc_update_rwc(fdc37c93x_fdc, 1, (valxor & 0x0C) >> 2); - if (valxor & 0x03) fdc_update_rwc(fdc37c93x_fdc, 0, (valxor & 0x03)); - break; - case 0xF4: - if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 0, (val & 0x18) >> 3); - break; - case 0xF5: - if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 1, (val & 0x18) >> 3); - break; - case 0xF6: - if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 2, (val & 0x18) >> 3); - break; - case 0xF7: - if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 3, (val & 0x18) >> 3); - break; - } - break; - case 3: - /* Parallel port */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - if (valxor) - { - fdc37c93x_lpt_handler(); - } - break; - } - break; - case 4: - /* Serial port 1 */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - { - fdc37c93x_serial_handler(1); - } - break; - } - break; - case 5: - /* Serial port 2 */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - { - fdc37c93x_serial_handler(2); - } - break; - } - break; - case 8: - /* Auxiliary I/O */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - { - fdc37c93x_auxio_handler(); - } - break; - } - break; - case 9: - /* Access bus (FDC37C932FR only) */ - switch(fdc37c93x_curreg) - { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - { - fdc37c932fr_access_bus_handler(); - } - break; - } - break; - } -} - -static uint8_t fdc37c93x_read(uint16_t port, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - - if (!fdc37c93x_locked) - { - return 0xff; - } - - if (index) - return fdc37c93x_curreg; - else - { - if (fdc37c93x_curreg < 0x30) - { - return fdc37c93x_regs[fdc37c93x_curreg]; - } - else - { - if ((fdc37c93x_regs[7] == 0) && (fdc37c93x_curreg == 0xF2)) return (fdc_get_rwc(fdc37c93x_fdc, 0) | (fdc_get_rwc(fdc37c93x_fdc, 1) << 2)); - return fdc37c93x_ld_regs[fdc37c93x_regs[7]][fdc37c93x_curreg]; - } - } -} - -static void fdc37c93x_reset(void) -{ - int i = 0; - - memset(fdc37c93x_regs, 0, 48); - - fdc37c93x_regs[0x03] = 3; - fdc37c93x_regs[0x21] = 1; - fdc37c93x_regs[0x22] = 0x39; - fdc37c93x_regs[0x24] = 4; - fdc37c93x_regs[0x26] = 0xF0; - fdc37c93x_regs[0x27] = 3; - - for (i = 0; i < 10; i++) - { - memset(fdc37c93x_ld_regs[i], 0, 256); - } - - /* Logical device 0: FDD */ - fdc37c93x_ld_regs[0][0x30] = 1; - fdc37c93x_ld_regs[0][0x60] = 3; - fdc37c93x_ld_regs[0][0x61] = 0xF0; - fdc37c93x_ld_regs[0][0x70] = 6; - fdc37c93x_ld_regs[0][0x74] = 2; - fdc37c93x_ld_regs[0][0xF0] = 0xE; - fdc37c93x_ld_regs[0][0xF2] = 0xFF; - - /* Logical device 1: IDE1 */ - fdc37c93x_ld_regs[1][0x30] = 0; - fdc37c93x_ld_regs[1][0x60] = 1; - fdc37c93x_ld_regs[1][0x61] = 0xF0; - fdc37c93x_ld_regs[1][0x62] = 3; - fdc37c93x_ld_regs[1][0x63] = 0xF6; - fdc37c93x_ld_regs[1][0x70] = 0xE; - fdc37c93x_ld_regs[1][0xF0] = 0xC; - - /* Logical device 2: IDE2 */ - fdc37c93x_ld_regs[2][0x30] = 0; - fdc37c93x_ld_regs[2][0x60] = 1; - fdc37c93x_ld_regs[2][0x61] = 0x70; - fdc37c93x_ld_regs[2][0x62] = 3; - fdc37c93x_ld_regs[2][0x63] = 0x76; - fdc37c93x_ld_regs[2][0x70] = 0xF; - - /* Logical device 3: Parallel Port */ - fdc37c93x_ld_regs[3][0x30] = 1; - fdc37c93x_ld_regs[3][0x60] = 3; - fdc37c93x_ld_regs[3][0x61] = 0x78; - fdc37c93x_ld_regs[3][0x70] = 7; - fdc37c93x_ld_regs[3][0x74] = 4; - fdc37c93x_ld_regs[3][0xF0] = 0x3C; - - /* Logical device 4: Serial Port 1 */ - fdc37c93x_ld_regs[4][0x30] = 1; - fdc37c93x_ld_regs[4][0x60] = 3; - fdc37c93x_ld_regs[4][0x61] = 0xf8; - fdc37c93x_ld_regs[4][0x70] = 4; - fdc37c93x_ld_regs[4][0xF0] = 3; - serial_setup(1, 0x3f8, fdc37c93x_ld_regs[4][0x70]); - - /* Logical device 5: Serial Port 2 */ - fdc37c93x_ld_regs[5][0x30] = 1; - fdc37c93x_ld_regs[5][0x60] = 2; - fdc37c93x_ld_regs[5][0x61] = 0xf8; - fdc37c93x_ld_regs[5][0x70] = 3; - fdc37c93x_ld_regs[5][0x74] = 4; - fdc37c93x_ld_regs[5][0xF1] = 2; - fdc37c93x_ld_regs[5][0xF2] = 3; - serial_setup(2, 0x2f8, fdc37c93x_ld_regs[5][0x70]); - - /* Logical device 6: RTC */ - fdc37c93x_ld_regs[6][0x63] = 0x70; - fdc37c93x_ld_regs[6][0xF4] = 3; - - /* Logical device 7: Keyboard */ - fdc37c93x_ld_regs[7][0x30] = 1; - fdc37c93x_ld_regs[7][0x61] = 0x60; - fdc37c93x_ld_regs[7][0x70] = 1; - - /* Logical device 8: Auxiliary I/O */ - fdc37c93x_ld_regs[8][0x30] = 1; - fdc37c93x_ld_regs[8][0x61] = 0xEA; - - /* Logical device 8: AUX I/O */ - - /* Logical device 9: ACCESS.bus */ - - io_removehandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL); - fdc37c93x_gpio_base = 0x00EA; - io_sethandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL); - - fdc37c93x_lpt_handler(); - fdc37c93x_serial_handler(1); - fdc37c93x_serial_handler(2); - fdc37c93x_auxio_handler(); - - fdc_reset(fdc37c93x_fdc); - - fdc37c93x_locked = 0; -} - -static void fdc37c932fr_reset(void) -{ - fdc37c93x_reset(); - - fdc37c93x_regs[0x20] = 3; - - fdc37c932fr_access_bus_handler(); -} - -static void fdc37c935_reset(void) -{ - fdc37c93x_reset(); - - fdc37c93x_regs[0x20] = 2; -} - -static void fdc37c93x_init(void) -{ - lpt2_remove(); - - fdc37c93x_fdc = device_add(&fdc_at_smc_device); - - fdc37c93x_gpio_reg = 0xFD; - - io_sethandler(0x3f0, 0x0002, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, NULL); -} - -void fdc37c932fr_init(void) -{ - fdc37c93x_init(); - fdc37c932fr_reset(); -} - -void fdc37c935_init(void) -{ - fdc37c93x_init(); - fdc37c935_reset(); -} diff --git a/src - Cópia/sio_pc87306.c b/src - Cópia/sio_pc87306.c deleted file mode 100644 index 3761d53d5..000000000 --- a/src - Cópia/sio_pc87306.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the NatSemi PC87306 Super I/O chip. - * - * Version: @(#)sio_pc87306.c 1.0.12 2018/05/11 - * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "io.h" -#include "device.h" -#include "lpt.h" -#include "mem.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 "machine/machine.h" -#include "sio.h" - - -static int pc87306_curreg; -static uint8_t pc87306_regs[29]; -static uint8_t pc87306_gpio[2] = {0xFF, 0xFB}; -static fdc_t *pc87306_fdc; -static uint8_t tries; -static uint16_t lpt_port; - -void pc87306_gpio_remove(); -void pc87306_gpio_init(); - -void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) -{ - pc87306_gpio[port & 1] = val; -} - -uint8_t uart1_int() -{ - uint8_t fer_irq, pnp1_irq; - fer_irq = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ - pnp1_irq = ((pc87306_regs[0x1C] >> 2) & 1) ? 4 : 3; - return (pc87306_regs[0x1C] & 1) ? pnp1_irq : fer_irq; -} - -uint8_t uart2_int() -{ - uint8_t fer_irq, pnp1_irq; - fer_irq = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ - pnp1_irq = ((pc87306_regs[0x1C] >> 6) & 1) ? 4 : 3; - return (pc87306_regs[0x1C] & 1) ? pnp1_irq : fer_irq; -} - -void lpt1_handler() -{ - int temp; - uint16_t lptba; - temp = pc87306_regs[0x01] & 3; - lptba = ((uint16_t) pc87306_regs[0x19]) << 2; - if (pc87306_regs[0x1B] & 0x10) { - if (pc87306_regs[0x1B] & 0x20) - lpt_port = 0x278; - else - lpt_port = 0x378; - } else { - switch (temp) { - case 0: - lpt_port = 0x378; - break; - case 1: - lpt_port = lptba; - break; - case 2: - lpt_port = 0x278; - break; - case 3: - lpt_port = 0x000; - break; - } - } - if (lpt_port) - lpt1_init(lpt_port); -} - -void serial1_handler() -{ - int temp; - temp = (pc87306_regs[1] >> 2) & 3; - switch (temp) - { - case 0: serial_setup(1, SERIAL1_ADDR, uart1_int()); break; - case 1: serial_setup(1, SERIAL2_ADDR, uart1_int()); break; - case 2: - switch ((pc87306_regs[1] >> 6) & 3) - { - case 0: serial_setup(1, 0x3e8, uart1_int()); break; - case 1: serial_setup(1, 0x338, uart1_int()); break; - case 2: serial_setup(1, 0x2e8, uart1_int()); break; - case 3: serial_setup(1, 0x220, uart1_int()); break; - } - break; - case 3: - switch ((pc87306_regs[1] >> 6) & 3) - { - case 0: serial_setup(1, 0x2e8, uart1_int()); break; - case 1: serial_setup(1, 0x238, uart1_int()); break; - case 2: serial_setup(1, 0x2e0, uart1_int()); break; - case 3: serial_setup(1, 0x228, uart1_int()); break; - } - break; - } -} - -void serial2_handler() -{ - int temp; - temp = (pc87306_regs[1] >> 4) & 3; - switch (temp) - { - case 0: serial_setup(2, SERIAL1_ADDR, uart2_int()); break; - case 1: serial_setup(2, SERIAL2_ADDR, uart2_int()); break; - case 2: - switch ((pc87306_regs[1] >> 6) & 3) - { - case 0: serial_setup(2, 0x3e8, uart2_int()); break; - case 1: serial_setup(2, 0x338, uart2_int()); break; - case 2: serial_setup(2, 0x2e8, uart2_int()); break; - case 3: serial_setup(2, 0x220, uart2_int()); break; - } - break; - case 3: - switch ((pc87306_regs[1] >> 6) & 3) - { - case 0: serial_setup(2, 0x2e8, uart2_int()); break; - case 1: serial_setup(2, 0x238, uart2_int()); break; - case 2: serial_setup(2, 0x2e0, uart2_int()); break; - case 3: serial_setup(2, 0x228, uart2_int()); break; - } - break; - } -} - -void pc87306_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t index, valxor; - - index = (port & 1) ? 0 : 1; - - if (index) - { - pc87306_curreg = val & 0x1f; - tries = 0; - return; - } - else - { - if (tries) - { - if ((pc87306_curreg == 0) && (val == 8)) - { - val = 0x4b; - } - valxor = val ^ pc87306_regs[pc87306_curreg]; - tries = 0; - if ((pc87306_curreg == 0x19) && !(pc87306_regs[0x1B] & 0x40)) - { - return; - } - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)/* && (pc87306_curreg != 0x18)*/) - { - if (pc87306_curreg == 0) - { - val &= 0x5f; - } - if (((pc87306_curreg == 0x0F) || (pc87306_curreg == 0x12)) && valxor) - { - pc87306_gpio_remove(); - } - pc87306_regs[pc87306_curreg] = val; - goto process_value; - } - } - else - { - tries++; - return; - } - } - return; - -process_value: - switch(pc87306_curreg) - { - case 0: - if (valxor & 1) - { - lpt1_remove(); - if (val & 1) - { - lpt1_handler(); - } - } - - if (valxor & 2) - { - serial_remove(1); - if (val & 2) - { - serial1_handler(); - } - } - if (valxor & 4) - { - serial_remove(2); - if (val & 4) - { - serial2_handler(); - } - } - if (valxor & 0x28) - { - fdc_remove(pc87306_fdc); - if (val & 8) - { - fdc_set_base(pc87306_fdc, (val & 0x20) ? 0x370 : 0x3f0); - } - } - break; - case 1: - if (valxor & 3) - { - lpt1_remove(); - if (pc87306_regs[0] & 1) - { - lpt1_handler(); - } - } - - if (valxor & 0xcc) - { - if (pc87306_regs[0] & 2) - { - serial1_handler(); - } - else - { - serial_remove(1); - } - } - - if (valxor & 0xf0) - { - if (pc87306_regs[0] & 4) - { - serial2_handler(); - } - else - { - serial_remove(2); - } - } - break; - case 2: - if (valxor & 1) - { - if (val & 1) - { - lpt1_remove(); - serial_remove(1); - serial_remove(2); - fdc_remove(pc87306_fdc); - } - else - { - if (pc87306_regs[0] & 1) - { - lpt1_handler(); - } - if (pc87306_regs[0] & 2) - { - serial1_handler(); - } - if (pc87306_regs[0] & 4) - { - serial2_handler(); - } - if (pc87306_regs[0] & 8) - { - fdc_set_base(pc87306_fdc, (pc87306_regs[0] & 0x20) ? 0x370 : 0x3f0); - } - } - } - break; - case 9: - if (valxor & 0x44) - { - fdc_update_enh_mode(pc87306_fdc, (val & 4) ? 1 : 0); - fdc_update_densel_polarity(pc87306_fdc, (val & 0x40) ? 1 : 0); - } - break; - case 0xF: - if (valxor) - { - pc87306_gpio_init(); - } - break; - case 0x12: - if (valxor & 0x30) - { - pc87306_gpio_init(); - } - break; - case 0x19: - if (valxor) - { - lpt1_remove(); - if (pc87306_regs[0] & 1) - { - lpt1_handler(); - } - } - break; - case 0x1B: - if (valxor & 0x70) - { - lpt1_remove(); - if (!(val & 0x40)) - { - pc87306_regs[0x19] = 0xEF; - } - if (pc87306_regs[0] & 1) - { - lpt1_handler(); - } - } - break; - case 0x1C: - if (valxor) - { - if (pc87306_regs[0] & 2) - { - serial1_handler(); - } - if (pc87306_regs[0] & 4) - { - serial2_handler(); - } - } - break; - } -} - -uint8_t pc87306_gpio_read(uint16_t port, void *priv) -{ - return pc87306_gpio[port & 1]; -} - -uint8_t pc87306_read(uint16_t port, void *priv) -{ - uint8_t index; - index = (port & 1) ? 0 : 1; - - tries = 0; - - if (index) - { - return pc87306_curreg & 0x1f; - } - else - { - if (pc87306_curreg >= 28) - { - return 0xff; - } - else if (pc87306_curreg == 8) - { - return 0x70; - } - else - { - return pc87306_regs[pc87306_curreg]; - } - } -} - -void pc87306_gpio_remove() -{ - io_removehandler(pc87306_regs[0xF] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); -} - -void pc87306_gpio_init() -{ - if ((pc87306_regs[0x12]) & 0x10) - { - io_sethandler(pc87306_regs[0xF] << 2, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); - } - - if ((pc87306_regs[0x12]) & 0x20) - { - io_sethandler((pc87306_regs[0xF] << 2) + 1, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); - } -} - -void pc87306_reset(void) -{ - memset(pc87306_regs, 0, 29); - - pc87306_regs[0] = 0x0B; - pc87306_regs[1] = 0x01; - pc87306_regs[3] = 0x01; - pc87306_regs[5] = 0x0D; - pc87306_regs[8] = 0x70; - pc87306_regs[9] = 0xC0; - pc87306_regs[0xB] = 0x80; - pc87306_regs[0xF] = 0x1E; - pc87306_regs[0x12] = 0x30; - pc87306_regs[0x19] = 0xEF; - /* - 0 = 360 rpm @ 500 kbps for 3.5" - 1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5" - */ - lpt1_remove(); - lpt2_remove(); - lpt1_handler(); - serial_remove(1); - serial_remove(2); - serial1_handler(); - serial2_handler(); - fdc_reset(pc87306_fdc); - pc87306_gpio_init(); -} - -void pc87306_init() -{ - pc87306_fdc = device_add(&fdc_at_nsc_device); - - lpt2_remove(); - - pc87306_reset(); - - io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, NULL); -} diff --git a/src - Cópia/sio_um8669f.c b/src - Cópia/sio_um8669f.c deleted file mode 100644 index fb991fede..000000000 --- a/src - Cópia/sio_um8669f.c +++ /dev/null @@ -1,295 +0,0 @@ -/*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 "86box.h" -#include "device.h" -#include "io.h" -#include "pci.h" -#include "lpt.h" -#include "serial.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "sio.h" - - -typedef struct um8669f_t -{ - int locked; - int cur_reg_108; - uint8_t regs_108[256]; - - int cur_reg; - int cur_device; - struct - { - int enable; - uint16_t addr; - int irq; - int dma; - } dev[8]; - - fdc_t *fdc; - int pnp_active; -} um8669f_t; - - -static um8669f_t um8669f_global; - - -#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 - - -void um8669f_pnp_write(uint16_t port, uint8_t val, void *p) -{ - um8669f_t *um8669f = (um8669f_t *)p; - - uint8_t valxor = 0; - - if (port == 0x279) - um8669f->cur_reg = val; - else - { - if (um8669f->cur_reg == REG_DEVICE) - um8669f->cur_device = val & 7; - else - { - switch (um8669f->cur_reg) - { - case REG_ENABLE: - valxor = um8669f->dev[um8669f->cur_device].enable ^ val; - um8669f->dev[um8669f->cur_device].enable = val; - break; - case REG_ADDRLO: - valxor = (um8669f->dev[um8669f->cur_device].addr & 0xff) ^ val; - um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val; - break; - case REG_ADDRHI: - valxor = ((um8669f->dev[um8669f->cur_device].addr >> 8) & 0xff) ^ val; - um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8); - break; - case REG_IRQ: - valxor = um8669f->dev[um8669f->cur_device].irq ^ val; - um8669f->dev[um8669f->cur_device].irq = val; - break; - case REG_DMA: - valxor = um8669f->dev[um8669f->cur_device].dma ^ val; - um8669f->dev[um8669f->cur_device].dma = val; - break; - default: - valxor = 0; - break; - } - - switch (um8669f->cur_device) - { - case DEV_FDC: - if ((um8669f->cur_reg == REG_ENABLE) && valxor) - { - fdc_remove(um8669f_global.fdc); - if (um8669f->dev[DEV_FDC].enable & 1) - fdc_set_base(um8669f_global.fdc, 0x03f0); - } - break; - case DEV_COM1: - if ((um8669f->cur_reg == REG_ENABLE) && valxor) - { - serial_remove(1); - if (um8669f->dev[DEV_COM1].enable & 1) - serial_setup(1, um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq); - } - break; - case DEV_COM2: - if ((um8669f->cur_reg == REG_ENABLE) && valxor) - { - serial_remove(2); - if (um8669f->dev[DEV_COM2].enable & 1) - serial_setup(2, um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq); - } - break; - case DEV_LPT1: - if ((um8669f->cur_reg == REG_ENABLE) && valxor) - { - lpt1_remove(); - if (um8669f->dev[DEV_LPT1].enable & 1) - lpt1_init(um8669f->dev[DEV_LPT1].addr); - } - break; - } - } - } -} - - -uint8_t um8669f_pnp_read(uint16_t port, void *p) -{ - um8669f_t *um8669f = (um8669f_t *)p; - - switch (um8669f->cur_reg) - { - case REG_DEVICE: - return um8669f->cur_device; - case REG_ENABLE: - return um8669f->dev[um8669f->cur_device].enable; - case REG_ADDRLO: - return um8669f->dev[um8669f->cur_device].addr & 0xff; - case REG_ADDRHI: - return um8669f->dev[um8669f->cur_device].addr >> 8; - case REG_IRQ: - return um8669f->dev[um8669f->cur_device].irq; - case REG_DMA: - return um8669f->dev[um8669f->cur_device].dma; - } - - return 0xff; -} - - -void um8669f_write(uint16_t port, uint8_t val, void *p) -{ - um8669f_t *um8669f = (um8669f_t *)p; - int new_pnp_active; - - if (um8669f->locked) - { - if (port == 0x108 && val == 0xaa) - um8669f->locked = 0; - } - else - { - if (port == 0x108) - { - if (val == 0x55) - um8669f->locked = 1; - else - um8669f->cur_reg_108 = val; - } - else - { - um8669f->regs_108[um8669f->cur_reg_108] = val; - - if (um8669f->cur_reg_108 == 0xc1) { - new_pnp_active = !!(um8669f->regs_108[0xc1] & 0x80); - if (new_pnp_active != um8669f->pnp_active) { - if (new_pnp_active) { - io_sethandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); - io_sethandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); - io_sethandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); - } else { - io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); - io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); - io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); - } - um8669f->pnp_active = new_pnp_active; - } - } - } - } -} - - -uint8_t um8669f_read(uint16_t port, void *p) -{ - um8669f_t *um8669f = (um8669f_t *)p; - - if (um8669f->locked) - return 0xff; - - if (port == 0x108) - return um8669f->cur_reg_108; /*???*/ - else - return um8669f->regs_108[um8669f->cur_reg_108]; -} - - -void um8669f_reset(void) -{ - fdc_t *temp_fdc = um8669f_global.fdc; - - fdc_reset(um8669f_global.fdc); - - serial_remove(1); - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - - serial_remove(2); - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - - lpt2_remove(); - - lpt1_remove(); - lpt1_init(0x378); - - if (um8669f_global.pnp_active) { - io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global); - io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global); - io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, &um8669f_global); - um8669f_global.pnp_active = 0; - } - - memset(&um8669f_global, 0, sizeof(um8669f_t)); - - um8669f_global.fdc = temp_fdc; - - um8669f_global.locked = 1; - - um8669f_global.dev[DEV_FDC].enable = 1; - um8669f_global.dev[DEV_FDC].addr = 0x03f0; - um8669f_global.dev[DEV_FDC].irq = 6; - um8669f_global.dev[DEV_FDC].dma = 2; - - um8669f_global.dev[DEV_COM1].enable = 1; - um8669f_global.dev[DEV_COM1].addr = 0x03f8; - um8669f_global.dev[DEV_COM1].irq = 4; - - um8669f_global.dev[DEV_COM2].enable = 1; - um8669f_global.dev[DEV_COM2].addr = 0x02f8; - um8669f_global.dev[DEV_COM2].irq = 3; - - um8669f_global.dev[DEV_LPT1].enable = 1; - um8669f_global.dev[DEV_LPT1].addr = 0x0378; - um8669f_global.dev[DEV_LPT1].irq = 7; -} - - -void um8669f_init(void) -{ - um8669f_global.fdc = device_add(&fdc_at_device); - - io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global); - - um8669f_reset(); -} diff --git a/src - Cópia/sio_w83877f.c b/src - Cópia/sio_w83877f.c deleted file mode 100644 index 775beccfe..000000000 --- a/src - Cópia/sio_w83877f.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the Winbond W83877F Super I/O Chip. - * - * Winbond W83877F Super I/O Chip - * Used by the Award 430HX - * - * Version: @(#)sio_w83877f.c 1.0.11 2018/04/29 - * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "machine/machine.h" -#include "device.h" -#include "io.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 "sio.h" - - -static int w83877f_locked; -static int w83877f_rw_locked = 0; -static int w83877f_curreg = 0; -static uint8_t w83877f_regs[0x2A]; -static uint8_t tries; -static fdc_t *w83877f_fdc; - -static int winbond_port = 0x3f0; -static int winbond_key = 0x89; -static int winbond_key_times = 1; - - -void w83877f_write(uint16_t port, uint8_t val, void *priv); -uint8_t w83877f_read(uint16_t port, void *priv); - -#define OCSS0 (w83877f_regs[0] & 1) -#define OCSS1 ((w83877f_regs[0] >> 1) & 1) -#define PRTMODS0 ((w83877f_regs[0] >> 2) & 1) -#define PRTMODS1 ((w83877f_regs[0] >> 3) & 1) - -#define ABCHG (w83877f_regs[1] >> 7) - -#define CEA (w83877f_regs[2] & 1) -#define EA3 ((w83877f_regs[2] >> 1) & 1) -#define EA4 ((w83877f_regs[2] >> 2) & 1) -#define EA5 ((w83877f_regs[2] >> 3) & 1) -#define EA6 ((w83877f_regs[2] >> 4) & 1) -#define EA7 ((w83877f_regs[2] >> 5) & 1) -#define EA8 ((w83877f_regs[2] >> 6) & 1) -#define EA9 (w83877f_regs[2] >> 7) - -#define SUBMIDI (w83877f_regs[3] & 1) -#define SUAMIDI ((w83877f_regs[3] >> 1) & 1) -#define GMODS ((w83877f_regs[3] >> 4) & 1) -#define EPPVER ((w83877f_regs[3] >> 5) & 1) -#define GMENL ((w83877f_regs[3] >> 6) & 1) - -#define URBTRI (w83877f_regs[4] & 1) -#define URATRI ((w83877f_regs[4] >> 1) & 1) -#define GMTRI ((w83877f_regs[4] >> 2) & 1) -#define PRTTRI ((w83877f_regs[4] >> 3) & 1) -#define URBPWD ((w83877f_regs[4] >> 4) & 1) -#define URAPWD ((w83877f_regs[4] >> 5) & 1) -#define GMPWD ((w83877f_regs[4] >> 6) & 1) -#define PRTPWD (w83877f_regs[4] >> 7) - -#define ECPFTHR0 (w83877f_regs[5] & 1) -#define ECPFTHR1 ((w83877f_regs[5] >> 1) & 1) -#define ECPFTHR2 ((w83877f_regs[5] >> 2) & 1) -#define ECPFTHR3 ((w83877f_regs[5] >> 3) & 1) - -#define IDETRI (w83877f_regs[6] & 1) -#define FDCTRI ((w83877f_regs[6] >> 1) & 1) -#define IDEPWD ((w83877f_regs[6] >> 2) & 1) -#define FDCPWD ((w83877f_regs[6] >> 3) & 1) -#define FIPURDWM ((w83877f_regs[6] >> 4) & 1) -#define SEL4FDD ((w83877f_regs[6] >> 5) & 1) -#define OSCS2 ((w83877f_regs[6] >> 6) & 1) - -#define FDDA_TYPE (w83877f_regs[7] & 3) -#define FDDB_TYPE ((w83877f_regs[7] >> 2) & 3) -#define FDDC_TYPE ((w83877f_regs[7] >> 4) & 3) -#define FDDD_TYPE ((w83877f_regs[7] >> 6) & 3) - -#define FD_BOOT (w83877f_regs[8] & 3) -#define MEDIA_ID ((w83877f_regs[8] >> 2) & 3) -#define SWWP ((w83877f_regs[8] >> 4) & 1) -#define DISFDDWR ((w83877f_regs[8] >> 5) & 1) -#define APDTMS2 ((w83877f_regs[8] >> 6) & 1) -#define APDTMS1 (w83877f_regs[8] >> 7) - -#define CHIP_ID (w83877f_regs[9] & 0xF) -#define EN3MODE ((w83877f_regs[9] >> 5) & 1) -#define LOCKREG ((w83877f_regs[9] >> 6) & 1) -#define PRTMODS2 ((w83877f_regs[9] >> 7) & 1) - -#define PEXTECPP (w83877f_regs[0xA] & 1) -#define PEXT_ECP ((w83877f_regs[0xA] >> 1) & 1) -#define PEXT_EPP ((w83877f_regs[0xA] >> 2) & 1) -#define PEXT_ADP ((w83877f_regs[0xA] >> 3) & 1) -#define PDCACT ((w83877f_regs[0xA] >> 4) & 1) -#define PDIRHOP ((w83877f_regs[0xA] >> 5) & 1) -#define PEXT_ACT ((w83877f_regs[0xA] >> 6) & 1) -#define PFDCACT (w83877f_regs[0xA] >> 7) - -#define DRV2EN_NEG (w83877f_regs[0xB] & 1) /* 0 = drive 2 installed */ -#define INVERTZ ((w83877f_regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ -#define MFM ((w83877f_regs[0xB] >> 2) & 1) -#define IDENT ((w83877f_regs[0xB] >> 3) & 1) -#define ENIFCHG ((w83877f_regs[0xB] >> 4) & 1) - -#define TX2INV (w83877f_regs[0xC] & 1) -#define RX2INV ((w83877f_regs[0xC] >> 1) & 1) -#define URIRSEL ((w83877f_regs[0xC] >> 3) & 1) -#define HEFERE ((w83877f_regs[0xC] >> 5) & 1) -#define TURB ((w83877f_regs[0xC] >> 6) & 1) -#define TURA (w83877f_regs[0xC] >> 7) - -#define IRMODE0 (w83877f_regs[0xD] & 1) -#define IRMODE1 ((w83877f_regs[0xD] >> 1) & 1) -#define IRMODE2 ((w83877f_regs[0xD] >> 2) & 1) -#define HDUPLX ((w83877f_regs[0xD] >> 3) & 1) -#define SIRRX0 ((w83877f_regs[0xD] >> 4) & 1) -#define SIRRX1 ((w83877f_regs[0xD] >> 5) & 1) -#define SIRTX0 ((w83877f_regs[0xD] >> 6) & 1) -#define SIRTX1 (w83877f_regs[0xD] >> 7) - -#define GIO0AD (w83877f_regs[0x10] | (((uint16_t) w83877f_regs[0x11] & 7) << 8)) -#define GIO0CADM (w83877f_regs[0x11] >> 6) -#define GIO1AD (w83877f_regs[0x12] | (((uint16_t) w83877f_regs[0x13] & 7) << 8)) -#define GIO1CADM (w83877f_regs[0x13] >> 6) - -#define GDA0IPI (w83877f_regs[0x14] & 1) -#define GDA0OPI ((w83877f_regs[0x14] >> 1) & 1) -#define GCS0IOW ((w83877f_regs[0x14] >> 2) & 1) -#define GCS0IOR ((w83877f_regs[0x14] >> 3) & 1) -#define GIO0CSH ((w83877f_regs[0x14] >> 4) & 1) -#define GIOP0MD ((w83877f_regs[0x14] >> 5) & 7) - -#define GDA1IPI (w83877f_regs[0x15] & 1) -#define GDA1OPI ((w83877f_regs[0x15] >> 1) & 1) -#define GCS1IOW ((w83877f_regs[0x15] >> 2) & 1) -#define GCS1IOR ((w83877f_regs[0x15] >> 3) & 1) -#define GIO1CSH ((w83877f_regs[0x15] >> 4) & 1) -#define GIOP1MD ((w83877f_regs[0x15] >> 5) & 7) - -#define HEFRAS (w83877f_regs[0x16] & 1) -#define IRIDE ((w83877f_regs[0x16] >> 1) & 1) -#define PNPCVS ((w83877f_regs[0x16] >> 2) & 1) -#define GMDRQ ((w83877f_regs[0x16] >> 3) & 1) -#define GOIQSEL ((w83877f_regs[0x16] >> 4) & 1) - -#define DSUBLGRQ (w83877f_regs[0x17] & 1) -#define DSUALGRQ ((w83877f_regs[0x17] >> 1) & 1) -#define DSPRLGRQ ((w83877f_regs[0x17] >> 2) & 1) -#define DSFDLGRQ ((w83877f_regs[0x17] >> 3) & 1) -#define PRIRQOD ((w83877f_regs[0x17] >> 4) & 1) - -#define GMAS (w83877f_regs[0x1E] & 3) -#define GMAD (w83877f_regs[0x1E] & 0xFC) - -#define FDCAD ((w83877f_regs[0x20] & 0xFC) << 2) - -/* Main IDE base address. */ -#define IDE0AD ((w83877f_regs[0x21] & 0xFC) << 2) -/* IDE Alternate status base address. */ -#define IDE1AD ((w83877f_regs[0x22] & 0xFC) << 2) - -#define PRTAD (((uint16_t) w83877f_regs[0x23]) << 2) - -#define URAAD (((uint16_t) w83877f_regs[0x24] & 0xFE) << 2) -#define URBAD (((uint16_t) w83877f_regs[0x25] & 0xFE) << 2) - -#define PRTDQS (w83877f[regs[0x26] & 0xF) -#define FDCDQS (w83877f[regs[0x26] >> 4) - -#define PRTIQS (w83877f[regs[0x27] & 0xF) -#define ECPIRQx (w83877f[regs[0x27] >> 5) - -#define URBIQS (w83877f[regs[0x28] & 0xF) -#define URAIQS (w83877f[regs[0x28] >> 4) - -#define IQNIQS (w83877f[regs[0x29] & 0xF) -#define FDCIQS (w83877f[regs[0x29] >> 4) - -#define W83757 (!PRTMODS2 && !PRTMODS1 && !PRTMODS0) -#define EXTFDC (!PRTMODS2 && !PRTMODS1 && PRTMODS0) -#define EXTADP (!PRTMODS2 && PRTMODS1 && !PRTMODS0) -#define EXT2FDD (!PRTMODS2 && PRTMODS1 && PRTMODS0) -#define JOYSTICK (PRTMODS2 && !PRTMODS1 && !PRTMODS0) -#define EPP_SPP (PRTMODS2 && !PRTMODS1 && PRTMODS0) -#define ECP (PRTMODS2 && PRTMODS1 && !PRTMODS0) -#define ECP_EPP (PRTMODS2 && PRTMODS1 && PRTMODS0) - -static uint16_t fdc_valid_ports[2] = {0x3F0, 0x370}; -static uint16_t ide_valid_ports[2] = {0x1F0, 0x170}; -static uint16_t ide_as_valid_ports[2] = {0x3F6, 0x376}; -static uint16_t lpt1_valid_ports[3] = {0x3BC, 0x378, 0x278}; -static uint16_t com1_valid_ports[9] = {0x3F8, 0x2F8, 0x3E8, 0x2E8}; -static uint16_t com2_valid_ports[9] = {0x3F8, 0x2F8, 0x3E8, 0x2E8}; - - -static void w83877f_remap(void) -{ - io_removehandler(0x250, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL); - io_removehandler(0x3f0, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL); - io_sethandler(HEFRAS ? 0x3f0 : 0x250, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL); - winbond_port = (HEFRAS ? 0x3f0 : 0x250); - winbond_key_times = HEFRAS + 1; - winbond_key = (HEFRAS ? 0x86 : 0x88) | HEFERE; -} - - -static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port) -{ - uint8_t i = 0; - - for (i = 0; i < max; i++) - { - if (port_array[i] == port) return 1; - } - return 0; -} - - -static uint16_t make_port(uint8_t reg) -{ - uint16_t p = 0; - - switch(reg) - { - case 0x20: - p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2; - p &= 0xFF0; - if ((p < 0x100) || (p > 0x3F0)) p = 0x3F0; - if (!(is_in_array(fdc_valid_ports, 2, p))) p = 0x3F0; - w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3); - break; - case 0x21: - p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2; - p &= 0xFF0; - if ((p < 0x100) || (p > 0x3F0)) p = 0x1F0; - if (!(is_in_array(ide_valid_ports, 2, p))) p = 0x1F0; - w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3); - break; - case 0x22: - p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2; - p &= 0xFF0; - if ((p < 0x106) || (p > 0x3F6)) p = 0x3F6; - if (!(is_in_array(ide_as_valid_ports, 2, p))) p = 0x3F6; - w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3); - break; - case 0x23: - p = ((uint16_t) (w83877f_regs[reg] & 0xff)) << 2; - p &= 0xFFC; - if ((p < 0x100) || (p > 0x3F8)) p = 0x378; - if (!(is_in_array(lpt1_valid_ports, 3, p))) p = 0x378; - w83877f_regs[reg] = (p >> 2); - break; - case 0x24: - p = ((uint16_t) (w83877f_regs[reg] & 0xfe)) << 2; - p &= 0xFF8; - if ((p < 0x100) || (p > 0x3F8)) p = 0x3F8; - if (!(is_in_array(com1_valid_ports, 9, p))) p = 0x3F8; - w83877f_regs[reg] = ((p >> 2) & 0xfe) | (w83877f_regs[reg] & 1); - break; - case 0x25: - p = ((uint16_t) (w83877f_regs[reg] & 0xfe)) << 2; - p &= 0xFF8; - if ((p < 0x100) || (p > 0x3F8)) p = 0x2F8; - if (!(is_in_array(com2_valid_ports, 9, p))) p = 0x2F8; - w83877f_regs[reg] = ((p >> 2) & 0xfe) | (w83877f_regs[reg] & 1); - break; - } - - return p; -} - - -void w83877f_serial_handler(int id) -{ - int reg_mask = (id - 1) ? 0x10 : 0x20; - int reg_id = (id - 1) ? 0x24 : 0x25; - int irq_mask = (id - 1) ? 0xF : 0xF0; - - if ((w83877f_regs[4] & reg_mask) || !(w83877f_regs[reg_id] & 0xc0)) - { - serial_remove(id); - } - else - { - serial_setup(id, make_port(reg_id), w83877f_regs[0x28] & irq_mask); - } -} - - -void w83877f_write(uint16_t port, uint8_t val, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - uint8_t max = 0x2A; - - if (index) - { - if ((val == winbond_key) && !w83877f_locked) - { - if (winbond_key_times == 2) - { - if (tries) - { - w83877f_locked = 1; - tries = 0; - } - else - { - tries++; - } - } - else - { - w83877f_locked = 1; - tries = 0; - } - } - else - { - if (w83877f_locked) - { - if (val < max) w83877f_curreg = val; - if (val == 0xaa) - { - w83877f_locked = 0; - } - } - else - { - if (tries) - tries = 0; - } - } - } - else - { - if (w83877f_locked) - { - if (w83877f_rw_locked) return; - if ((w83877f_curreg >= 0x26) && (w83877f_curreg <= 0x27)) return; - if (w83877f_curreg == 0x29) return; - if (w83877f_curreg == 6) val &= 0xF3; - valxor = val ^ w83877f_regs[w83877f_curreg]; - w83877f_regs[w83877f_curreg] = val; - goto process_value; - } - } - return; - -process_value: - switch(w83877f_curreg) - { - case 1: - if (valxor & 0x80) - { - fdc_set_swap(w83877f_fdc, (w83877f_regs[1] & 0x80) ? 1 : 0); - } - break; - case 4: - if (valxor & 0x10) - { - w83877f_serial_handler(2); - } - if (valxor & 0x20) - { - w83877f_serial_handler(1); - } - if (valxor & 0x80) - { - lpt1_remove(); - if (!(w83877f_regs[4] & 0x80)) lpt1_init(make_port(0x23)); - } - break; - case 6: - if (valxor & 0x08) - { - fdc_remove(w83877f_fdc); - if (!(w83877f_regs[6] & 0x08)) fdc_set_base(w83877f_fdc, 0x03f0); - } - break; - case 7: - if (valxor & 3) fdc_update_rwc(w83877f_fdc, 0, FDDA_TYPE); - if (valxor & 0xC) fdc_update_rwc(w83877f_fdc, 1, FDDB_TYPE); - if (valxor & 0x30) fdc_update_rwc(w83877f_fdc, 2, FDDC_TYPE); - if (valxor & 0xC0) fdc_update_rwc(w83877f_fdc, 3, FDDD_TYPE); - break; - case 8: - if (valxor & 3) fdc_update_boot_drive(w83877f_fdc, FD_BOOT); - if (valxor & 0x10) fdc_set_swwp(w83877f_fdc, SWWP ? 1 : 0); - if (valxor & 0x20) fdc_set_diswr(w83877f_fdc, DISFDDWR ? 1 : 0); - break; - case 9: - if (valxor & 0x20) - { - fdc_update_enh_mode(w83877f_fdc, EN3MODE ? 1 : 0); - } - if (valxor & 0x40) - { - w83877f_rw_locked = (val & 0x40) ? 1 : 0; - } - break; - case 0xB: - if (valxor & 1) fdc_update_drv2en(w83877f_fdc, DRV2EN_NEG ? 0 : 1); - if (valxor & 2) fdc_update_densel_polarity(w83877f_fdc, INVERTZ ? 1 : 0); - break; - case 0xC: - if (valxor & 0x20) w83877f_remap(); - break; - case 0x16: - if (valxor & 1) w83877f_remap(); - break; - case 0x23: - if (valxor) - { - lpt1_remove(); - if (!(w83877f_regs[4] & 0x80)) lpt1_init(make_port(0x23)); - } - break; - case 0x24: - if (valxor & 0xfe) - { - w83877f_serial_handler(1); - } - break; - case 0x25: - if (valxor & 0xfe) - { - w83877f_serial_handler(2); - } - break; - case 0x28: - if (valxor & 0xf) - { - if ((w83877f_regs[0x28] & 0xf) == 0) w83877f_regs[0x28] |= 0x3; - if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); - } - if (valxor & 0xf0) - { - if ((w83877f_regs[0x28] & 0xf0) == 0) w83877f_regs[0x28] |= 0x40; - if (!(w83877f_regs[4] & 0x20)) - { - serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); - } - } - break; - } -} - - -uint8_t w83877f_read(uint16_t port, void *priv) -{ - uint8_t index = (port & 1) ? 0 : 1; - - if (!w83877f_locked) - { - return 0xff; - } - - if (index) - { - return w83877f_curreg; - } - else - { - if ((w83877f_curreg < 0x18) && w83877f_rw_locked) return 0xff; - if (w83877f_curreg == 7) - return (fdc_get_rwc(w83877f_fdc, 0) | (fdc_get_rwc(w83877f_fdc, 1) << 2)); - return w83877f_regs[w83877f_curreg]; - } -} - - -void w83877f_reset(void) -{ - lpt1_remove(); - lpt1_init(0x378); - - fdc_reset(w83877f_fdc); - - memset(w83877f_regs, 0, 0x2A); - w83877f_regs[3] = 0x30; - w83877f_regs[7] = 0xF5; - w83877f_regs[9] = 0x0A; - w83877f_regs[0xA] = 0x1F; - w83877f_regs[0xC] = 0x28; - w83877f_regs[0xD] = 0xA3; - w83877f_regs[0x16] = (romset == ROM_PRESIDENT) ? 4 : 5; - w83877f_regs[0x1E] = 0x81; - w83877f_regs[0x20] = (0x3f0 >> 2) & 0xfc; - w83877f_regs[0x21] = (0x1f0 >> 2) & 0xfc; - w83877f_regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; - w83877f_regs[0x23] = (0x378 >> 2); - w83877f_regs[0x24] = (0x3f8 >> 2) & 0xfe; - w83877f_regs[0x25] = (0x2f8 >> 2) & 0xfe; - w83877f_regs[0x26] = (2 << 4) | 4; - w83877f_regs[0x27] = (6 << 4) | 7; - w83877f_regs[0x28] = (4 << 4) | 3; - w83877f_regs[0x29] = 0x62; - - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); - w83877f_remap(); - w83877f_locked = 0; - w83877f_rw_locked = 0; -} - - -void w83877f_init(void) -{ - w83877f_fdc = device_add(&fdc_at_winbond_device); - - lpt2_remove(); - - w83877f_reset(); -} diff --git a/src - Cópia/sound/dbopl.cpp b/src - Cópia/sound/dbopl.cpp deleted file mode 100644 index 85228ae10..000000000 --- a/src - Cópia/sound/dbopl.cpp +++ /dev/null @@ -1,1512 +0,0 @@ -/* Copyright holders: The DOSBox Team - see COPYING for more details -*/ - -/* - DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator. - Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2 - Except for the table generation it's all integer math - Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms - The generation was based on the MAME implementation but tried to have it use less memory and be faster in general - MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times - - //TODO Don't delay first operator 1 sample in opl3 mode - //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter - //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? - //TODO Check if having the same accuracy in all frequency multipliers sounds better or not - - //DUNNO Keyon in 4op, switch to 2op without keyoff. -*/ - -/* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */ - -#include -#include -#include -#include "dbopl.h" - - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - -namespace DBOPL { - -#define OPLRATE ((double)(14318180.0 / 288.0)) -#define TREMOLO_TABLE 52 - -//Try to use most precision for frequencies -//Else try to keep different waves in synch -//#define WAVE_PRECISION 1 -#ifndef WAVE_PRECISION -//Wave bits available in the top of the 32bit range -//Original adlib uses 10.10, we use 10.22 -#define WAVE_BITS 10 -#else -//Need some extra bits at the top to have room for octaves and frequency multiplier -//We support to 8 times lower rate -//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits -#define WAVE_BITS 14 -#endif -#define WAVE_SH ( 32 - WAVE_BITS ) -#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) - -//Use the same accuracy as the waves -#define LFO_SH ( WAVE_SH - 10 ) -//LFO is controlled by our tremolo 256 sample limit -#define LFO_MAX ( 256 << ( LFO_SH ) ) - - -//Maximum amount of attenuation bits -//Envelope goes to 511, 9 bits -#if (DBOPL_WAVE == WAVE_TABLEMUL ) -//Uses the value directly -#define ENV_BITS ( 9 ) -#else -//Add 3 bits here for more accuracy and would have to be shifted up either way -#define ENV_BITS ( 9 ) -#endif -//Limits of the envelope with those bits and when the envelope goes silent -#define ENV_MIN 0 -#define ENV_EXTRA ( ENV_BITS - 9 ) -#define ENV_MAX ( 511 << ENV_EXTRA ) -#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) -#define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT ) - -//Attack/decay/release rate counter shift -#define RATE_SH 24 -#define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) -//Has to fit within 16bit lookuptable -#define MUL_SH 16 - -//Check some ranges -#if ENV_EXTRA > 3 -#error Too many envelope bits -#endif - - -//How much to substract from the base value for the final attenuation -static const Bit8u KslCreateTable[16] = { - //0 will always be be lower than 7 * 8 - 64, 32, 24, 19, - 16, 12, 11, 10, - 8, 6, 5, 4, - 3, 2, 1, 0, -}; - -#define M(_X_) ((Bit8u)( (_X_) * 2)) -static const Bit8u FreqCreateTable[16] = { - M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ), - M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15) -}; -#undef M - -//We're not including the highest attack rate, that gets a special value -static const Bit8u AttackSamplesTable[13] = { - 69, 55, 46, 40, - 35, 29, 23, 20, - 19, 15, 11, 10, - 9 -}; -//On a real opl these values take 8 samples to reach and are based upon larger tables -static const Bit8u EnvelopeIncreaseTable[13] = { - 4, 5, 6, 7, - 8, 10, 12, 14, - 16, 20, 24, 28, - 32, -}; - -#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) -static Bit16u ExpTable[ 256 ]; -#endif - -#if ( DBOPL_WAVE == WAVE_HANDLER ) -//PI table used by WAVEHANDLER -static Bit16u SinTable[ 512 ]; -#endif - -#if ( DBOPL_WAVE > WAVE_HANDLER ) -//Layout of the waveform table in 512 entry intervals -//With overlapping waves we reduce the table to half it's size - -// | |//\\|____|WAV7|//__|/\ |____|/\/\| -// |\\//| | |WAV7| | \/| | | -// |06 |0126|17 |7 |3 |4 |4 5 |5 | - -//6 is just 0 shifted and masked - -static Bit16s WaveTable[ 8 * 512 ]; -//Distance into WaveTable the wave starts -static const Bit16u WaveBaseTable[8] = { - 0x000, 0x200, 0x200, 0x800, - 0xa00, 0xc00, 0x100, 0x400, - -}; -//Mask the counter with this -static const Bit16u WaveMaskTable[8] = { - 1023, 1023, 511, 511, - 1023, 1023, 512, 1023, -}; - -//Where to start the counter on at keyon -static const Bit16u WaveStartTable[8] = { - 512, 0, 0, 0, - 0, 512, 512, 256, -}; -#endif - -#if ( DBOPL_WAVE == WAVE_TABLEMUL ) -static Bit16u MulTable[ 384 ]; -#endif - -static Bit8u KslTable[ 8 * 16 ]; -static Bit8u TremoloTable[ TREMOLO_TABLE ]; -//Start of a channel behind the chip struct start -static Bit16u ChanOffsetTable[32]; -//Start of an operator behind the chip struct start -static Bit16u OpOffsetTable[64]; - -//The lower bits are the shift of the operator vibrato value -//The highest bit is right shifted to generate -1 or 0 for negation -//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 -static const Bit8s VibratoTable[ 8 ] = { - 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, - 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 -}; - -//Shift strength for the ksl value determined by ksl strength -static const Bit8u KslShiftTable[4] = { - 31,1,2,0 -}; - -//Generate a table index and table shift value using input value from a selected rate -static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) { - if ( val < 13 * 4 ) { //Rate 0 - 12 - shift = 12 - ( val >> 2 ); - index = val & 3; - } else if ( val < 15 * 4 ) { //rate 13 - 14 - shift = 0; - index = val - 12 * 4; - } else { //rate 15 and up - shift = 0; - index = 12; - } -} - -#if ( DBOPL_WAVE == WAVE_HANDLER ) -/* - Generate the different waveforms out of the sine/exponetial table using handlers -*/ -static inline Bits MakeVolume( Bitu wave, Bitu volume ) { - Bitu total = wave + volume; - Bitu index = total & 0xff; - Bitu sig = ExpTable[ index ]; - Bitu exp = total >> 8; -#if 0 - //Check if we overflow the 31 shift limit - if ( exp >= 32 ) { - LOG_MSG( "WTF %d %d", total, exp ); - } -#endif - return (sig >> exp); -}; - -static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - return (MakeVolume( wave, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) { - Bit32u wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) { - Bitu wave = SinTable[i & 511]; - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) { - Bitu wave = SinTable[i & 255]; - wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) { - //Twice as fast - i <<= 1; - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return (MakeVolume( wave, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) { - //Twice as fast - i <<= 1; - Bitu wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) { - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - return (MakeVolume( 0, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) { - //Negative is reversed here - Bits neg = (( i >> 9) & 1) - 1; - Bitu wave = (i << 3); - //When negative the volume also runs backwards - wave = ((wave ^ neg) - neg) & 4095; - return (MakeVolume( wave, volume ) ^ neg) - neg; -} - -static const WaveHandler WaveHandlerTable[8] = { - WaveForm0, WaveForm1, WaveForm2, WaveForm3, - WaveForm4, WaveForm5, WaveForm6, WaveForm7 -}; - -#endif - -/* - Operator -*/ - -//We zero out when rate == 0 -inline void Operator::UpdateAttack( const Chip* chip ) { - Bit8u rate = reg60 >> 4; - if ( rate ) { - Bit8u val = (rate << 2) + ksr; - attackAdd = chip->attackRates[ val ]; - rateZero &= ~(1 << ATTACK); - } else { - attackAdd = 0; - rateZero |= (1 << ATTACK); - } -} -inline void Operator::UpdateDecay( const Chip* chip ) { - Bit8u rate = reg60 & 0xf; - if ( rate ) { - Bit8u val = (rate << 2) + ksr; - decayAdd = chip->linearRates[ val ]; - rateZero &= ~(1 << DECAY); - } else { - decayAdd = 0; - rateZero |= (1 << DECAY); - } -} -inline void Operator::UpdateRelease( const Chip* chip ) { - Bit8u rate = reg80 & 0xf; - if ( rate ) { - Bit8u val = (rate << 2) + ksr; - releaseAdd = chip->linearRates[ val ]; - rateZero &= ~(1 << RELEASE); - if ( !(reg20 & MASK_SUSTAIN ) ) { - rateZero &= ~( 1 << SUSTAIN ); - } - } else { - rateZero |= (1 << RELEASE); - releaseAdd = 0; - if ( !(reg20 & MASK_SUSTAIN ) ) { - rateZero |= ( 1 << SUSTAIN ); - } - } -} - -inline void Operator::UpdateAttenuation( ) { - Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff); - Bit32u tl = reg40 & 0x3f; - Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; - //Make sure the attenuation goes to the right bits - totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max - totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift; -} - -void Operator::UpdateFrequency( ) { - Bit32u freq = chanData & (( 1 << 10 ) - 1); - Bit32u block = (chanData >> 10) & 0xff; -#ifdef WAVE_PRECISION - block = 7 - block; - waveAdd = ( freq * freqMul ) >> block; -#else - waveAdd = ( freq << block ) * freqMul; -#endif - if ( reg20 & MASK_VIBRATO ) { - vibStrength = (Bit8u)(freq >> 7); - -#ifdef WAVE_PRECISION - vibrato = ( vibStrength * freqMul ) >> block; -#else - vibrato = ( vibStrength << block ) * freqMul; -#endif - } else { - vibStrength = 0; - vibrato = 0; - } -} - -void Operator::UpdateRates( const Chip* chip ) { - //Mame seems to reverse this where enabling ksr actually lowers - //the rate, but pdf manuals says otherwise? - Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff); - if ( !( reg20 & MASK_KSR ) ) { - newKsr >>= 2; - } - if ( ksr == newKsr ) - return; - ksr = newKsr; - UpdateAttack( chip ); - UpdateDecay( chip ); - UpdateRelease( chip ); -} - -INLINE Bit32s Operator::RateForward( Bit32u add ) { - rateIndex += add; - Bit32s ret = rateIndex >> RATE_SH; - rateIndex = rateIndex & RATE_MASK; - return ret; -} - -template< Operator::State yes> -Bits Operator::TemplateVolume( ) { - Bit32s vol = volume; - Bit32s change; - switch ( yes ) { - case OFF: - return ENV_MAX; - case ATTACK: - change = RateForward( attackAdd ); - if ( !change ) - return vol; - vol += ( (~vol) * change ) >> 3; - if ( vol < ENV_MIN ) { - volume = ENV_MIN; - rateIndex = 0; - SetState( DECAY ); - return ENV_MIN; - } - break; - case DECAY: - vol += RateForward( decayAdd ); - if ( GCC_UNLIKELY(vol >= sustainLevel) ) { - //Check if we didn't overshoot max attenuation, then just go off - if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { - volume = ENV_MAX; - SetState( OFF ); - return ENV_MAX; - } - //Continue as sustain - rateIndex = 0; - SetState( SUSTAIN ); - } - break; - case SUSTAIN: - if ( reg20 & MASK_SUSTAIN ) { - return vol; - } - //In sustain phase, but not sustaining, do regular release - case RELEASE: - vol += RateForward( releaseAdd );; - if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { - volume = ENV_MAX; - SetState( OFF ); - return ENV_MAX; - } - break; - } - volume = vol; - return vol; -} - -static const VolumeHandler VolumeHandlerTable[5] = { - &Operator::TemplateVolume< Operator::OFF >, - &Operator::TemplateVolume< Operator::RELEASE >, - &Operator::TemplateVolume< Operator::SUSTAIN >, - &Operator::TemplateVolume< Operator::DECAY >, - &Operator::TemplateVolume< Operator::ATTACK > -}; - -INLINE Bitu Operator::ForwardVolume() { - return currentLevel + (this->*volHandler)(); -} - - -INLINE Bitu Operator::ForwardWave() { - waveIndex += waveCurrent; - return waveIndex >> WAVE_SH; -} - -void Operator::Write20( const Chip* chip, Bit8u val ) { - Bit8u change = (reg20 ^ val ); - if ( !change ) - return; - reg20 = val; - //Shift the tremolo bit over the entire register, saved a branch, YES! - tremoloMask = (Bit8s)(val) >> 7; - tremoloMask &= ~(( 1 << ENV_EXTRA ) -1); - //Update specific features based on changes - if ( change & MASK_KSR ) { - UpdateRates( chip ); - } - //With sustain enable the volume doesn't change - if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) { - rateZero |= ( 1 << SUSTAIN ); - } else { - rateZero &= ~( 1 << SUSTAIN ); - } - //Frequency multiplier or vibrato changed - if ( change & (0xf | MASK_VIBRATO) ) { - freqMul = chip->freqMul[ val & 0xf ]; - UpdateFrequency(); - } -} - -void Operator::Write40( const Chip* /*chip*/, Bit8u val ) { - if (!(reg40 ^ val )) - return; - reg40 = val; - UpdateAttenuation( ); -} - -void Operator::Write60( const Chip* chip, Bit8u val ) { - Bit8u change = reg60 ^ val; - reg60 = val; - if ( change & 0x0f ) { - UpdateDecay( chip ); - } - if ( change & 0xf0 ) { - UpdateAttack( chip ); - } -} - -void Operator::Write80( const Chip* chip, Bit8u val ) { - Bit8u change = (reg80 ^ val ); - if ( !change ) - return; - reg80 = val; - Bit8u sustain = val >> 4; - //Turn 0xf into 0x1f - sustain |= ( sustain + 1) & 0x10; - sustainLevel = sustain << ( ENV_BITS - 5 ); - if ( change & 0x0f ) { - UpdateRelease( chip ); - } -} - -void Operator::WriteE0( const Chip* chip, Bit8u val ) { - if ( !(regE0 ^ val) ) - return; - //in opl3 mode you can always selet 7 waveforms regardless of waveformselect - Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) ); - regE0 = val; -#if ( DBOPL_WAVE == WAVE_HANDLER ) - waveHandler = WaveHandlerTable[ waveForm ]; -#else - waveBase = WaveTable + WaveBaseTable[ waveForm ]; - waveStart = WaveStartTable[ waveForm ] << WAVE_SH; - waveMask = WaveMaskTable[ waveForm ]; -#endif -} - -INLINE void Operator::SetState( Bit8u s ) { - state = s; - volHandler = VolumeHandlerTable[ s ]; -} - -INLINE bool Operator::Silent() const { - if ( !ENV_SILENT( totalLevel + volume ) ) - return false; - if ( !(rateZero & ( 1 << state ) ) ) - return false; - return true; -} - -INLINE void Operator::Prepare( const Chip* chip ) { - currentLevel = totalLevel + (chip->tremoloValue & tremoloMask); - waveCurrent = waveAdd; - if ( vibStrength >> chip->vibratoShift ) { - Bit32s add = vibrato >> chip->vibratoShift; - //Sign extend over the shift value - Bit32s neg = chip->vibratoSign; - //Negate the add with -1 or 0 - add = ( add ^ neg ) - neg; - waveCurrent += add; - } -} - -void Operator::KeyOn( Bit8u mask ) { - if ( !keyOn ) { - //Restart the frequency generator -#if ( DBOPL_WAVE > WAVE_HANDLER ) - waveIndex = waveStart; -#else - waveIndex = 0; -#endif - rateIndex = 0; - SetState( ATTACK ); - } - keyOn |= mask; -} - -void Operator::KeyOff( Bit8u mask ) { - keyOn &= ~mask; - if ( !keyOn ) { - if ( state != OFF ) { - SetState( RELEASE ); - } - } -} - -INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { -#if ( DBOPL_WAVE == WAVE_HANDLER ) - return waveHandler( index, vol << ( 3 - ENV_EXTRA ) ); -#elif ( DBOPL_WAVE == WAVE_TABLEMUL ) - return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; -#elif ( DBOPL_WAVE == WAVE_TABLELOG ) - Bit32s wave = waveBase[ index & waveMask ]; - Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); - Bit32s sig = ExpTable[ total & 0xff ]; - Bit32u exp = total >> 8; - Bit32s neg = wave >> 16; - return ((sig ^ neg) - neg) >> exp; -#else -#error "No valid wave routine" -#endif -} - -Bits INLINE Operator::GetSample( Bits modulation ) { - Bitu vol = ForwardVolume(); - if ( ENV_SILENT( vol ) ) { - //Simply forward the wave - waveIndex += waveCurrent; - return 0; - } else { - Bitu index = ForwardWave(); - index += modulation; - return GetWave( index, vol ); - } -} - -Operator::Operator() { - chanData = 0; - freqMul = 0; - waveIndex = 0; - waveAdd = 0; - waveCurrent = 0; - keyOn = 0; - ksr = 0; - reg20 = 0; - reg40 = 0; - reg60 = 0; - reg80 = 0; - regE0 = 0; - SetState( OFF ); - rateZero = (1 << OFF); - sustainLevel = ENV_MAX; - currentLevel = ENV_MAX; - totalLevel = ENV_MAX; - volume = ENV_MAX; - releaseAdd = 0; -} - -/* - Channel -*/ - -Channel::Channel() { - old[0] = old[1] = 0; - chanData = 0; - regB0 = 0; - regC0 = 0; - maskLeft = -1; - maskRight = -1; - feedback = 31; - fourMask = 0; - synthHandler = &Channel::BlockTemplate< sm2FM >; -}; - -void Channel::SetChanData( const Chip* chip, Bit32u data ) { - Bit32u change = chanData ^ data; - chanData = data; - Op( 0 )->chanData = data; - Op( 1 )->chanData = data; - //Since a frequency update triggered this, always update frequency - Op( 0 )->UpdateFrequency(); - Op( 1 )->UpdateFrequency(); - if ( change & ( 0xff << SHIFT_KSLBASE ) ) { - Op( 0 )->UpdateAttenuation(); - Op( 1 )->UpdateAttenuation(); - } - if ( change & ( 0xff << SHIFT_KEYCODE ) ) { - Op( 0 )->UpdateRates( chip ); - Op( 1 )->UpdateRates( chip ); - } -} - -void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) { - //Extrace the frequency bits - Bit32u data = chanData & 0xffff; - Bit32u kslBase = KslTable[ data >> 6 ]; - Bit32u keyCode = ( data & 0x1c00) >> 9; - if ( chip->reg08 & 0x40 ) { - keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ - } else { - keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ - } - //Add the keycode and ksl into the highest bits of chanData - data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); - ( this + 0 )->SetChanData( chip, data ); - if ( fourOp & 0x3f ) { - ( this + 1 )->SetChanData( chip, data ); - } -} - -void Channel::WriteA0( const Chip* chip, Bit8u val ) { - Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; - //Don't handle writes to silent fourop channels - if ( fourOp > 0x80 ) - return; - Bit32u change = (chanData ^ val ) & 0xff; - if ( change ) { - chanData ^= change; - UpdateFrequency( chip, fourOp ); - } -} - -void Channel::WriteB0( const Chip* chip, Bit8u val ) { - Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; - //Don't handle writes to silent fourop channels - if ( fourOp > 0x80 ) - return; - Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00; - if ( change ) { - chanData ^= change; - UpdateFrequency( chip, fourOp ); - } - //Check for a change in the keyon/off state - if ( !(( val ^ regB0) & 0x20)) - return; - regB0 = val; - if ( val & 0x20 ) { - Op(0)->KeyOn( 0x1 ); - Op(1)->KeyOn( 0x1 ); - if ( fourOp & 0x3f ) { - ( this + 1 )->Op(0)->KeyOn( 1 ); - ( this + 1 )->Op(1)->KeyOn( 1 ); - } - } else { - Op(0)->KeyOff( 0x1 ); - Op(1)->KeyOff( 0x1 ); - if ( fourOp & 0x3f ) { - ( this + 1 )->Op(0)->KeyOff( 1 ); - ( this + 1 )->Op(1)->KeyOff( 1 ); - } - } -} - -void Channel::WriteC0( const Chip* chip, Bit8u val ) { - Bit8u change = val ^ regC0; - if ( !change ) - return; - regC0 = val; - feedback = ( val >> 1 ) & 7; - if ( feedback ) { - //We shift the input to the right 10 bit wave index value - feedback = 9 - feedback; - } else { - feedback = 31; - } - //Select the new synth mode - if ( chip->opl3Active ) { - //4-op mode enabled for this channel - if ( (chip->reg104 & fourMask) & 0x3f ) { - Channel* chan0, *chan1; - //Check if it's the 2nd channel in a 4-op - if ( !(fourMask & 0x80 ) ) { - chan0 = this; - chan1 = this + 1; - } else { - chan0 = this - 1; - chan1 = this; - } - - Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); - switch ( synth ) { - case 0: - chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; - break; - case 1: - chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; - break; - case 2: - chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; - break; - case 3: - chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; - break; - } - //Disable updating percussion channels - } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { - - //Regular dual op, am or fm - } else if ( val & 1 ) { - synthHandler = &Channel::BlockTemplate< sm3AM >; - } else { - synthHandler = &Channel::BlockTemplate< sm3FM >; - } - maskLeft = ( val & 0x10 ) ? -1 : 0; - maskRight = ( val & 0x20 ) ? -1 : 0; - //opl2 active - } else { - //Disable updating percussion channels - if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { - - //Regular dual op, am or fm - } else if ( val & 1 ) { - synthHandler = &Channel::BlockTemplate< sm2AM >; - } else { - synthHandler = &Channel::BlockTemplate< sm2FM >; - } - } -} - -void Channel::ResetC0( const Chip* chip ) { - Bit8u val = regC0; - regC0 ^= 0xff; - WriteC0( chip, val ); -}; - -template< bool opl3Mode> -INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { - Channel* chan = this; - - //BassDrum - Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; - old[0] = old[1]; - old[1] = Op(0)->GetSample( mod ); - - //When bassdrum is in AM mode first operator is ignoed - if ( chan->regC0 & 1 ) { - mod = 0; - } else { - mod = old[0]; - } - Bit32s sample = Op(1)->GetSample( mod ); - - - //Precalculate stuff used by other outputs - Bit32u noiseBit = chip->ForwardNoise() & 0x1; - Bit32u c2 = Op(2)->ForwardWave(); - Bit32u c5 = Op(5)->ForwardWave(); - Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; - - //Hi-Hat - Bit32u hhVol = Op(2)->ForwardVolume(); - if ( !ENV_SILENT( hhVol ) ) { - Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); - sample += Op(2)->GetWave( hhIndex, hhVol ); - } - //Snare Drum - Bit32u sdVol = Op(3)->ForwardVolume(); - if ( !ENV_SILENT( sdVol ) ) { - Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); - sample += Op(3)->GetWave( sdIndex, sdVol ); - } - //Tom-tom - sample += Op(4)->GetSample( 0 ); - - //Top-Cymbal - Bit32u tcVol = Op(5)->ForwardVolume(); - if ( !ENV_SILENT( tcVol ) ) { - Bit32u tcIndex = (1 + phaseBit) << 8; - sample += Op(5)->GetWave( tcIndex, tcVol ); - } - sample <<= 1; - if ( opl3Mode ) { - output[0] += sample; - output[1] += sample; - } else { - output[0] += sample; - } -} - -template -Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { - switch( mode ) { - case sm2AM: - case sm3AM: - if ( Op(0)->Silent() && Op(1)->Silent() ) { - old[0] = old[1] = 0; - return (this + 1); - } - break; - case sm2FM: - case sm3FM: - if ( Op(1)->Silent() ) { - old[0] = old[1] = 0; - return (this + 1); - } - break; - case sm3FMFM: - if ( Op(3)->Silent() ) { - old[0] = old[1] = 0; - return (this + 2); - } - break; - case sm3AMFM: - if ( Op(0)->Silent() && Op(3)->Silent() ) { - old[0] = old[1] = 0; - return (this + 2); - } - break; - case sm3FMAM: - if ( Op(1)->Silent() && Op(3)->Silent() ) { - old[0] = old[1] = 0; - return (this + 2); - } - break; - case sm3AMAM: - if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) { - old[0] = old[1] = 0; - return (this + 2); - } - break; - case sm2Percussion: - case sm3Percussion: - break; - } - //Init the operators with the the current vibrato and tremolo values - Op( 0 )->Prepare( chip ); - Op( 1 )->Prepare( chip ); - if ( mode > sm4Start ) { - Op( 2 )->Prepare( chip ); - Op( 3 )->Prepare( chip ); - } - if ( mode > sm6Start ) { - Op( 4 )->Prepare( chip ); - Op( 5 )->Prepare( chip ); - } - for ( Bitu i = 0; i < samples; i++ ) { - //Early out for percussion handlers - if ( mode == sm2Percussion ) { - GeneratePercussion( chip, output + i ); - continue; //Prevent some unitialized value bitching - } else if ( mode == sm3Percussion ) { - GeneratePercussion( chip, output + i * 2 ); - continue; //Prevent some unitialized value bitching - } - - //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise - Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; - old[0] = old[1]; - old[1] = Op(0)->GetSample( mod ); - Bit32s sample; - Bit32s out0 = old[0]; - if ( mode == sm2AM || mode == sm3AM ) { - sample = out0 + Op(1)->GetSample( 0 ); - } else if ( mode == sm2FM || mode == sm3FM ) { - sample = Op(1)->GetSample( out0 ); - } else if ( mode == sm3FMFM ) { - Bits next = Op(1)->GetSample( out0 ); - next = Op(2)->GetSample( next ); - sample = Op(3)->GetSample( next ); - } else if ( mode == sm3AMFM ) { - sample = out0; - Bits next = Op(1)->GetSample( 0 ); - next = Op(2)->GetSample( next ); - sample += Op(3)->GetSample( next ); - } else if ( mode == sm3FMAM ) { - sample = Op(1)->GetSample( out0 ); - Bits next = Op(2)->GetSample( 0 ); - sample += Op(3)->GetSample( next ); - } else if ( mode == sm3AMAM ) { - sample = out0; - Bits next = Op(1)->GetSample( 0 ); - sample += Op(2)->GetSample( next ); - sample += Op(3)->GetSample( 0 ); - } - switch( mode ) { - case sm2AM: - case sm2FM: - if (chip->is_opl3) - { - output[ i * 2 + 0 ] += sample; - output[ i * 2 + 1 ] += sample; - } - else - output[ i ] += sample; - break; - case sm3AM: - case sm3FM: - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - output[ i * 2 + 0 ] += sample & maskLeft; - output[ i * 2 + 1 ] += sample & maskRight; - break; - case sm2Percussion: - case sm3Percussion: - break; - } - } - switch( mode ) { - case sm2AM: - case sm2FM: - case sm3AM: - case sm3FM: - return ( this + 1 ); - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - return( this + 2 ); - case sm2Percussion: - case sm3Percussion: - return( this + 3 ); - } - return 0; -} - -/* - Chip -*/ - -Chip::Chip() { - reg08 = 0; - reg04 = 0; - regBD = 0; - reg104 = 0; - opl3Active = 0; -} - -INLINE Bit32u Chip::ForwardNoise() { - noiseCounter += noiseAdd; - Bitu count = noiseCounter >> LFO_SH; - noiseCounter &= WAVE_MASK; - for ( ; count > 0; --count ) { - //Noise calculation from mame - noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) ); - noiseValue >>= 1; - } - return noiseValue; -} - -INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) { - //Current vibrato value, runs 4x slower than tremolo - vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7; - vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; - tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; - - //Check hom many samples there can be done before the value changes - Bit32u todo = LFO_MAX - lfoCounter; - Bit32u count = (todo + lfoAdd - 1) / lfoAdd; - if ( count > samples ) { - count = samples; - lfoCounter += count * lfoAdd; - } else { - lfoCounter += count * lfoAdd; - lfoCounter &= (LFO_MAX - 1); - //Maximum of 7 vibrato value * 4 - vibratoIndex = ( vibratoIndex + 1 ) & 31; - //Clip tremolo to the the table size - if ( tremoloIndex + 1 < TREMOLO_TABLE ) - ++tremoloIndex; - else - tremoloIndex = 0; - } - return count; -} - - -void Chip::WriteBD( Bit8u val ) { - Bit8u change = regBD ^ val; - if ( !change ) - return; - regBD = val; - //TODO could do this with shift and xor? - vibratoStrength = (val & 0x40) ? 0x00 : 0x01; - tremoloStrength = (val & 0x80) ? 0x00 : 0x02; - if ( val & 0x20 ) { - //Drum was just enabled, make sure channel 6 has the right synth - if ( change & 0x20 ) { - // if ( opl3Active ) { - if ( is_opl3 ) { - chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; - } else { - chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; - } - } - //Bass Drum - if ( val & 0x10 ) { - chan[6].op[0].KeyOn( 0x2 ); - chan[6].op[1].KeyOn( 0x2 ); - } else { - chan[6].op[0].KeyOff( 0x2 ); - chan[6].op[1].KeyOff( 0x2 ); - } - //Hi-Hat - if ( val & 0x1 ) { - chan[7].op[0].KeyOn( 0x2 ); - } else { - chan[7].op[0].KeyOff( 0x2 ); - } - //Snare - if ( val & 0x8 ) { - chan[7].op[1].KeyOn( 0x2 ); - } else { - chan[7].op[1].KeyOff( 0x2 ); - } - //Tom-Tom - if ( val & 0x4 ) { - chan[8].op[0].KeyOn( 0x2 ); - } else { - chan[8].op[0].KeyOff( 0x2 ); - } - //Top Cymbal - if ( val & 0x2 ) { - chan[8].op[1].KeyOn( 0x2 ); - } else { - chan[8].op[1].KeyOff( 0x2 ); - } - //Toggle keyoffs when we turn off the percussion - } else if ( change & 0x20 ) { - //Trigger a reset to setup the original synth handler - chan[6].ResetC0( this ); - chan[6].op[0].KeyOff( 0x2 ); - chan[6].op[1].KeyOff( 0x2 ); - chan[7].op[0].KeyOff( 0x2 ); - chan[7].op[1].KeyOff( 0x2 ); - chan[8].op[0].KeyOff( 0x2 ); - chan[8].op[1].KeyOff( 0x2 ); - } -} - - -#define REGOP( _FUNC_ ) \ - index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ - if ( OpOffsetTable[ index ] ) { \ - Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ - regOp->_FUNC_( this, val ); \ - } - -#define REGCHAN( _FUNC_ ) \ - index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ - if ( ChanOffsetTable[ index ] ) { \ - Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ - regChan->_FUNC_( this, val ); \ - } - -void Chip::WriteReg( Bit32u reg, Bit8u val ) { - Bitu index; - switch ( (reg & 0xf0) >> 4 ) { - case 0x00 >> 4: - if ( reg == 0x01 ) { - waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; - } else if ( reg == 0x104 ) { - //Only detect changes in lowest 6 bits - if ( !((reg104 ^ val) & 0x3f) ) - return; - //Always keep the highest bit enabled, for checking > 0x80 - reg104 = 0x80 | ( val & 0x3f ); - } else if ( reg == 0x105 ) { - //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register - if ( !((opl3Active ^ val) & 1 ) ) - return; - opl3Active = ( val & 1 ) ? 0xff : 0; - //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers - for ( int i = 0; i < 18;i++ ) { - chan[i].ResetC0( this ); - } - } else if ( reg == 0x08 ) { - reg08 = val; - } - case 0x10 >> 4: - break; - case 0x20 >> 4: - case 0x30 >> 4: - REGOP( Write20 ); - break; - case 0x40 >> 4: - case 0x50 >> 4: - REGOP( Write40 ); - break; - case 0x60 >> 4: - case 0x70 >> 4: - REGOP( Write60 ); - break; - case 0x80 >> 4: - case 0x90 >> 4: - REGOP( Write80 ); - break; - case 0xa0 >> 4: - REGCHAN( WriteA0 ); - break; - case 0xb0 >> 4: - if ( reg == 0xbd ) { - WriteBD( val ); - } else { - REGCHAN( WriteB0 ); - } - break; - case 0xc0 >> 4: - REGCHAN( WriteC0 ); - case 0xd0 >> 4: - break; - case 0xe0 >> 4: - case 0xf0 >> 4: - REGOP( WriteE0 ); - break; - } -} - - -Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { - switch ( port & 3 ) { - case 0: - return val; - case 2: - if ( opl3Active || (val == 0x05) ) - return 0x100 | val; - else - return val; - } - return 0; -} - -void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { - while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); - memset(output, 0, sizeof(Bit32s) * samples); - int count = 0; - for( Channel* ch = chan; ch < chan + 9; ) { - count++; - ch = (ch->*(ch->synthHandler))( this, samples, output ); - } - total -= samples; - output += samples; - } -} - -void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { - while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); - memset(output, 0, sizeof(Bit32s) * samples *2); - int count = 0; - for( Channel* ch = chan; ch < chan + 18; ) { - count++; - ch = (ch->*(ch->synthHandler))( this, samples, output ); - } - total -= samples; - output += samples * 2; - } -} - -void Chip::Setup( Bit32u rate, int chip_is_opl3 ) { - double original = OPLRATE; -// double original = rate; - double scale = original / (double)rate; - - is_opl3 = chip_is_opl3; - - //Noise counter is run at the same precision as general waves - noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); - noiseCounter = 0; - noiseValue = 1; //Make sure it triggers the noise xor the first time - //The low frequency oscillation counter - //Every time his overflows vibrato and tremoloindex are increased - lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); - lfoCounter = 0; - vibratoIndex = 0; - tremoloIndex = 0; - - //With higher octave this gets shifted up - //-1 since the freqCreateTable = *2 -#ifdef WAVE_PRECISION - double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); - for ( int i = 0; i < 16; i++ ) { - freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); - } -#else - Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); - for ( int i = 0; i < 16; i++ ) { - freqMul[i] = freqScale * FreqCreateTable[ i ]; - } -#endif - - //-3 since the real envelope takes 8 steps to reach the single value we supply - for ( Bit8u i = 0; i < 76; i++ ) { - Bit8u index, shift; - EnvelopeSelect( i, index, shift ); - linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); - } - //Generate the best matching attack rate - for ( Bit8u i = 0; i < 62; i++ ) { - Bit8u index, shift; - EnvelopeSelect( i, index, shift ); - //Original amount of samples the attack would take - Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); - - Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); - Bit32s bestAdd = guessAdd; - Bit32u bestDiff = 1 << 30; - for( Bit32u passes = 0; passes < 16; passes ++ ) { - Bit32s volume = ENV_MAX; - Bit32s samples = 0; - Bit32u count = 0; - while ( volume > 0 && samples < original * 2 ) { - count += guessAdd; - Bit32s change = count >> RATE_SH; - count &= RATE_MASK; - if ( GCC_UNLIKELY(change) ) { // less than 1 % - volume += ( ~volume * change ) >> 3; - } - samples++; - - } - Bit32s diff = original - samples; - Bit32u lDiff = labs( diff ); - //Init last on first pass - if ( lDiff < bestDiff ) { - bestDiff = lDiff; - bestAdd = guessAdd; - if ( !bestDiff ) - break; - } - //Below our target - if ( diff < 0 ) { - //Better than the last time - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = ((guessAdd * mul) >> 12); - guessAdd++; - } else if ( diff > 0 ) { - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = (guessAdd * mul) >> 12; - guessAdd--; - } - } - attackRates[i] = bestAdd; - } - for ( Bit8u i = 62; i < 76; i++ ) { - //This should provide instant volume maximizing - attackRates[i] = 8 << RATE_SH; - } - //Setup the channels with the correct four op flags - //Channels are accessed through a table so they appear linear here - chan[ 0].fourMask = 0x00 | ( 1 << 0 ); - chan[ 1].fourMask = 0x80 | ( 1 << 0 ); - chan[ 2].fourMask = 0x00 | ( 1 << 1 ); - chan[ 3].fourMask = 0x80 | ( 1 << 1 ); - chan[ 4].fourMask = 0x00 | ( 1 << 2 ); - chan[ 5].fourMask = 0x80 | ( 1 << 2 ); - - chan[ 9].fourMask = 0x00 | ( 1 << 3 ); - chan[10].fourMask = 0x80 | ( 1 << 3 ); - chan[11].fourMask = 0x00 | ( 1 << 4 ); - chan[12].fourMask = 0x80 | ( 1 << 4 ); - chan[13].fourMask = 0x00 | ( 1 << 5 ); - chan[14].fourMask = 0x80 | ( 1 << 5 ); - - //mark the percussion channels - chan[ 6].fourMask = 0x40; - chan[ 7].fourMask = 0x40; - chan[ 8].fourMask = 0x40; - - //Clear Everything in opl3 mode - WriteReg( 0x105, 0x1 ); - for ( int i = 0; i < 512; i++ ) { - if ( i == 0x105 ) - continue; - WriteReg( i, 0xff ); - WriteReg( i, 0x0 ); - } - WriteReg( 0x105, 0x0 ); - //Clear everything in opl2 mode - for ( int i = 0; i < 255; i++ ) { - WriteReg( i, 0xff ); - WriteReg( i, 0x0 ); - } -} - -static bool doneTables = false; -void InitTables( void ) { - if ( doneTables ) - return; - doneTables = true; -#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) - //Exponential volume table, same as the real adlib - for ( int i = 0; i < 256; i++ ) { - //Save them in reverse - ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); - ExpTable[i] += 1024; //or remove the -1 oh well :) - //Preshift to the left once so the final volume can shift to the right - ExpTable[i] *= 2; - } -#endif -#if ( DBOPL_WAVE == WAVE_HANDLER ) - //Add 0.5 for the trunc rounding of the integer cast - //Do a PI sinetable instead of the original 0.5 PI - for ( int i = 0; i < 512; i++ ) { - SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); - } -#endif -#if ( DBOPL_WAVE == WAVE_TABLEMUL ) - //Multiplication based tables - for ( int i = 0; i < 384; i++ ) { - int s = i * 8; - //TODO maybe keep some of the precision errors of the original table? - double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); - MulTable[i] = (Bit16u)(val); - } - - //Sine Wave Base - for ( int i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); - WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; - } - //Exponential wave - for ( int i = 0; i < 256; i++ ) { - WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); - WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; - } -#endif -#if ( DBOPL_WAVE == WAVE_TABLELOG ) - //Sine Wave Base - for ( int i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); - WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; - } - //Exponential wave - for ( int i = 0; i < 256; i++ ) { - WaveTable[ 0x700 + i ] = i * 8; - WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; - } -#endif - - // | |//\\|____|WAV7|//__|/\ |____|/\/\| - // |\\//| | |WAV7| | \/| | | - // |06 |0126|27 |7 |3 |4 |4 5 |5 | - -#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) - for ( int i = 0; i < 256; i++ ) { - //Fill silence gaps - WaveTable[ 0x400 + i ] = WaveTable[0]; - WaveTable[ 0x500 + i ] = WaveTable[0]; - WaveTable[ 0x900 + i ] = WaveTable[0]; - WaveTable[ 0xc00 + i ] = WaveTable[0]; - WaveTable[ 0xd00 + i ] = WaveTable[0]; - //Replicate sines in other pieces - WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; - //double speed sines - WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; - WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; - } -#endif - - //Create the ksl table - for ( int oct = 0; oct < 8; oct++ ) { - int base = oct * 8; - for ( int i = 0; i < 16; i++ ) { - int val = base - KslCreateTable[i]; - if ( val < 0 ) - val = 0; - //*4 for the final range to match attenuation range - KslTable[ oct * 16 + i ] = val * 4; - } - } - //Create the Tremolo table, just increase and decrease a triangle wave - for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) { - Bit8u val = i << ENV_EXTRA; - TremoloTable[i] = val; - TremoloTable[TREMOLO_TABLE - 1 - i] = val; - } - //Create a table with offsets of the channels from the start of the chip - DBOPL::Chip* chip = 0; - for ( Bitu i = 0; i < 32; i++ ) { - Bitu index = i & 0xf; - if ( index >= 9 ) { - ChanOffsetTable[i] = 0; - continue; - } - //Make sure the four op channels follow eachother - if ( index < 6 ) { - index = (index % 3) * 2 + ( index / 3 ); - } - //Add back the bits for highest ones - if ( i >= 16 ) - index += 9; - intptr_t blah = reinterpret_cast( &(chip->chan[ index ]) ); - ChanOffsetTable[i] = blah; - } - //Same for operators - for ( Bitu i = 0; i < 64; i++ ) { - if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { - OpOffsetTable[i] = 0; - continue; - } - Bitu chNum = (i / 8) * 3 + (i % 8) % 3; - //Make sure we use 16 and up for the 2nd range to match the chanoffset gap - if ( chNum >= 12 ) - chNum += 16 - 12; - Bitu opNum = ( i % 8 ) / 3; - DBOPL::Channel* chan = 0; - intptr_t blah = reinterpret_cast( &(chan->op[opNum]) ); - OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah; - } -#if 0 - //Stupid checks if table's are correct - for ( Bitu i = 0; i < 18; i++ ) { - Bit32u find = (Bit16u)( &(chip->chan[ i ]) ); - for ( Bitu c = 0; c < 32; c++ ) { - if ( ChanOffsetTable[c] == find ) { - find = 0; - break; - } - } - if ( find ) { - find = find; - } - } - for ( Bitu i = 0; i < 36; i++ ) { - Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) ); - for ( Bitu c = 0; c < 64; c++ ) { - if ( OpOffsetTable[c] == find ) { - find = 0; - break; - } - } - if ( find ) { - find = find; - } - } -#endif -} - -/*Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) { - return chip.WriteAddr( port, val ); - -} -void Handler::WriteReg( Bit32u addr, Bit8u val ) { - chip.WriteReg( addr, val ); -} - -void Handler::Generate( MixerChannel* chan, Bitu samples ) { - Bit32s buffer[ 512 * 2 ]; - if ( GCC_UNLIKELY(samples > 512) ) - samples = 512; - if ( !chip.opl3Active ) { - chip.GenerateBlock2( samples, buffer ); - chan->AddSamples_m32( samples, buffer ); - } else { - chip.GenerateBlock3( samples, buffer ); - chan->AddSamples_s32( samples, buffer ); - } -} - -void Handler::Init( Bitu rate ) { - InitTables(); - chip.Setup( rate ); -}*/ - - -}; //Namespace DBOPL - diff --git a/src - Cópia/sound/dbopl.h b/src - Cópia/sound/dbopl.h deleted file mode 100644 index 7507dd1a4..000000000 --- a/src - Cópia/sound/dbopl.h +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright holders: The DOSBox Team - see COPYING for more details -*/ - -//#include "adlib.h" -//#include "dosbox.h" -#include -typedef signed int Bits; -typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; -typedef uint16_t Bit16u; -typedef int32_t Bit32s; -typedef uint32_t Bit32u; - -#define INLINE inline - -#define GCC_UNLIKELY(x) (x) - -//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume -#define WAVE_HANDLER 10 -//Use a logarithmic wavetable with an exponential table for volume -#define WAVE_TABLELOG 11 -//Use a linear wavetable with a multiply table for volume -#define WAVE_TABLEMUL 12 - -//Select the type of wave generator routine -#define DBOPL_WAVE WAVE_TABLEMUL - -namespace DBOPL { - -struct Chip; -struct Operator; -struct Channel; - -#if (DBOPL_WAVE == WAVE_HANDLER) -typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); -#endif - -typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); -typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output ); - -//Different synth modes that can generate blocks of data -typedef enum { - sm2AM, - sm2FM, - sm3AM, - sm3FM, - sm4Start, - sm3FMFM, - sm3AMFM, - sm3FMAM, - sm3AMAM, - sm6Start, - sm2Percussion, - sm3Percussion, -} SynthMode; - -//Shifts for the values contained in chandata variable -enum { - SHIFT_KSLBASE = 16, - SHIFT_KEYCODE = 24, -}; - -struct Operator { -public: - //Masks for operator 20 values - enum { - MASK_KSR = 0x10, - MASK_SUSTAIN = 0x20, - MASK_VIBRATO = 0x40, - MASK_TREMOLO = 0x80, - }; - - typedef enum { - OFF, - RELEASE, - SUSTAIN, - DECAY, - ATTACK, - } State; - - VolumeHandler volHandler; - -#if (DBOPL_WAVE == WAVE_HANDLER) - WaveHandler waveHandler; //Routine that generate a wave -#else - Bit16s* waveBase; - Bit32u waveMask; - Bit32u waveStart; -#endif - Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index - Bit32u waveAdd; //The base frequency without vibrato - Bit32u waveCurrent; //waveAdd + vibratao - - Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this - Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? - Bit32u vibrato; //Scaled up vibrato strength - Bit32s sustainLevel; //When stopping at sustain level stop here - Bit32s totalLevel; //totalLevel is added to every generated volume - Bit32u currentLevel; //totalLevel + tremolo - Bit32s volume; //The currently active volume - - Bit32u attackAdd; //Timers for the different states of the envelope - Bit32u decayAdd; - Bit32u releaseAdd; - Bit32u rateIndex; //Current position of the evenlope - - Bit8u rateZero; //Bits for the different states of the envelope having no changes - Bit8u keyOn; //Bitmask of different values that can generate keyon - //Registers, also used to check for changes - Bit8u reg20, reg40, reg60, reg80, regE0; - //Active part of the envelope we're in - Bit8u state; - //0xff when tremolo is enabled - Bit8u tremoloMask; - //Strength of the vibrato - Bit8u vibStrength; - //Keep track of the calculated KSR so we can check for changes - Bit8u ksr; -private: - void SetState( Bit8u s ); - void UpdateAttack( const Chip* chip ); - void UpdateRelease( const Chip* chip ); - void UpdateDecay( const Chip* chip ); -public: - void UpdateAttenuation(); - void UpdateRates( const Chip* chip ); - void UpdateFrequency( ); - - void Write20( const Chip* chip, Bit8u val ); - void Write40( const Chip* chip, Bit8u val ); - void Write60( const Chip* chip, Bit8u val ); - void Write80( const Chip* chip, Bit8u val ); - void WriteE0( const Chip* chip, Bit8u val ); - - bool Silent() const; - void Prepare( const Chip* chip ); - - void KeyOn( Bit8u mask); - void KeyOff( Bit8u mask); - - template< State state> - Bits TemplateVolume( ); - - Bit32s RateForward( Bit32u add ); - Bitu ForwardWave(); - Bitu ForwardVolume(); - - Bits GetSample( Bits modulation ); - Bits GetWave( Bitu index, Bitu vol ); -public: - Operator(); -}; - -struct Channel { - Operator op[2]; - inline Operator* Op( Bitu index ) { - return &( ( this + (index >> 1) )->op[ index & 1 ]); - } - SynthHandler synthHandler; - Bit32u chanData; //Frequency/octave and derived values - Bit32s old[2]; //Old data for feedback - - Bit8u feedback; //Feedback shift - Bit8u regB0; //Register values to check for changes - Bit8u regC0; - //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel - Bit8u fourMask; - Bit8s maskLeft; //Sign extended values for both channel's panning - Bit8s maskRight; - - //Forward the channel data to the operators of the channel - void SetChanData( const Chip* chip, Bit32u data ); - //Change in the chandata, check for new values and if we have to forward to operators - void UpdateFrequency( const Chip* chip, Bit8u fourOp ); - void WriteA0( const Chip* chip, Bit8u val ); - void WriteB0( const Chip* chip, Bit8u val ); - void WriteC0( const Chip* chip, Bit8u val ); - void ResetC0( const Chip* chip ); - - //call this for the first channel - template< bool opl3Mode > - void GeneratePercussion( Chip* chip, Bit32s* output ); - - //Generate blocks of data in specific modes - template - Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); - Channel(); -}; - -struct Chip { - //This is used as the base counter for vibrato and tremolo - Bit32u lfoCounter; - Bit32u lfoAdd; - - - Bit32u noiseCounter; - Bit32u noiseAdd; - Bit32u noiseValue; - - //Frequency scales for the different multiplications - Bit32u freqMul[16]; - //Rates for decay and release for rate of this chip - Bit32u linearRates[76]; - //Best match attack rates for the rate of this chip - Bit32u attackRates[76]; - - //18 channels with 2 operators each - Channel chan[18]; - - Bit8u reg104; - Bit8u reg08; - Bit8u reg04; - Bit8u regBD; - Bit8u vibratoIndex; - Bit8u tremoloIndex; - Bit8s vibratoSign; - Bit8u vibratoShift; - Bit8u tremoloValue; - Bit8u vibratoStrength; - Bit8u tremoloStrength; - //Mask for allowed wave forms - Bit8u waveFormMask; - //0 or -1 when enabled - Bit8s opl3Active; - - int is_opl3; - - //Return the maximum amount of samples before and LFO change - Bit32u ForwardLFO( Bit32u samples ); - Bit32u ForwardNoise(); - - void WriteBD( Bit8u val ); - void WriteReg(Bit32u reg, Bit8u val ); - - Bit32u WriteAddr( Bit32u port, Bit8u val ); - - void GenerateBlock2( Bitu samples, Bit32s* output ); - void GenerateBlock3( Bitu samples, Bit32s* output ); - - void Generate( Bit32u samples ); - void Setup( Bit32u r, int chip_is_opl3 ); - - Chip(); -}; - -/*struct Handler : public Adlib::Handler { - DBOPL::Chip chip; - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ); - virtual void WriteReg( Bit32u addr, Bit8u val ); - virtual void Generate( MixerChannel* chan, Bitu samples ); - virtual void Init( Bitu rate ); -};*/ - -void InitTables( void ); - -}; //Namespace diff --git a/src - Cópia/sound/filters.h b/src - Cópia/sound/filters.h deleted file mode 100644 index 95354176e..000000000 --- a/src - Cópia/sound/filters.h +++ /dev/null @@ -1,377 +0,0 @@ -#define NCoef 2 - -/* fc=350Hz */ -static inline float low_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.00049713569693400649, - 0.00099427139386801299, - 0.00049713569693400649 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.93522955470669530000, - 0.93726236021404663000 - }; - - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - -/* fc=350Hz */ -static inline float low_cut_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.96839970114733542000, - -1.93679940229467080000, - 0.96839970114733542000 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.93522955471202770000, - 0.93726236021916731000 - }; - - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - -/* fc=3.5kHz */ -static inline float high_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.72248704753064896000, - -1.44497409506129790000, - 0.72248704753064896000 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.36640781670578510000, - 0.52352474706139873000 - }; - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - -/* fc=3.5kHz */ -static inline float high_cut_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.03927726802250377400, - 0.07855453604500754700, - 0.03927726802250377400 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.36640781666419950000, - 0.52352474703279628000 - }; - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - - -#undef NCoef -#define NCoef 2 - -/* fc=3.2kHz */ -static inline float sb_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.03356837051492005100, - 0.06713674102984010200, - 0.03356837051492005100 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.41898265221812010000, - 0.55326988968868285000 - }; - -/* float ACoef[NCoef+1] = { - 0.17529642630084405000, - 0.17529642630084405000 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -0.64940759319751051000 - };*/ - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - - - -#undef NCoef -#define NCoef 2 - -/* fc=150Hz */ -static inline float adgold_highpass_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.98657437157334349000, - -1.97314874314668700000, - 0.98657437157334349000 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.97223372919758360000, - 0.97261396931534050000 - }; - - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - -/* fc=150Hz */ -static inline float adgold_lowpass_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.00009159473951071446, - 0.00018318947902142891, - 0.00009159473951071446 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.97223372919526560000, - 0.97261396931306277000 - }; - - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - -/* fc=56Hz */ -static inline float adgold_pseudo_stereo_iir(float NewSample) { - float ACoef[NCoef+1] = { - 0.00001409030866231767, - 0.00002818061732463533, - 0.00001409030866231767 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.98733021473466760000, - 0.98738361004063568000 - }; - - static float y[NCoef+1]; /* output samples */ - static float x[NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[n] = x[n-1]; - y[n] = y[n-1]; - } - - /* Calculate the new output */ - x[0] = NewSample; - y[0] = ACoef[0] * x[0]; - for(n=1; n<=NCoef; n++) - y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; - - return y[0]; -} - -/* fc=3.2kHz - probably incorrect */ -static inline float dss_iir(float NewSample) { - float ACoef[NCoef+1] = { - 0.03356837051492005100, - 0.06713674102984010200, - 0.03356837051492005100 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.41898265221812010000, - 0.55326988968868285000 - }; - - static float y[NCoef+1]; /* output samples */ - static float x[NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[n] = x[n-1]; - y[n] = y[n-1]; - } - - /* Calculate the new output */ - x[0] = NewSample; - y[0] = ACoef[0] * x[0]; - for(n=1; n<=NCoef; n++) - y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; - - return y[0]; -} - -#undef NCoef -#define NCoef 1 -/*Basic high pass to remove DC bias. fc=10Hz*/ -static inline float dac_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.99901119820285345000, - -0.99901119820285345000 - }; - - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -0.99869185905052738000 - }; - - static float y[2][NCoef+1]; /* output samples */ - static float x[2][NCoef+1]; /* input samples */ - int n; - - /* shift the old samples */ - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } - - /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; - for(n=1; n<=NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; - - return y[i][0]; -} - - -#define SB16_NCoef 51 - -extern float low_fir_sb16_coef[SB16_NCoef]; - -static inline float low_fir_sb16(int i, float NewSample) -{ - static float x[2][SB16_NCoef+1]; //input samples - static int pos = 0; - float out = 0.0; - int n; - - /* Calculate the new output */ - x[i][pos] = NewSample; - - for (n = 0; n < ((SB16_NCoef+1)-pos) && n < SB16_NCoef; n++) - out += low_fir_sb16_coef[n] * x[i][n+pos]; - for (; n < SB16_NCoef; n++) - out += low_fir_sb16_coef[n] * x[i][(n+pos) - (SB16_NCoef+1)]; - - if (i == 1) - { - pos++; - if (pos > SB16_NCoef) - pos = 0; - } - - return out; -} diff --git a/src - Cópia/sound/midi.c b/src - Cópia/sound/midi.c deleted file mode 100644 index d49eb6b29..000000000 --- a/src - Cópia/sound/midi.c +++ /dev/null @@ -1,260 +0,0 @@ -#include -#include -#include -#include -#include -#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 - - -int midi_device_current = 0; -static int midi_device_last = 0; - - -typedef struct -{ - const char *name; - const char *internal_name; - const device_t *device; -} MIDI_DEVICE; - -static const MIDI_DEVICE devices[] = -{ - {"None", "none", NULL}, -#ifdef USE_FLUIDSYNTH - {"FluidSynth", "fluidsynth", &fluidsynth_device}, -#endif -#ifdef USE_MUNT - {"Roland MT-32 Emulation", "mt32", &mt32_device}, - {"Roland CM-32L Emulation", "cm32l", &cm32l_device}, -#endif - {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, - {"", "", NULL} -}; - -static midi_device_t* m_device = NULL; - -int midi_device_available(int card) -{ - if (devices[card].device) - return device_available(devices[card].device); - - return 1; -} - -char *midi_device_getname(int card) -{ - return (char *) devices[card].name; -} - -const device_t *midi_device_getdevice(int card) -{ - return devices[card].device; -} - -int midi_device_has_config(int card) -{ - if (!devices[card].device) - return 0; - return devices[card].device->config ? 1 : 0; -} - -char *midi_device_get_internal_name(int card) -{ - return (char *) devices[card].internal_name; -} - -int midi_device_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(devices[c].internal_name)) - { - if (!strcmp(devices[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -void midi_device_init() -{ - if (devices[midi_device_current].device) - device_add(devices[midi_device_current].device); - midi_device_last = midi_device_current; -} - -static uint8_t midi_rt_buf[1024]; -static uint8_t midi_cmd_buf[1024]; -static int midi_cmd_pos = 0; -static int midi_cmd_len = 0; -static uint8_t midi_status = 0; -static unsigned int midi_sysex_start = 0; -static unsigned int midi_sysex_delay = 0; - -uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 - - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 -}; - -static unsigned int midi_pos; -static uint8_t midi_sysex_data[1024+2]; - -void midi_init(midi_device_t* device) -{ - memset(midi_rt_buf, 0, sizeof(midi_rt_buf)); - memset(midi_cmd_buf, 0, sizeof(midi_cmd_buf)); - - midi_cmd_pos = midi_cmd_len = 0; - midi_status = 0; - - midi_sysex_start = midi_sysex_delay = 0; - - m_device = device; - -} - -void midi_close() -{ - m_device = NULL; -} - -void midi_poll() -{ - if (m_device && m_device->poll) m_device->poll(); -} - -void play_msg(uint8_t *msg) -{ - if (m_device->play_msg) m_device->play_msg(msg); -} - - -void play_sysex(uint8_t *sysex, unsigned int len) -{ - if (m_device->play_sysex) m_device->play_sysex(sysex, len); -} - -#define SYSEX_SIZE 1024 -#define RAWBUF 1024 - -void midi_write(uint8_t val) -{ - if (!m_device) return; - - if (m_device->write && m_device->write(val)) return; - - uint32_t passed_ticks; - - if (midi_sysex_start) - { - passed_ticks = plat_get_ticks() - midi_sysex_start; - if (passed_ticks < midi_sysex_delay) - { - plat_delay_ms(midi_sysex_delay - passed_ticks); - } - } - - /* Test for a realtime MIDI message */ - if (val >= 0xf8) - { - midi_rt_buf[0] = val; - play_msg(midi_rt_buf); - return; - } - - /* Test for a active sysex transfer */ - - if (midi_status == 0xf0) - { - if (!(val & 0x80)) - { - if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; - return; - } - else - { - midi_sysex_data[midi_pos++] = 0xf7; - - if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x41) && (midi_sysex_data[3] == 0x16)) - { - /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ - } - else - { - play_sysex(midi_sysex_data, midi_pos); - if (midi_sysex_start) - { - if (midi_sysex_data[5] == 0x7f) - { - midi_sysex_delay = 290; /* All parameters reset */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) - { - midi_sysex_delay = 145; /* Viking Child */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) - { - midi_sysex_delay = 30; /* Dark Sun 1 */ - } - else - midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - - midi_sysex_start = plat_get_ticks(); - } - } - } - } - - - if (val & 0x80) - { - midi_status = val; - midi_cmd_pos = 0; - midi_cmd_len = MIDI_evt_len[val]; - if (midi_status == 0xf0) - { - midi_sysex_data[0] = 0xf0; - midi_pos = 1; - } - } - - if (midi_cmd_len) - { - midi_cmd_buf[midi_cmd_pos++] = val; - if (midi_cmd_pos >= midi_cmd_len) - { - play_msg(midi_cmd_buf); - midi_cmd_pos = 1; - } - } -} diff --git a/src - Cópia/sound/midi.h b/src - Cópia/sound/midi.h deleted file mode 100644 index 6268a0e0c..000000000 --- a/src - Cópia/sound/midi.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef EMU_SOUND_MIDI_H -# define EMU_SOUND_MIDI_H - - -extern int midi_device_current; - - -int midi_device_available(int card); -char *midi_device_getname(int card); -#ifdef EMU_DEVICE_H -const device_t *midi_device_getdevice(int card); -#endif -int midi_device_has_config(int card); -char *midi_device_get_internal_name(int card); -int midi_device_get_from_internal_name(char *s); -void midi_device_init(); - -typedef struct midi_device_t -{ - void (*play_sysex)(uint8_t *sysex, unsigned int len); - void (*play_msg)(uint8_t *msg); - void (*poll)(); - int (*write)(uint8_t val); -} midi_device_t; - -void midi_init(midi_device_t* device); -void midi_close(); -void midi_write(uint8_t val); -void midi_poll(); - -#if 0 -#ifdef _WIN32 -#define SYSTEM_MIDI_NAME "Windows MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "windows_midi" -#else -#define SYSTEM_MIDI_NAME "System MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" -#endif -#else -#define SYSTEM_MIDI_NAME "System MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" -#endif - - -#endif /*EMU_SOUND_MIDI_H*/ diff --git a/src - Cópia/sound/midi_fluidsynth.c b/src - Cópia/sound/midi_fluidsynth.c deleted file mode 100644 index 22d318fbf..000000000 --- a/src - Cópia/sound/midi_fluidsynth.c +++ /dev/null @@ -1,578 +0,0 @@ -/* some code borrowed from scummvm */ -#ifdef USE_FLUIDSYNTH -#include -#include -#include -#include -#include -#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" - - -#define FLUID_CHORUS_DEFAULT_N 3 -#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f -#define FLUID_CHORUS_DEFAULT_SPEED 0.3f -#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f -#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE - -#define RENDER_RATE 100 -#define BUFFER_SEGMENTS 10 - - -enum fluid_chorus_mod { - FLUID_CHORUS_MOD_SINE = 0, - FLUID_CHORUS_MOD_TRIANGLE = 1 -}; - -enum fluid_interp { - FLUID_INTERP_NONE = 0, - FLUID_INTERP_LINEAR = 1, - FLUID_INTERP_DEFAULT = 4, - FLUID_INTERP_4THORDER = 4, - FLUID_INTERP_7THORDER = 7, - FLUID_INTERP_HIGHEST = 7 -}; - - -extern void givealbuffer_midi(void *buf, uint32_t size); -extern void al_set_midi(int freq, int buf_size); -extern int soundon; - -static void *fluidsynth_handle; /* handle to FluidSynth DLL */ - -/* Pointers to the real functions. */ -static void * (*f_new_fluid_settings)(void); -static void (*f_delete_fluid_settings)(void *settings); -static int (*f_fluid_settings_setnum)(void *settings, const char *name, double val); -static int (*f_fluid_settings_getnum)(void *settings, const char *name, double *val); -static void * (*f_new_fluid_synth)(void *settings); -static int (*f_delete_fluid_synth)(void *synth); -static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel); -static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key); -static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val); -static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun); -static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val); -static int (*f_fluid_synth_program_change)(void *synth, int chan, int program); -static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets); -static int (*f_fluid_synth_sfunload)(void *synth, unsigned int id, int reset_presets); -static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method); -static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level); -static void (*f_fluid_synth_set_reverb_on)(void *synth, int on); -static void (*f_fluid_synth_set_chorus)(void *synth, int nr, double level, double speed, double depth_ms, int type); -static void (*f_fluid_synth_set_chorus_on)(void *synth, int on); -static int (*f_fluid_synth_write_s16)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static int (*f_fluid_synth_write_float)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static char* (*f_fluid_version_str)(void); -static dllimp_t fluidsynth_imports[] = { - { "new_fluid_settings", &f_new_fluid_settings }, - { "delete_fluid_settings", &f_delete_fluid_settings }, - { "fluid_settings_setnum", &f_fluid_settings_setnum }, - { "fluid_settings_getnum", &f_fluid_settings_getnum }, - { "new_fluid_synth", &f_new_fluid_synth }, - { "delete_fluid_synth", &f_delete_fluid_synth }, - { "fluid_synth_noteon", &f_fluid_synth_noteon }, - { "fluid_synth_noteoff", &f_fluid_synth_noteoff }, - { "fluid_synth_cc", &f_fluid_synth_cc }, - { "fluid_synth_sysex", &f_fluid_synth_sysex }, - { "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend }, - { "fluid_synth_program_change", &f_fluid_synth_program_change }, - { "fluid_synth_sfload", &f_fluid_synth_sfload }, - { "fluid_synth_sfunload", &f_fluid_synth_sfunload }, - { "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method }, - { "fluid_synth_set_reverb", &f_fluid_synth_set_reverb }, - { "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on }, - { "fluid_synth_set_chorus", &f_fluid_synth_set_chorus }, - { "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on }, - { "fluid_synth_write_s16", &f_fluid_synth_write_s16 }, - { "fluid_synth_write_float", &f_fluid_synth_write_float }, - { "fluid_version_str", &f_fluid_version_str }, - { NULL, NULL }, -}; - - -typedef struct fluidsynth -{ - void* settings; - void* synth; - int samplerate; - int sound_font; - - thread_t* thread_h; - event_t* event; - int buf_size; - float* buffer; - int16_t* buffer_int16; - int midi_pos; - -} fluidsynth_t; - -fluidsynth_t fsdev; - -int fluidsynth_available(void) -{ - return 1; -} - -void fluidsynth_poll(void) -{ - fluidsynth_t* data = &fsdev; - data->midi_pos++; - if (data->midi_pos == 48000/RENDER_RATE) - { - data->midi_pos = 0; - thread_set_event(data->event); - } -} - -static void fluidsynth_thread(void *param) -{ - fluidsynth_t* data = (fluidsynth_t*)param; - int buf_pos = 0; - int buf_size = data->buf_size / BUFFER_SEGMENTS; - while (1) - { - thread_wait_event(data->event, -1); - if (sound_is_float) - { - float *buf = (float*)((uint8_t*)data->buffer + buf_pos); - memset(buf, 0, buf_size); - if (data->synth) - f_fluid_synth_write_float(data->synth, buf_size/(2 * sizeof(float)), buf, 0, 2, buf, 1, 2); - buf_pos += buf_size; - if (buf_pos >= data->buf_size) - { - if (soundon) - givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); - buf_pos = 0; - } - } - else - { - int16_t *buf = (int16_t*)((uint8_t*)data->buffer_int16 + buf_pos); - memset(buf, 0, buf_size); - if (data->synth) - f_fluid_synth_write_s16(data->synth, buf_size/(2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); - buf_pos += buf_size; - if (buf_pos >= data->buf_size) - { - if (soundon) - givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); - buf_pos = 0; - } - } - -#if 0 - if (sound_is_float) - { - memset(data->buffer, 0, data->buf_size * sizeof(float)); - if (data->synth) - f_fluid_synth_write_float(data->synth, data->buf_size/2, data->buffer, 0, 2, data->buffer, 1, 2); - if (soundon) - givealbuffer_midi(data->buffer, data->buf_size); - } - else - { - memset(data->buffer, 0, data->buf_size * sizeof(int16_t)); - if (data->synth) - f_fluid_synth_write_s16(data->synth, data->buf_size/2, data->buffer_int16, 0, 2, data->buffer_int16, 1, 2); - if (soundon) - givealbuffer_midi(data->buffer_int16, data->buf_size); - } -#endif - } -} - -void fluidsynth_msg(uint8_t *msg) -{ - fluidsynth_t* data = &fsdev; - - uint32_t val = *((uint32_t*)msg); - - uint32_t param2 = (uint8_t) ((val >> 16) & 0xFF); - uint32_t param1 = (uint8_t) ((val >> 8) & 0xFF); - uint8_t cmd = (uint8_t) (val & 0xF0); - uint8_t chan = (uint8_t) (val & 0x0F); - - switch (cmd) { - case 0x80: /* Note Off */ - f_fluid_synth_noteoff(data->synth, chan, param1); - break; - case 0x90: /* Note On */ - f_fluid_synth_noteon(data->synth, chan, param1, param2); - break; - case 0xA0: /* Aftertouch */ - break; - case 0xB0: /* Control Change */ - f_fluid_synth_cc(data->synth, chan, param1, param2); - break; - case 0xC0: /* Program Change */ - f_fluid_synth_program_change(data->synth, chan, param1); - break; - case 0xD0: /* Channel Pressure */ - break; - case 0xE0: /* Pitch Bend */ - f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1); - break; - case 0xF0: /* SysEx */ - break; - default: - break; - } -} - -void fluidsynth_sysex(uint8_t* data, unsigned int len) -{ - fluidsynth_t* d = &fsdev; - - f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); -} - -void* fluidsynth_init(const device_t *info) -{ - fluidsynth_t* data = &fsdev; - memset(data, 0, sizeof(fluidsynth_t)); - - /* Try loading the DLL. */ -#ifdef _WIN32 - fluidsynth_handle = dynld_module("libfluidsynth-1.dll", fluidsynth_imports); -#else - fluidsynth_handle = dynld_module("libfluidsynth.so", fluidsynth_imports); -#endif - if (fluidsynth_handle == NULL) - { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2081); - return NULL; - } - - data->settings = f_new_fluid_settings(); - - f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); - f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain")/100.0f); - - data->synth = f_new_fluid_synth(data->settings); - - char* sound_font = device_get_config_string("sound_font"); - data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1); - - if (device_get_config_int("chorus")) - { - f_fluid_synth_set_chorus_on(data->synth, 1); - - int chorus_voices = device_get_config_int("chorus_voices"); - double chorus_level = device_get_config_int("chorus_level") / 100.0; - double chorus_speed = device_get_config_int("chorus_speed") / 100.0; - double chorus_depth = device_get_config_int("chorus_depth") / 10.0; - - int chorus_waveform = FLUID_CHORUS_MOD_SINE; - if (device_get_config_int("chorus_waveform") == 0) - chorus_waveform = FLUID_CHORUS_MOD_SINE; - else - chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE; - - f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); - } - else - f_fluid_synth_set_chorus_on(data->synth, 0); - - if (device_get_config_int("reverb")) - { - f_fluid_synth_set_reverb_on(data->synth, 1); - - double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0; - double reverb_damping = device_get_config_int("reverb_damping") / 100.0; - int reverb_width = device_get_config_int("reverb_width"); - double reverb_level = device_get_config_int("reverb_level") / 100.0; - - f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); - } - else - f_fluid_synth_set_reverb_on(data->synth, 0); - - int interpolation = device_get_config_int("interpolation"); - int fs_interpolation = FLUID_INTERP_4THORDER; - - if (interpolation == 0) - fs_interpolation = FLUID_INTERP_NONE; - else if (interpolation == 1) - fs_interpolation = FLUID_INTERP_LINEAR; - else if (interpolation == 2) - fs_interpolation = FLUID_INTERP_4THORDER; - else if (interpolation == 3) - fs_interpolation = FLUID_INTERP_7THORDER; - - f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation); - - double samplerate; - f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); - data->samplerate = (int)samplerate; - if (sound_is_float) - { - data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(float)*BUFFER_SEGMENTS; - data->buffer = malloc(data->buf_size); - data->buffer_int16 = NULL; - } - else - { - data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(int16_t)*BUFFER_SEGMENTS; - data->buffer = NULL; - data->buffer_int16 = malloc(data->buf_size); - } - data->event = thread_create_event(); - data->thread_h = thread_create(fluidsynth_thread, data); - - al_set_midi(data->samplerate, data->buf_size); - - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = fluidsynth_msg; - dev->play_sysex = fluidsynth_sysex; - dev->poll = fluidsynth_poll; - - midi_init(dev); - - return dev; -} - -void fluidsynth_close(void* p) -{ - if (!p) return; - - fluidsynth_t* data = &fsdev; - - if (data->sound_font != -1) { - f_fluid_synth_sfunload(data->synth, data->sound_font, 1); - data->sound_font = -1; - } - - if (data->synth) { - f_delete_fluid_synth(data->synth); - data->synth = NULL; - } - - if (data->settings) { - f_delete_fluid_settings(data->settings); - data->settings = NULL; - } - - midi_close(); - - if (data->buffer) - { - free(data->buffer); - data->buffer = NULL; - } - - if (data->buffer_int16) - { - free(data->buffer_int16); - data->buffer_int16 = NULL; - } - - /* Unload the DLL if possible. */ - if (fluidsynth_handle != NULL) - { - dynld_close(fluidsynth_handle); - fluidsynth_handle = NULL; - } -} - -static const device_config_t fluidsynth_config[] = -{ - { - .name = "sound_font", - .description = "Sound Font", - .type = CONFIG_FNAME, - .default_string = "", - .file_filter = - { - { - .description = "SF2 Sound Fonts", - .extensions = - { - "sf2" - } - } - } - }, - { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "chorus", - .description = "Chorus", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "chorus_voices", - .description = "Chorus Voices", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 99 - }, - .default_int = 3 - }, - { - .name = "chorus_level", - .description = "Chorus Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "chorus_speed", - .description = "Chorus Speed", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 30, - .max = 500 - }, - .default_int = 30 - }, - { - .name = "chorus_depth", - .description = "Chorus Depth", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 210 - }, - .default_int = 80 - }, - { - .name = "chorus_waveform", - .description = "Chorus Waveform", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Sine", - .value = 0 - }, - { - .description = "Triangle", - .value = 1 - } - }, - .default_int = 0 - }, - { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "reverb_room_size", - .description = "Reverb Room Size", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 120 - }, - .default_int = 20 - }, - { - .name = "reverb_damping", - .description = "Reverb Damping", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 0 - }, - { - .name = "reverb_width", - .description = "Reverb Width", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 1 - }, - { - .name = "reverb_level", - .description = "Reverb Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 90 - }, - { - .name = "interpolation", - .description = "Interpolation Method", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "None", - .value = 0 - }, - { - .description = "Linear", - .value = 1 - }, - { - .description = "4th Order", - .value = 2 - }, - { - .description = "7th Order", - .value = 3 - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -const device_t fluidsynth_device = -{ - "FluidSynth", - 0, - 0, - fluidsynth_init, - fluidsynth_close, - NULL, - fluidsynth_available, - NULL, - NULL, - fluidsynth_config -}; - - -#endif /*USE_FLUIDSYNTH*/ diff --git a/src - Cópia/sound/midi_fluidsynth.h b/src - Cópia/sound/midi_fluidsynth.h deleted file mode 100644 index 518b1461d..000000000 --- a/src - Cópia/sound/midi_fluidsynth.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t fluidsynth_device; diff --git a/src - Cópia/sound/midi_mt32.c b/src - Cópia/sound/midi_mt32.c deleted file mode 100644 index 7903b2b05..000000000 --- a/src - Cópia/sound/midi_mt32.c +++ /dev/null @@ -1,330 +0,0 @@ -#include -#include -#include -#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 "sound.h" -#include "midi.h" -#include "midi_mt32.h" - - -extern void givealbuffer_midi(void *buf, uint32_t size); -extern void al_set_midi(int freq, int buf_size); - -static const mt32emu_report_handler_i_v0 handler_v0 = { - /** Returns the actual interface version ID */ - NULL, //mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); - - /** Callback for debug messages, in vprintf() format */ - NULL, //void (*printDebug)(void *instance_data, const char *fmt, va_list list); - /** Callbacks for reporting errors */ - NULL, //void (*onErrorControlROM)(void *instance_data); - NULL, //void (*onErrorPCMROM)(void *instance_data); - /** Callback for reporting about displaying a new custom message on LCD */ - NULL, //void (*showLCDMessage)(void *instance_data, const char *message); - /** Callback for reporting actual processing of a MIDI message */ - NULL, //void (*onMIDIMessagePlayed)(void *instance_data); - /** - * Callback for reporting an overflow of the input MIDI queue. - * Returns MT32EMU_BOOL_TRUE if a recovery action was taken - * and yet another attempt to enqueue the MIDI event is desired. - */ - NULL, //mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); - /** - * Callback invoked when a System Realtime MIDI message is detected in functions - * mt32emu_parse_stream and mt32emu_play_short_message and the likes. - */ - NULL, //void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); - /** Callbacks for reporting system events */ - NULL, //void (*onDeviceReset)(void *instance_data); - NULL, //void (*onDeviceReconfig)(void *instance_data); - /** Callbacks for reporting changes of reverb settings */ - NULL, //void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); - NULL, //void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); - NULL, //void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); - /** Callbacks for reporting various information */ - NULL, //void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); - NULL, //void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); -}; - -static const mt32emu_report_handler_i handler = { &handler_v0 }; - -static mt32emu_context context = NULL; -static int roms_present[2] = {-1, -1}; - -mt32emu_return_code mt32_check(const char* func, mt32emu_return_code ret, mt32emu_return_code expected) -{ - if (ret != expected) - { - return 0; - } - return 1; -} - -int mt32_available() -{ - if (roms_present[0] < 0) - roms_present[0] = (rom_present(L"roms/sound/mt32/mt32_control.rom") && rom_present(L"roms/sound/mt32/mt32_pcm.rom")); - return roms_present[0]; -} - -int cm32l_available() -{ - if (roms_present[1] < 0) - roms_present[1] = (rom_present(L"roms/sound/cm32l/cm32l_control.rom") && rom_present(L"roms/sound/cm32l/cm32l_pcm.rom")); - return roms_present[1]; -} - -static thread_t *thread_h = NULL; -static event_t *event = NULL; - -#define RENDER_RATE 100 -#define BUFFER_SEGMENTS 10 - -static uint32_t samplerate = 44100; -static int buf_size = 0; -static float* buffer = NULL; -static int16_t* buffer_int16 = NULL; -static int midi_pos = 0; - -void mt32_stream(float* stream, int len) -{ - if (context) mt32emu_render_float(context, stream, len); -} - -void mt32_stream_int16(int16_t* stream, int len) -{ - if (context) mt32emu_render_bit16s(context, stream, len); -} - -void mt32_poll() -{ - midi_pos++; - if (midi_pos == 48000/RENDER_RATE) - { - midi_pos = 0; - thread_set_event(event); - } -} - -extern int soundon; - -static void mt32_thread(void *param) -{ - int buf_pos = 0; - int bsize = buf_size / BUFFER_SEGMENTS; - while (1) - { - thread_wait_event(event, -1); - - if (sound_is_float) - { - float *buf = (float *) ((uint8_t*)buffer + buf_pos); - memset(buf, 0, bsize); - mt32_stream(buf, bsize / (2 * sizeof(float))); - buf_pos += bsize; - if (buf_pos >= buf_size) - { - if (soundon) - givealbuffer_midi(buffer, buf_size / sizeof(float)); - buf_pos = 0; - } - } - else - { - int16_t *buf = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos); - memset(buf, 0, bsize); - mt32_stream_int16(buf, bsize / (2 * sizeof(int16_t))); - buf_pos += bsize; - if (buf_pos >= buf_size) - { - if (soundon) - givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t)); - buf_pos = 0; - } - } - } -} - -void mt32_msg(uint8_t* val) -{ - if (context) mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t*)val), MT32EMU_RC_OK); -} - -void mt32_sysex(uint8_t* data, unsigned int len) -{ - if (context) mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK); -} - -void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom) -{ - wchar_t s[512]; - char fn[512]; - context = mt32emu_create_context(handler, NULL); - if (!rom_getfile(control_rom, s, 512)) return 0; - wcstombs(fn, s, (wcslen(s) << 1) + 2); - if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) return 0; - if (!rom_getfile(pcm_rom, s, 512)) return 0; - wcstombs(fn, s, (wcslen(s) << 1) + 2); - if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_PCM_ROM)) return 0; - - if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) return 0; - - event = thread_create_event(); - thread_h = thread_create(mt32_thread, 0); - samplerate = mt32emu_get_actual_stereo_output_samplerate(context); - /* buf_size = samplerate/RENDER_RATE*2; */ - if (sound_is_float) - { - buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(float); - buffer = malloc(buf_size); - buffer_int16 = NULL; - } - else - { - buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(int16_t); - buffer = NULL; - buffer_int16 = malloc(buf_size); - } - - mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f); - mt32emu_set_reverb_enabled(context, device_get_config_int("reverb")); - mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain")/100.0f); - mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo")); - mt32emu_set_nice_amp_ramp_enabled(context, device_get_config_int("nice_ramp")); - - al_set_midi(samplerate, buf_size); - - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = mt32_msg; - dev->play_sysex = mt32_sysex; - dev->poll = mt32_poll; - - midi_init(dev); - - return dev; -} - -void *mt32_init(const device_t *info) -{ - return mt32emu_init(L"roms/sound/mt32/mt32_control.rom", L"roms/sound/mt32/mt32_pcm.rom"); -} - -void *cm32l_init(const device_t *info) -{ - return mt32emu_init(L"roms/sound/cm32l/cm32l_control.rom", L"roms/sound/cm32l/cm32l_pcm.rom"); -} - -void mt32_close(void* p) -{ - if (!p) return; - - if (thread_h) - thread_kill(thread_h); - if (event) - thread_destroy_event(event); - event = NULL; - thread_h = NULL; - - if (context) - { - mt32emu_close_synth(context); - mt32emu_free_context(context); - } - context = NULL; - - if (buffer) - free(buffer); - buffer = NULL; - - if (buffer_int16) - free(buffer_int16); - buffer_int16 = NULL; - - midi_close(); - - free((midi_device_t*)p); -} - -static const device_config_t mt32_config[] = -{ - { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "reverb_output_gain", - .description = "Reverb Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "reversed_stereo", - .description = "Reversed stereo", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "nice_ramp", - .description = "Nice ramp", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .type = -1 - } -}; - -const device_t mt32_device = -{ - "Roland MT-32 Emulation", - 0, - 0, - mt32_init, - mt32_close, - NULL, - mt32_available, - NULL, - NULL, - mt32_config -}; - -const device_t cm32l_device = -{ - "Roland CM-32L Emulation", - 0, - 0, - cm32l_init, - mt32_close, - NULL, - cm32l_available, - NULL, - NULL, - mt32_config -}; diff --git a/src - Cópia/sound/midi_mt32.h b/src - Cópia/sound/midi_mt32.h deleted file mode 100644 index 0aa012fa1..000000000 --- a/src - Cópia/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 - Cópia/sound/midi_system.c b/src - Cópia/sound/midi_system.c deleted file mode 100644 index d9a15c6a9..000000000 --- a/src - Cópia/sound/midi_system.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "midi.h" -#include "midi_system.h" - - -void* system_midi_init(const device_t *info) -{ - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = plat_midi_play_msg; - dev->play_sysex = plat_midi_play_sysex; - dev->write = plat_midi_write; - - plat_midi_init(); - - midi_init(dev); - - return dev; -} - -void system_midi_close(void* p) -{ - plat_midi_close(); - - midi_close(); -} - -int system_midi_available(void) -{ - return plat_midi_get_num_devs(); -} - -static const device_config_t system_midi_config[] = -{ - { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .type = -1 - } -}; - -const device_t system_midi_device = -{ - SYSTEM_MIDI_NAME, - 0, 0, - system_midi_init, - system_midi_close, - NULL, - system_midi_available, - NULL, - NULL, - system_midi_config -}; diff --git a/src - Cópia/sound/midi_system.h b/src - Cópia/sound/midi_system.h deleted file mode 100644 index b79bbf96f..000000000 --- a/src - Cópia/sound/midi_system.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t system_midi_device; diff --git a/src - Cópia/sound/munt/Analog.cpp b/src - Cópia/sound/munt/Analog.cpp deleted file mode 100644 index 2901198f2..000000000 --- a/src - Cópia/sound/munt/Analog.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "Analog.h" -#include "Synth.h" - -namespace MT32Emu { - -/* FIR approximation of the overall impulse response of the cascade composed of the sample & hold circuit and the low pass filter - * of the MT-32 first generation. - * The coefficients below are found by windowing the inverse DFT of the 1024 pin frequency response converted to the minimum phase. - * The frequency response of the LPF is computed directly, the effect of the S&H is approximated by multiplying the LPF frequency - * response by the corresponding sinc. Although, the LPF has DC gain of 3.2, we ignore this in the emulation and use normalised model. - * The peak gain of the normalised cascade appears about 1.7 near 11.8 kHz. Relative error doesn't exceed 1% for the frequencies - * below 12.5 kHz. In the higher frequency range, the relative error is below 8%. Peak error value is at 16 kHz. - */ -static const FloatSample COARSE_LPF_FLOAT_TAPS_MT32[] = { - 1.272473681f, -0.220267785f, -0.158039905f, 0.179603785f, -0.111484097f, 0.054137498f, -0.023518029f, 0.010997169f, -0.006935698f -}; - -// Similar approximation for new MT-32 and CM-32L/LAPC-I LPF. As the voltage controlled amplifier was introduced, LPF has unity DC gain. -// The peak gain value shifted towards higher frequencies and a bit higher about 1.83 near 13 kHz. -static const FloatSample COARSE_LPF_FLOAT_TAPS_CM32L[] = { - 1.340615635f, -0.403331694f, 0.036005517f, 0.066156844f, -0.069672532f, 0.049563806f, -0.031113416f, 0.019169774f, -0.012421368f -}; - -static const unsigned int COARSE_LPF_INT_FRACTION_BITS = 14; - -// Integer versions of the FIRs above multiplied by (1 << 14) and rounded. -static const IntSampleEx COARSE_LPF_INT_TAPS_MT32[] = { - 20848, -3609, -2589, 2943, -1827, 887, -385, 180, -114 -}; - -static const IntSampleEx COARSE_LPF_INT_TAPS_CM32L[] = { - 21965, -6608, 590, 1084, -1142, 812, -510, 314, -204 -}; - -/* Combined FIR that both approximates the impulse response of the analogue circuits of sample & hold and the low pass filter - * in the audible frequency range (below 20 kHz) and attenuates unwanted mirror spectra above 28 kHz as well. It is a polyphase - * filter intended for resampling the signal to 48 kHz yet for applying high frequency boost. - * As with the filter above, the analogue LPF frequency response is obtained for 1536 pin grid for range up to 96 kHz and multiplied - * by the corresponding sinc. The result is further squared, windowed and passed to generalised Parks-McClellan routine as a desired response. - * Finally, the minimum phase factor is found that's essentially the coefficients below. - * Relative error in the audible frequency range doesn't exceed 0.0006%, attenuation in the stopband is better than 100 dB. - * This level of performance makes it nearly bit-accurate for standard 16-bit sample resolution. - */ - -// FIR version for MT-32 first generation. -static const FloatSample ACCURATE_LPF_TAPS_MT32[] = { - 0.003429281f, 0.025929869f, 0.096587777f, 0.228884848f, 0.372413431f, 0.412386503f, 0.263980018f, - -0.014504962f, -0.237394528f, -0.257043496f, -0.103436603f, 0.063996095f, 0.124562333f, 0.083703206f, - 0.013921662f, -0.033475018f, -0.046239712f, -0.029310921f, 0.00126585f, 0.021060961f, 0.017925605f, - 0.003559874f, -0.005105248f, -0.005647917f, -0.004157918f, -0.002065664f, 0.00158747f, 0.003762585f, - 0.001867137f, -0.001090028f, -0.001433979f, -0.00022367f, 4.34308E-05f, -0.000247827f, 0.000157087f, - 0.000605823f, 0.000197317f, -0.000370511f, -0.000261202f, 9.96069E-05f, 9.85073E-05f, -5.28754E-05f, - -1.00912E-05f, 7.69943E-05f, 2.03162E-05f, -5.67967E-05f, -3.30637E-05f, 1.61958E-05f, 1.73041E-05f -}; - -// FIR version for new MT-32 and CM-32L/LAPC-I. -static const FloatSample ACCURATE_LPF_TAPS_CM32L[] = { - 0.003917452f, 0.030693861f, 0.116424199f, 0.275101674f, 0.43217361f, 0.431247894f, 0.183255659f, - -0.174955671f, -0.354240244f, -0.212401714f, 0.072259178f, 0.204655344f, 0.108336211f, -0.039099027f, - -0.075138174f, -0.026261906f, 0.00582663f, 0.003052193f, 0.00613657f, 0.017017951f, 0.008732535f, - -0.011027427f, -0.012933664f, 0.001158097f, 0.006765958f, 0.00046778f, -0.002191106f, 0.001561017f, - 0.001842871f, -0.001996876f, -0.002315836f, 0.000980965f, 0.001817454f, -0.000243272f, -0.000972848f, - 0.000149941f, 0.000498886f, -0.000204436f, -0.000347415f, 0.000142386f, 0.000249137f, -4.32946E-05f, - -0.000131231f, 3.88575E-07f, 4.48813E-05f, -1.31906E-06f, -1.03499E-05f, 7.71971E-06f, 2.86721E-06f -}; - -// According to the CM-64 PCB schematic, there is a difference in the values of the LPF entrance resistors for the reverb and non-reverb channels. -// This effectively results in non-unity LPF DC gain for the reverb channel of 0.68 while the LPF has unity DC gain for the LA32 output channels. -// In emulation, the reverb output gain is multiplied by this factor to compensate for the LPF gain difference. -static const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f; - -static const unsigned int OUTPUT_GAIN_FRACTION_BITS = 8; -static const float OUTPUT_GAIN_MULTIPLIER = float(1 << OUTPUT_GAIN_FRACTION_BITS); - -static const unsigned int COARSE_LPF_DELAY_LINE_LENGTH = 8; // Must be a power of 2 -static const unsigned int ACCURATE_LPF_DELAY_LINE_LENGTH = 16; // Must be a power of 2 -static const unsigned int ACCURATE_LPF_NUMBER_OF_PHASES = 3; // Upsampling factor -static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_REGULAR = 2; // Downsampling factor -static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED = 1; // No downsampling -static const Bit32u ACCURATE_LPF_DELTAS_REGULAR[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 1, 0 }, { 1, 2, 1 } }; -static const Bit32u ACCURATE_LPF_DELTAS_OVERSAMPLED[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 } }; - -template -class AbstractLowPassFilter { -public: - static AbstractLowPassFilter &createLowPassFilter(const AnalogOutputMode mode, const bool oldMT32AnalogLPF); - - virtual ~AbstractLowPassFilter() {} - virtual SampleEx process(const SampleEx sample) = 0; - - virtual bool hasNextSample() const { - return false; - } - - virtual unsigned int getOutputSampleRate() const { - return SAMPLE_RATE; - } - - virtual unsigned int estimateInSampleCount(const unsigned int outSamples) const { - return outSamples; - } - - virtual void addPositionIncrement(const unsigned int) {} -}; - -template -class NullLowPassFilter : public AbstractLowPassFilter { -public: - SampleEx process(const SampleEx sample) { - return sample; - } -}; - -template -class CoarseLowPassFilter : public AbstractLowPassFilter { -private: - const SampleEx * const lpfTaps; - SampleEx ringBuffer[COARSE_LPF_DELAY_LINE_LENGTH]; - unsigned int ringBufferPosition; - -public: - static inline const SampleEx *getLPFTaps(const bool oldMT32AnalogLPF); - static inline SampleEx normaliseSample(const SampleEx sample); - - explicit CoarseLowPassFilter(const bool oldMT32AnalogLPF) : - lpfTaps(getLPFTaps(oldMT32AnalogLPF)), - ringBufferPosition(0) - { - Synth::muteSampleBuffer(ringBuffer, COARSE_LPF_DELAY_LINE_LENGTH); - } - - SampleEx process(const SampleEx inSample) { - static const unsigned int DELAY_LINE_MASK = COARSE_LPF_DELAY_LINE_LENGTH - 1; - - SampleEx sample = lpfTaps[COARSE_LPF_DELAY_LINE_LENGTH] * ringBuffer[ringBufferPosition]; - ringBuffer[ringBufferPosition] = Synth::clipSampleEx(inSample); - - for (unsigned int i = 0; i < COARSE_LPF_DELAY_LINE_LENGTH; i++) { - sample += lpfTaps[i] * ringBuffer[(i + ringBufferPosition) & DELAY_LINE_MASK]; - } - - ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK; - - return normaliseSample(sample); - } -}; - -class AccurateLowPassFilter : public AbstractLowPassFilter, public AbstractLowPassFilter { -private: - const FloatSample * const LPF_TAPS; - const Bit32u (* const deltas)[ACCURATE_LPF_NUMBER_OF_PHASES]; - const unsigned int phaseIncrement; - const unsigned int outputSampleRate; - - FloatSample ringBuffer[ACCURATE_LPF_DELAY_LINE_LENGTH]; - unsigned int ringBufferPosition; - unsigned int phase; - -public: - AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample); - FloatSample process(const FloatSample sample); - IntSampleEx process(const IntSampleEx sample); - bool hasNextSample() const; - unsigned int getOutputSampleRate() const; - unsigned int estimateInSampleCount(const unsigned int outSamples) const; - void addPositionIncrement(const unsigned int positionIncrement); -}; - -static inline IntSampleEx normaliseSample(const IntSampleEx sample) { - return sample >> OUTPUT_GAIN_FRACTION_BITS; -} - -static inline FloatSample normaliseSample(const FloatSample sample) { - return sample; -} - -static inline float getActualReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode) { - return mt32ReverbCompatibilityMode ? reverbGain : reverbGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR; -} - -static inline IntSampleEx getIntOutputGain(const float outputGain) { - return IntSampleEx(((OUTPUT_GAIN_MULTIPLIER < outputGain) ? OUTPUT_GAIN_MULTIPLIER : outputGain) * OUTPUT_GAIN_MULTIPLIER); -} - -template -class AnalogImpl : public Analog { -public: - AbstractLowPassFilter &leftChannelLPF; - AbstractLowPassFilter &rightChannelLPF; - SampleEx synthGain; - SampleEx reverbGain; - - AnalogImpl(const AnalogOutputMode mode, const bool oldMT32AnalogLPF) : - leftChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, oldMT32AnalogLPF)), - rightChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, oldMT32AnalogLPF)), - synthGain(0), - reverbGain(0) - {} - - ~AnalogImpl() { - delete &leftChannelLPF; - delete &rightChannelLPF; - } - - unsigned int getOutputSampleRate() const { - return leftChannelLPF.getOutputSampleRate(); - } - - Bit32u getDACStreamsLength(const Bit32u outputLength) const { - return leftChannelLPF.estimateInSampleCount(outputLength); - } - - void setSynthOutputGain(const float synthGain); - void setReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode); - - bool process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength); - bool process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength); - - template - void produceOutput(Sample *outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, Bit32u outLength) { - if (outStream == NULL) { - leftChannelLPF.addPositionIncrement(outLength); - rightChannelLPF.addPositionIncrement(outLength); - return; - } - - while (0 < (outLength--)) { - SampleEx outSampleL; - SampleEx outSampleR; - - if (leftChannelLPF.hasNextSample()) { - outSampleL = leftChannelLPF.process(0); - outSampleR = rightChannelLPF.process(0); - } else { - SampleEx inSampleL = (SampleEx(*(nonReverbLeft++)) + SampleEx(*(reverbDryLeft++))) * synthGain + SampleEx(*(reverbWetLeft++)) * reverbGain; - SampleEx inSampleR = (SampleEx(*(nonReverbRight++)) + SampleEx(*(reverbDryRight++))) * synthGain + SampleEx(*(reverbWetRight++)) * reverbGain; - - outSampleL = leftChannelLPF.process(normaliseSample(inSampleL)); - outSampleR = rightChannelLPF.process(normaliseSample(inSampleR)); - } - - *(outStream++) = Synth::clipSampleEx(outSampleL); - *(outStream++) = Synth::clipSampleEx(outSampleR); - } - } -}; - -Analog *Analog::createAnalog(const AnalogOutputMode mode, const bool oldMT32AnalogLPF, const RendererType rendererType) { - switch (rendererType) - { - case RendererType_BIT16S: - return new AnalogImpl(mode, oldMT32AnalogLPF); - case RendererType_FLOAT: - return new AnalogImpl(mode, oldMT32AnalogLPF); - } - return NULL; -} - -template<> -bool AnalogImpl::process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength) { - produceOutput(outStream, nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, outLength); - return true; -} - -template<> -bool AnalogImpl::process(IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, Bit32u) { - return false; -} - -template<> -bool AnalogImpl::process(FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, Bit32u) { - return false; -} - -template<> -bool AnalogImpl::process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength) { - produceOutput(outStream, nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, outLength); - return true; -} - -template<> -void AnalogImpl::setSynthOutputGain(const float useSynthGain) { - synthGain = getIntOutputGain(useSynthGain); -} - -template<> -void AnalogImpl::setReverbOutputGain(const float useReverbGain, const bool mt32ReverbCompatibilityMode) { - reverbGain = getIntOutputGain(getActualReverbOutputGain(useReverbGain, mt32ReverbCompatibilityMode)); -} - -template<> -void AnalogImpl::setSynthOutputGain(const float useSynthGain) { - synthGain = useSynthGain; -} - -template<> -void AnalogImpl::setReverbOutputGain(const float useReverbGain, const bool mt32ReverbCompatibilityMode) { - reverbGain = getActualReverbOutputGain(useReverbGain, mt32ReverbCompatibilityMode); -} - -template<> -AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) { - switch (mode) { - case AnalogOutputMode_COARSE: - return *new CoarseLowPassFilter(oldMT32AnalogLPF); - case AnalogOutputMode_ACCURATE: - return *new AccurateLowPassFilter(oldMT32AnalogLPF, false); - case AnalogOutputMode_OVERSAMPLED: - return *new AccurateLowPassFilter(oldMT32AnalogLPF, true); - default: - return *new NullLowPassFilter; - } -} - -template<> -AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) { - switch (mode) { - case AnalogOutputMode_COARSE: - return *new CoarseLowPassFilter(oldMT32AnalogLPF); - case AnalogOutputMode_ACCURATE: - return *new AccurateLowPassFilter(oldMT32AnalogLPF, false); - case AnalogOutputMode_OVERSAMPLED: - return *new AccurateLowPassFilter(oldMT32AnalogLPF, true); - default: - return *new NullLowPassFilter; - } -} - -template<> -const IntSampleEx *CoarseLowPassFilter::getLPFTaps(const bool oldMT32AnalogLPF) { - return oldMT32AnalogLPF ? COARSE_LPF_INT_TAPS_MT32 : COARSE_LPF_INT_TAPS_CM32L; -} - -template<> -const FloatSample *CoarseLowPassFilter::getLPFTaps(const bool oldMT32AnalogLPF) { - return oldMT32AnalogLPF ? COARSE_LPF_FLOAT_TAPS_MT32 : COARSE_LPF_FLOAT_TAPS_CM32L; -} - -template<> -IntSampleEx CoarseLowPassFilter::normaliseSample(const IntSampleEx sample) { - return sample >> COARSE_LPF_INT_FRACTION_BITS; -} - -template<> -FloatSample CoarseLowPassFilter::normaliseSample(const FloatSample sample) { - return sample; -} - -AccurateLowPassFilter::AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample) : - LPF_TAPS(oldMT32AnalogLPF ? ACCURATE_LPF_TAPS_MT32 : ACCURATE_LPF_TAPS_CM32L), - deltas(oversample ? ACCURATE_LPF_DELTAS_OVERSAMPLED : ACCURATE_LPF_DELTAS_REGULAR), - phaseIncrement(oversample ? ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED : ACCURATE_LPF_PHASE_INCREMENT_REGULAR), - outputSampleRate(SAMPLE_RATE * ACCURATE_LPF_NUMBER_OF_PHASES / phaseIncrement), - ringBufferPosition(0), - phase(0) -{ - Synth::muteSampleBuffer(ringBuffer, ACCURATE_LPF_DELAY_LINE_LENGTH); -} - -FloatSample AccurateLowPassFilter::process(const FloatSample inSample) { - static const unsigned int DELAY_LINE_MASK = ACCURATE_LPF_DELAY_LINE_LENGTH - 1; - - FloatSample sample = (phase == 0) ? LPF_TAPS[ACCURATE_LPF_DELAY_LINE_LENGTH * ACCURATE_LPF_NUMBER_OF_PHASES] * ringBuffer[ringBufferPosition] : 0.0f; - if (!hasNextSample()) { - ringBuffer[ringBufferPosition] = inSample; - } - - for (unsigned int tapIx = phase, delaySampleIx = 0; delaySampleIx < ACCURATE_LPF_DELAY_LINE_LENGTH; delaySampleIx++, tapIx += ACCURATE_LPF_NUMBER_OF_PHASES) { - sample += LPF_TAPS[tapIx] * ringBuffer[(delaySampleIx + ringBufferPosition) & DELAY_LINE_MASK]; - } - - phase += phaseIncrement; - if (ACCURATE_LPF_NUMBER_OF_PHASES <= phase) { - phase -= ACCURATE_LPF_NUMBER_OF_PHASES; - ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK; - } - - return ACCURATE_LPF_NUMBER_OF_PHASES * sample; -} - -IntSampleEx AccurateLowPassFilter::process(const IntSampleEx sample) { - return IntSampleEx(process(FloatSample(sample))); -} - -bool AccurateLowPassFilter::hasNextSample() const { - return phaseIncrement <= phase; -} - -unsigned int AccurateLowPassFilter::getOutputSampleRate() const { - return outputSampleRate; -} - -unsigned int AccurateLowPassFilter::estimateInSampleCount(const unsigned int outSamples) const { - Bit32u cycleCount = outSamples / ACCURATE_LPF_NUMBER_OF_PHASES; - Bit32u remainder = outSamples - cycleCount * ACCURATE_LPF_NUMBER_OF_PHASES; - return cycleCount * phaseIncrement + deltas[remainder][phase]; -} - -void AccurateLowPassFilter::addPositionIncrement(const unsigned int positionIncrement) { - phase = (phase + positionIncrement * phaseIncrement) % ACCURATE_LPF_NUMBER_OF_PHASES; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Analog.h b/src - Cópia/sound/munt/Analog.h deleted file mode 100644 index 3b6dcabfa..000000000 --- a/src - Cópia/sound/munt/Analog.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_ANALOG_H -#define MT32EMU_ANALOG_H - -#include "globals.h" -#include "internals.h" -#include "Enumerations.h" -#include "Types.h" - -namespace MT32Emu { - -/* Analog class is dedicated to perform fair emulation of analogue circuitry of hardware units that is responsible - * for processing output signal after the DAC. It appears that the analogue circuit labeled "LPF" on the schematic - * also applies audible changes to the signal spectra. There is a significant boost of higher frequencies observed - * aside from quite poor attenuation of the mirror spectra above 16 kHz which is due to a relatively low filter order. - * - * As the final mixing of multiplexed output signal is performed after the DAC, this function is migrated here from Synth. - * Saying precisely, mixing is performed within the LPF as the entrance resistors are actually components of a LPF - * designed using the multiple feedback topology. Nevertheless, the schematic separates them. - */ -class Analog { -public: - static Analog *createAnalog(const AnalogOutputMode mode, const bool oldMT32AnalogLPF, const RendererType rendererType); - - virtual ~Analog() {} - virtual unsigned int getOutputSampleRate() const = 0; - virtual Bit32u getDACStreamsLength(const Bit32u outputLength) const = 0; - virtual void setSynthOutputGain(const float synthGain) = 0; - virtual void setReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode) = 0; - - virtual bool process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength) = 0; - virtual bool process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength) = 0; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_ANALOG_H diff --git a/src - Cópia/sound/munt/BReverbModel.cpp b/src - Cópia/sound/munt/BReverbModel.cpp deleted file mode 100644 index af559a92a..000000000 --- a/src - Cópia/sound/munt/BReverbModel.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "BReverbModel.h" -#include "Synth.h" - -// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that -// the reverb model implemented in the real devices consists of three series allpass filters preceded by a non-feedback comb (or a delay with a LPF) -// and followed by three parallel comb filters - -namespace MT32Emu { - -// Because LA-32 chip makes it's output available to process by the Boss chip with a significant delay, -// the Boss chip puts to the buffer the LA32 dry output when it is ready and performs processing of the _previously_ latched data. -// Of course, the right way would be to use a dedicated variable for this, but our reverb model is way higher level, -// so we can simply increase the input buffer size. -static const Bit32u PROCESS_DELAY = 1; - -static const Bit32u MODE_3_ADDITIONAL_DELAY = 1; -static const Bit32u MODE_3_FEEDBACK_DELAY = 1; - -// Avoid denormals degrading performance, using biased input -static const FloatSample BIAS = 1e-20f; - -struct BReverbSettings { - const Bit32u numberOfAllpasses; - const Bit32u * const allpassSizes; - const Bit32u numberOfCombs; - const Bit32u * const combSizes; - const Bit32u * const outLPositions; - const Bit32u * const outRPositions; - const Bit8u * const filterFactors; - const Bit8u * const feedbackFactors; - const Bit8u * const dryAmps; - const Bit8u * const wetLevels; - const Bit8u lpfAmp; -}; - -// Default reverb settings for "new" reverb model implemented in CM-32L / LAPC-I. -// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog). -static const BReverbSettings &getCM32L_LAPCSettings(const ReverbMode mode) { - static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78}; - static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be processed via a hacked comb. - static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632}; - static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960}; - static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145}; - static const Bit8u MODE_0_COMB_FACTOR[] = {0xA0, 0x60, 0x60, 0x60}; - static const Bit8u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; - static const Bit8u MODE_0_DRY_AMP[] = {0xA0, 0xA0, 0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xD0}; - static const Bit8u MODE_0_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; - static const Bit8u MODE_0_LPF_AMP = 0x60; - - static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176}; - static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as for mode 0 above - static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519}; - static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518}; - static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274}; - static const Bit8u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60}; - static const Bit8u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; - static const Bit8u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0}; - static const Bit8u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; - static const Bit8u MODE_1_LPF_AMP = 0x60; - - static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157}; - static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as for mode 0 above - static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539}; - static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769}; - static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1}; - static const Bit8u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20}; - static const Bit8u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, - 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, - 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0}; - static const Bit8u MODE_2_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xC0, 0xE0}; - static const Bit8u MODE_2_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; - static const Bit8u MODE_2_LPF_AMP = 0x80; - - static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0; - static const Bit32u MODE_3_NUMBER_OF_COMBS = 1; - static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY}; - static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000}; - static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000}; - static const Bit8u MODE_3_COMB_FACTOR[] = {0x68}; - static const Bit8u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60}; - static const Bit8u MODE_3_DRY_AMP[] = {0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, - 0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50}; - static const Bit8u MODE_3_WET_AMP[] = {0x18, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8}; - - static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP}; - static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP}; - static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP}; - static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0}; - - static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS}; - - return *REVERB_SETTINGS[mode]; -} - -// Default reverb settings for "old" reverb model implemented in MT-32. -// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog). -static const BReverbSettings &getMT32Settings(const ReverbMode mode) { - static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78}; - static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation - static const Bit32u MODE_0_COMBS[] = {575 + PROCESS_DELAY, 2040, 2752, 3629}; - static const Bit32u MODE_0_OUTL[] = {2040, 687, 1814}; - static const Bit32u MODE_0_OUTR[] = {1019, 2072, 1}; - static const Bit8u MODE_0_COMB_FACTOR[] = {0xB0, 0x60, 0x60, 0x60}; - static const Bit8u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; - static const Bit8u MODE_0_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; - static const Bit8u MODE_0_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; - static const Bit8u MODE_0_LPF_AMP = 0x80; - - static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176}; - static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation - static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519}; - static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518}; - static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274}; - static const Bit8u MODE_1_COMB_FACTOR[] = {0x90, 0x60, 0x60, 0x60}; - static const Bit8u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; - static const Bit8u MODE_1_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; - static const Bit8u MODE_1_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; - static const Bit8u MODE_1_LPF_AMP = 0x80; - - static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3; - static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157}; - static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation - static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539}; - static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769}; - static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1}; - static const Bit8u MODE_2_COMB_FACTOR[] = {0, 0x60, 0x60, 0x60}; - static const Bit8u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, - 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; - static const Bit8u MODE_2_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; - static const Bit8u MODE_2_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; - static const Bit8u MODE_2_LPF_AMP = 0x80; - - static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0; - static const Bit32u MODE_3_NUMBER_OF_COMBS = 1; - static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY}; - static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000}; - static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000}; - static const Bit8u MODE_3_COMB_FACTOR[] = {0x68}; - static const Bit8u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60}; - static const Bit8u MODE_3_DRY_AMP[] = {0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x10, 0x20, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10}; - static const Bit8u MODE_3_WET_AMP[] = {0x08, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8}; - - static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP}; - static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP}; - static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP}; - static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0}; - - static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS}; - - return *REVERB_SETTINGS[mode]; -} - -static inline IntSample weirdMul(IntSample sample, Bit8u addMask, Bit8u carryMask) { -#if MT32EMU_BOSS_REVERB_PRECISE_MODE - // This algorithm tries to emulate exactly Boss multiplication operation (at least this is what we see on reverb RAM data lines). - Bit8u mask = 0x80; - IntSampleEx res = 0; - for (int i = 0; i < 8; i++) { - IntSampleEx carry = (sample < 0) && (mask & carryMask) > 0 ? sample & 1 : 0; - sample >>= 1; - res += (mask & addMask) > 0 ? sample + carry : 0; - mask >>= 1; - } - return IntSample(res); -#else - (void)carryMask; - return IntSample((IntSampleEx(sample) * addMask) >> 8); -#endif -} - -static inline FloatSample weirdMul(FloatSample sample, Bit8u addMask, Bit8u carryMask) { - (void)carryMask; - return sample * addMask / 256.0f; -} - -static inline IntSample halveSample(IntSample sample) { - return sample >> 1; -} - -static inline FloatSample halveSample(FloatSample sample) { - return 0.5f * sample; -} - -static inline IntSample quarterSample(IntSample sample) { -#if MT32EMU_BOSS_REVERB_PRECISE_MODE - return (sample >> 1) / 2; -#else - return sample >> 2; -#endif -} - -static inline FloatSample quarterSample(FloatSample sample) { - return 0.25f * sample; -} - -static inline IntSample addDCBias(IntSample sample) { - return sample; -} - -static inline FloatSample addDCBias(FloatSample sample) { - return sample + BIAS; -} - -static inline IntSample addAllpassNoise(IntSample sample) { -#if MT32EMU_BOSS_REVERB_PRECISE_MODE - // This introduces reverb noise which actually makes output from the real Boss chip nondeterministic - return sample - 1; -#else - return sample; -#endif -} - -static inline FloatSample addAllpassNoise(FloatSample sample) { - return sample; -} - -/* NOTE: - * Thanks to Mok for discovering, the adder in BOSS reverb chip is found to perform addition with saturation to avoid integer overflow. - * Analysing of the algorithm suggests that the overflow is most probable when the combs output is added below. - * So, despite this isn't actually accurate, we only add the check here for performance reasons. - */ -static inline IntSample mixCombs(IntSample out1, IntSample out2, IntSample out3) { -#if MT32EMU_BOSS_REVERB_PRECISE_MODE - return Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(IntSampleEx(out1) + (IntSampleEx(out1) >> 1)) + IntSampleEx(out2)) + (IntSampleEx(out2) >> 1)) + IntSampleEx(out3)); -#else - return Synth::clipSampleEx(IntSampleEx(out1) + (IntSampleEx(out1) >> 1) + IntSampleEx(out2) + (IntSampleEx(out2) >> 1) + IntSampleEx(out3)); -#endif -} - -static inline FloatSample mixCombs(FloatSample out1, FloatSample out2, FloatSample out3) { - return 1.5f * (out1 + out2) + out3; -} - -template -class RingBuffer { - static inline Sample sampleValueThreshold(); - -protected: - Sample *buffer; - const Bit32u size; - Bit32u index; - -public: - RingBuffer(const Bit32u newsize) : size(newsize), index(0) { - buffer = new Sample[size]; - } - - virtual ~RingBuffer() { - delete[] buffer; - buffer = NULL; - } - - Sample next() { - if (++index >= size) { - index = 0; - } - return buffer[index]; - } - - bool isEmpty() const { - if (buffer == NULL) return true; - - Sample *buf = buffer; - for (Bit32u i = 0; i < size; i++) { - if (*buf < -sampleValueThreshold() || *buf > sampleValueThreshold()) return false; - buf++; - } - return true; - } - - void mute() { - Synth::muteSampleBuffer(buffer, size); - } -}; - -template<> -IntSample RingBuffer::sampleValueThreshold() { - return 8; -} - -template<> -FloatSample RingBuffer::sampleValueThreshold() { - return 0.001f; -} - -template -class AllpassFilter : public RingBuffer { -public: - AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {} - - // This model corresponds to the allpass filter implementation of the real CM-32L device - // found from sample analysis - Sample process(const Sample in) { - const Sample bufferOut = this->next(); - - // store input - feedback / 2 - this->buffer[this->index] = in - halveSample(bufferOut); - - // return buffer output + feedforward / 2 - return bufferOut + halveSample(this->buffer[this->index]); - } -}; - -template -class CombFilter : public RingBuffer { -protected: - const Bit8u filterFactor; - Bit8u feedbackFactor; - -public: - CombFilter(const Bit32u useSize, const Bit8u useFilterFactor) : RingBuffer(useSize), filterFactor(useFilterFactor) {} - - // This model corresponds to the comb filter implementation of the real CM-32L device - void process(const Sample in) { - - // the previously stored value - const Sample last = this->buffer[this->index]; - - // prepare input + feedback - const Sample filterIn = in + weirdMul(this->next(), feedbackFactor, 0xF0); - - // store input + feedback processed by a low-pass filter - this->buffer[this->index] = weirdMul(last, filterFactor, 0xC0) - filterIn; - } - - Sample getOutputAt(const Bit32u outIndex) const { - return this->buffer[(this->size + this->index - outIndex) % this->size]; - } - - void setFeedbackFactor(const Bit8u useFeedbackFactor) { - feedbackFactor = useFeedbackFactor; - } -}; - -template -class DelayWithLowPassFilter : public CombFilter { - Bit8u amp; - -public: - DelayWithLowPassFilter(const Bit32u useSize, const Bit8u useFilterFactor, const Bit8u useAmp) - : CombFilter(useSize, useFilterFactor), amp(useAmp) {} - - void process(const Sample in) { - // the previously stored value - const Sample last = this->buffer[this->index]; - - // move to the next index - this->next(); - - // low-pass filter process - Sample lpfOut = weirdMul(last, this->filterFactor, 0xFF) + in; - - // store lpfOut multiplied by LPF amp factor - this->buffer[this->index] = weirdMul(lpfOut, amp, 0xFF); - } -}; - -template -class TapDelayCombFilter : public CombFilter { - Bit32u outL; - Bit32u outR; - -public: - TapDelayCombFilter(const Bit32u useSize, const Bit8u useFilterFactor) : CombFilter(useSize, useFilterFactor) {} - - void process(const Sample in) { - // the previously stored value - const Sample last = this->buffer[this->index]; - - // move to the next index - this->next(); - - // prepare input + feedback - // Actually, the size of the filter varies with the TIME parameter, the feedback sample is taken from the position just below the right output - const Sample filterIn = in + weirdMul(this->getOutputAt(outR + MODE_3_FEEDBACK_DELAY), this->feedbackFactor, 0xF0); - - // store input + feedback processed by a low-pass filter - this->buffer[this->index] = weirdMul(last, this->filterFactor, 0xF0) - filterIn; - } - - Sample getLeftOutput() const { - return this->getOutputAt(outL + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY); - } - - Sample getRightOutput() const { - return this->getOutputAt(outR + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY); - } - - void setOutputPositions(const Bit32u useOutL, const Bit32u useOutR) { - outL = useOutL; - outR = useOutR; - } -}; - -template -class BReverbModelImpl : public BReverbModel { -public: - AllpassFilter **allpasses; - CombFilter **combs; - - const BReverbSettings ¤tSettings; - const bool tapDelayMode; - Bit8u dryAmp; - Bit8u wetLevel; - - BReverbModelImpl(const ReverbMode mode, const bool mt32CompatibleModel) : - allpasses(NULL), combs(NULL), - currentSettings(mt32CompatibleModel ? getMT32Settings(mode) : getCM32L_LAPCSettings(mode)), - tapDelayMode(mode == REVERB_MODE_TAP_DELAY) - {} - - ~BReverbModelImpl() { - close(); - } - - bool isOpen() const { - return combs != NULL; - } - - void open() { - if (isOpen()) return; - if (currentSettings.numberOfAllpasses > 0) { - allpasses = new AllpassFilter*[currentSettings.numberOfAllpasses]; - for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { - allpasses[i] = new AllpassFilter(currentSettings.allpassSizes[i]); - } - } - combs = new CombFilter*[currentSettings.numberOfCombs]; - if (tapDelayMode) { - *combs = new TapDelayCombFilter(*currentSettings.combSizes, *currentSettings.filterFactors); - } else { - combs[0] = new DelayWithLowPassFilter(currentSettings.combSizes[0], currentSettings.filterFactors[0], currentSettings.lpfAmp); - for (Bit32u i = 1; i < currentSettings.numberOfCombs; i++) { - combs[i] = new CombFilter(currentSettings.combSizes[i], currentSettings.filterFactors[i]); - } - } - mute(); - } - - void close() { - if (allpasses != NULL) { - for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { - if (allpasses[i] != NULL) { - delete allpasses[i]; - allpasses[i] = NULL; - } - } - delete[] allpasses; - allpasses = NULL; - } - if (combs != NULL) { - for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { - if (combs[i] != NULL) { - delete combs[i]; - combs[i] = NULL; - } - } - delete[] combs; - combs = NULL; - } - } - - void mute() { - if (allpasses != NULL) { - for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { - allpasses[i]->mute(); - } - } - if (combs != NULL) { - for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { - combs[i]->mute(); - } - } - } - - void setParameters(Bit8u time, Bit8u level) { - if (!isOpen()) return; - level &= 7; - time &= 7; - if (tapDelayMode) { - TapDelayCombFilter *comb = static_cast *> (*combs); - comb->setOutputPositions(currentSettings.outLPositions[time], currentSettings.outRPositions[time & 7]); - comb->setFeedbackFactor(currentSettings.feedbackFactors[((level < 3) || (time < 6)) ? 0 : 1]); - } else { - for (Bit32u i = 1; i < currentSettings.numberOfCombs; i++) { - combs[i]->setFeedbackFactor(currentSettings.feedbackFactors[(i << 3) + time]); - } - } - if (time == 0 && level == 0) { - dryAmp = wetLevel = 0; - } else { - if (tapDelayMode && ((time == 0) || (time == 1 && level == 1))) { - // Looks like MT-32 implementation has some minor quirks in this mode: - // for odd level values, the output level changes sometimes depending on the time value which doesn't seem right. - dryAmp = currentSettings.dryAmps[level + 8]; - } else { - dryAmp = currentSettings.dryAmps[level]; - } - wetLevel = currentSettings.wetLevels[level]; - } - } - - bool isActive() const { - if (!isOpen()) return false; - for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { - if (!allpasses[i]->isEmpty()) return true; - } - for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { - if (!combs[i]->isEmpty()) return true; - } - return false; - } - - bool isMT32Compatible(const ReverbMode mode) const { - return ¤tSettings == &getMT32Settings(mode); - } - - template - void produceOutput(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, Bit32u numSamples) { - if (!isOpen()) { - Synth::muteSampleBuffer(outLeft, numSamples); - Synth::muteSampleBuffer(outRight, numSamples); - return; - } - - while ((numSamples--) > 0) { - Sample dry; - - if (tapDelayMode) { - dry = halveSample(*(inLeft++)) + halveSample(*(inRight++)); - } else { - dry = quarterSample(*(inLeft++)) + quarterSample(*(inRight++)); - } - - // Looks like dryAmp doesn't change in MT-32 but it does in CM-32L / LAPC-I - dry = weirdMul(addDCBias(dry), dryAmp, 0xFF); - - if (tapDelayMode) { - TapDelayCombFilter *comb = static_cast *>(*combs); - comb->process(dry); - if (outLeft != NULL) { - *(outLeft++) = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF); - } - if (outRight != NULL) { - *(outRight++) = weirdMul(comb->getRightOutput(), wetLevel, 0xFF); - } - } else { - DelayWithLowPassFilter * const entranceDelay = static_cast *>(combs[0]); - // If the output position is equal to the comb size, get it now in order not to loose it - Sample link = entranceDelay->getOutputAt(currentSettings.combSizes[0] - 1); - - // Entrance LPF. Note, comb.process() differs a bit here. - entranceDelay->process(dry); - - link = allpasses[0]->process(addAllpassNoise(link)); - link = allpasses[1]->process(link); - link = allpasses[2]->process(link); - - // If the output position is equal to the comb size, get it now in order not to loose it - Sample outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1); - - combs[1]->process(link); - combs[2]->process(link); - combs[3]->process(link); - - if (outLeft != NULL) { - Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]); - Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]); - Sample outSample = mixCombs(outL1, outL2, outL3); - *(outLeft++) = weirdMul(outSample, wetLevel, 0xFF); - } - if (outRight != NULL) { - Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]); - Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]); - Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]); - Sample outSample = mixCombs(outR1, outR2, outR3); - *(outRight++) = weirdMul(outSample, wetLevel, 0xFF); - } - } // if (tapDelayMode) - } // while ((numSamples--) > 0) - } // produceOutput - - bool process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples); - bool process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples); -}; - -BReverbModel *BReverbModel::createBReverbModel(const ReverbMode mode, const bool mt32CompatibleModel, const RendererType rendererType) { - switch (rendererType) - { - case RendererType_BIT16S: - return new BReverbModelImpl(mode, mt32CompatibleModel); - case RendererType_FLOAT: - return new BReverbModelImpl(mode, mt32CompatibleModel); - } - return NULL; -} - -template <> -bool BReverbModelImpl::process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples) { - produceOutput(inLeft, inRight, outLeft, outRight, numSamples); - return true; -} - -template <> -bool BReverbModelImpl::process(const FloatSample *, const FloatSample *, FloatSample *, FloatSample *, Bit32u) { - return false; -} - -template <> -bool BReverbModelImpl::process(const IntSample *, const IntSample *, IntSample *, IntSample *, Bit32u) { - return false; -} - -template <> -bool BReverbModelImpl::process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples) { - produceOutput(inLeft, inRight, outLeft, outRight, numSamples); - return true; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/BReverbModel.h b/src - Cópia/sound/munt/BReverbModel.h deleted file mode 100644 index 5b1d41198..000000000 --- a/src - Cópia/sound/munt/BReverbModel.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_B_REVERB_MODEL_H -#define MT32EMU_B_REVERB_MODEL_H - -#include "globals.h" -#include "internals.h" -#include "Enumerations.h" -#include "Types.h" - -namespace MT32Emu { - -class BReverbModel { -public: - static BReverbModel *createBReverbModel(const ReverbMode mode, const bool mt32CompatibleModel, const RendererType rendererType); - - virtual ~BReverbModel() {} - virtual bool isOpen() const = 0; - // After construction or a close(), open() must be called at least once before any other call (with the exception of close()). - virtual void open() = 0; - // May be called multiple times without an open() in between. - virtual void close() = 0; - virtual void mute() = 0; - virtual void setParameters(Bit8u time, Bit8u level) = 0; - virtual bool isActive() const = 0; - virtual bool isMT32Compatible(const ReverbMode mode) const = 0; - virtual bool process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples) = 0; - virtual bool process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples) = 0; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_B_REVERB_MODEL_H diff --git a/src - Cópia/sound/munt/Enumerations.h b/src - Cópia/sound/munt/Enumerations.h deleted file mode 100644 index bb580ca5b..000000000 --- a/src - Cópia/sound/munt/Enumerations.h +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/* Using two guards since this file may be included twice with different MT32EMU_C_ENUMERATIONS define. */ - -#if (!defined MT32EMU_CPP_ENUMERATIONS_H && !defined MT32EMU_C_ENUMERATIONS) || (!defined MT32EMU_C_ENUMERATIONS_H && defined MT32EMU_C_ENUMERATIONS) - -#ifdef MT32EMU_C_ENUMERATIONS - -#define MT32EMU_C_ENUMERATIONS_H - -#define MT32EMU_DAC_INPUT_MODE_NAME mt32emu_dac_input_mode -#define MT32EMU_DAC_INPUT_MODE(ident) MT32EMU_DAC_##ident - -#define MT32EMU_MIDI_DELAY_MODE_NAME mt32emu_midi_delay_mode -#define MT32EMU_MIDI_DELAY_MODE(ident) MT32EMU_MDM_##ident - -#define MT32EMU_ANALOG_OUTPUT_MODE_NAME mt32emu_analog_output_mode -#define MT32EMU_ANALOG_OUTPUT_MODE(ident) MT32EMU_AOM_##ident - -#define MT32EMU_PARTIAL_STATE_NAME mt32emu_partial_state -#define MT32EMU_PARTIAL_STATE(ident) MT32EMU_PS_##ident - -#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME mt32emu_samplerate_conversion_quality -#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY(ident) MT32EMU_SRCQ_##ident - -#define MT32EMU_RENDERER_TYPE_NAME mt32emu_renderer_type -#define MT32EMU_RENDERER_TYPE(ident) MT32EMU_RT_##ident - -#else /* #ifdef MT32EMU_C_ENUMERATIONS */ - -#define MT32EMU_CPP_ENUMERATIONS_H - -#define MT32EMU_DAC_INPUT_MODE_NAME DACInputMode -#define MT32EMU_DAC_INPUT_MODE(ident) DACInputMode_##ident - -#define MT32EMU_MIDI_DELAY_MODE_NAME MIDIDelayMode -#define MT32EMU_MIDI_DELAY_MODE(ident) MIDIDelayMode_##ident - -#define MT32EMU_ANALOG_OUTPUT_MODE_NAME AnalogOutputMode -#define MT32EMU_ANALOG_OUTPUT_MODE(ident) AnalogOutputMode_##ident - -#define MT32EMU_PARTIAL_STATE_NAME PartialState -#define MT32EMU_PARTIAL_STATE(ident) PartialState_##ident - -#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME SamplerateConversionQuality -#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY(ident) SamplerateConversionQuality_##ident - -#define MT32EMU_RENDERER_TYPE_NAME RendererType -#define MT32EMU_RENDERER_TYPE(ident) RendererType_##ident - -namespace MT32Emu { - -#endif /* #ifdef MT32EMU_C_ENUMERATIONS */ - -/** - * Methods for emulating the connection between the LA32 and the DAC, which involves - * some hacks in the real devices for doubling the volume. - * See also http://en.wikipedia.org/wiki/Roland_MT-32#Digital_overflow - */ -enum MT32EMU_DAC_INPUT_MODE_NAME { - /** - * Produces samples at double the volume, without tricks. - * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range) - * Higher quality than the real devices - */ - MT32EMU_DAC_INPUT_MODE(NICE), - - /** - * Produces samples that exactly match the bits output from the emulated LA32. - * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range) - * Much less likely to overdrive than any other mode. - * Half the volume of any of the other modes. - * Perfect for developers while debugging :) - */ - MT32EMU_DAC_INPUT_MODE(PURE), - - /** - * Re-orders the LA32 output bits as in early generation MT-32s (according to Wikipedia). - * Bit order at DAC (where each number represents the original LA32 output bit number, and XX means the bit is always low): - * 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 XX - */ - MT32EMU_DAC_INPUT_MODE(GENERATION1), - - /** - * Re-orders the LA32 output bits as in later generations (personally confirmed on my CM-32L - KG). - * Bit order at DAC (where each number represents the original LA32 output bit number): - * 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 14 - */ - MT32EMU_DAC_INPUT_MODE(GENERATION2) -}; - -/** Methods for emulating the effective delay of incoming MIDI messages introduced by a MIDI interface. */ -enum MT32EMU_MIDI_DELAY_MODE_NAME { - /** Process incoming MIDI events immediately. */ - MT32EMU_MIDI_DELAY_MODE(IMMEDIATE), - - /** - * Delay incoming short MIDI messages as if they where transferred via a MIDI cable to a real hardware unit and immediate sysex processing. - * This ensures more accurate timing of simultaneous NoteOn messages. - */ - MT32EMU_MIDI_DELAY_MODE(DELAY_SHORT_MESSAGES_ONLY), - - /** Delay all incoming MIDI events as if they where transferred via a MIDI cable to a real hardware unit.*/ - MT32EMU_MIDI_DELAY_MODE(DELAY_ALL) -}; - -/** Methods for emulating the effects of analogue circuits of real hardware units on the output signal. */ -enum MT32EMU_ANALOG_OUTPUT_MODE_NAME { - /** Only digital path is emulated. The output samples correspond to the digital signal at the DAC entrance. */ - MT32EMU_ANALOG_OUTPUT_MODE(DIGITAL_ONLY), - /** Coarse emulation of LPF circuit. High frequencies are boosted, sample rate remains unchanged. */ - MT32EMU_ANALOG_OUTPUT_MODE(COARSE), - /** - * Finer emulation of LPF circuit. Output signal is upsampled to 48 kHz to allow emulation of audible mirror spectra above 16 kHz, - * which is passed through the LPF circuit without significant attenuation. - */ - MT32EMU_ANALOG_OUTPUT_MODE(ACCURATE), - /** - * Same as AnalogOutputMode_ACCURATE mode but the output signal is 2x oversampled, i.e. the output sample rate is 96 kHz. - * This makes subsequent resampling easier. Besides, due to nonlinear passband of the LPF emulated, it takes fewer number of MACs - * compared to a regular LPF FIR implementations. - */ - MT32EMU_ANALOG_OUTPUT_MODE(OVERSAMPLED) -}; - -enum MT32EMU_PARTIAL_STATE_NAME { - MT32EMU_PARTIAL_STATE(INACTIVE), - MT32EMU_PARTIAL_STATE(ATTACK), - MT32EMU_PARTIAL_STATE(SUSTAIN), - MT32EMU_PARTIAL_STATE(RELEASE) -}; - -enum MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME { - /** Use this only when the speed is more important than the audio quality. */ - MT32EMU_SAMPLERATE_CONVERSION_QUALITY(FASTEST), - MT32EMU_SAMPLERATE_CONVERSION_QUALITY(FAST), - MT32EMU_SAMPLERATE_CONVERSION_QUALITY(GOOD), - MT32EMU_SAMPLERATE_CONVERSION_QUALITY(BEST) -}; - -enum MT32EMU_RENDERER_TYPE_NAME { - /** Use 16-bit signed samples in the renderer and the accurate wave generator model based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed. */ - MT32EMU_RENDERER_TYPE(BIT16S), - /** Use float samples in the renderer and simplified wave generator model. Maximum output quality and minimum noise. */ - MT32EMU_RENDERER_TYPE(FLOAT) -}; - -#ifndef MT32EMU_C_ENUMERATIONS - -} // namespace MT32Emu - -#endif - -#undef MT32EMU_DAC_INPUT_MODE_NAME -#undef MT32EMU_DAC_INPUT_MODE - -#undef MT32EMU_MIDI_DELAY_MODE_NAME -#undef MT32EMU_MIDI_DELAY_MODE - -#undef MT32EMU_ANALOG_OUTPUT_MODE_NAME -#undef MT32EMU_ANALOG_OUTPUT_MODE - -#undef MT32EMU_PARTIAL_STATE_NAME -#undef MT32EMU_PARTIAL_STATE - -#undef MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME -#undef MT32EMU_SAMPLERATE_CONVERSION_QUALITY - -#undef MT32EMU_RENDERER_TYPE_NAME -#undef MT32EMU_RENDERER_TYPE - -#endif /* #if (!defined MT32EMU_CPP_ENUMERATIONS_H && !defined MT32EMU_C_ENUMERATIONS) || (!defined MT32EMU_C_ENUMERATIONS_H && defined MT32EMU_C_ENUMERATIONS) */ diff --git a/src - Cópia/sound/munt/File.cpp b/src - Cópia/sound/munt/File.cpp deleted file mode 100644 index a5967b4f3..000000000 --- a/src - Cópia/sound/munt/File.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "File.h" -#include "sha1/sha1.h" - -namespace MT32Emu { - -AbstractFile::AbstractFile() : sha1DigestCalculated(false) { - sha1Digest[0] = 0; - - reserved = NULL; -} - -AbstractFile::AbstractFile(const SHA1Digest &useSHA1Digest) : sha1DigestCalculated(true) { - memcpy(sha1Digest, useSHA1Digest, sizeof(SHA1Digest) - 1); - sha1Digest[sizeof(SHA1Digest) - 1] = 0; // Ensure terminator char. - - reserved = NULL; -} - -const File::SHA1Digest &AbstractFile::getSHA1() { - if (sha1DigestCalculated) { - return sha1Digest; - } - sha1DigestCalculated = true; - - size_t size = getSize(); - if (size == 0) { - return sha1Digest; - } - - const Bit8u *data = getData(); - if (data == NULL) { - return sha1Digest; - } - - unsigned char fileDigest[20]; - - sha1::calc(data, int(size), fileDigest); - sha1::toHexString(fileDigest, sha1Digest); - return sha1Digest; -} - -ArrayFile::ArrayFile(const Bit8u *useData, size_t useSize) : data(useData), size(useSize) -{} - -ArrayFile::ArrayFile(const Bit8u *useData, size_t useSize, const SHA1Digest &useSHA1Digest) : AbstractFile(useSHA1Digest), data(useData), size(useSize) -{} - -size_t ArrayFile::getSize() { - return size; -} - -const Bit8u *ArrayFile::getData() { - return data; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/File.h b/src - Cópia/sound/munt/File.h deleted file mode 100644 index 91a0a7fe6..000000000 --- a/src - Cópia/sound/munt/File.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_FILE_H -#define MT32EMU_FILE_H - -#include - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -class MT32EMU_EXPORT File { -public: - // Includes terminator char. - typedef char SHA1Digest[41]; - - virtual ~File() {} - virtual size_t getSize() = 0; - virtual const Bit8u *getData() = 0; - virtual const SHA1Digest &getSHA1() = 0; - - virtual void close() = 0; -}; - -class MT32EMU_EXPORT AbstractFile : public File { -public: - const SHA1Digest &getSHA1(); - -protected: - AbstractFile(); - AbstractFile(const SHA1Digest &sha1Digest); - -private: - bool sha1DigestCalculated; - SHA1Digest sha1Digest; - - // Binary compatibility helper. - void *reserved; -}; - -class MT32EMU_EXPORT ArrayFile : public AbstractFile { -public: - ArrayFile(const Bit8u *data, size_t size); - ArrayFile(const Bit8u *data, size_t size, const SHA1Digest &sha1Digest); - - size_t getSize(); - const Bit8u *getData(); - void close() {} - -private: - const Bit8u *data; - size_t size; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_FILE_H diff --git a/src - Cópia/sound/munt/FileStream.cpp b/src - Cópia/sound/munt/FileStream.cpp deleted file mode 100644 index 48ecc84b1..000000000 --- a/src - Cópia/sound/munt/FileStream.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "internals.h" - -#include "FileStream.h" - -namespace MT32Emu { - -using std::ios_base; - -FileStream::FileStream() : ifsp(*new std::ifstream), data(NULL), size(0) -{} - -FileStream::~FileStream() { - // destructor closes ifsp - delete &ifsp; - delete[] data; -} - -size_t FileStream::getSize() { - if (size != 0) { - return size; - } - if (!ifsp.is_open()) { - return 0; - } - ifsp.seekg(0, ios_base::end); - size = size_t(ifsp.tellg()); - return size; -} - -const Bit8u *FileStream::getData() { - if (data != NULL) { - return data; - } - if (!ifsp.is_open()) { - return NULL; - } - if (getSize() == 0) { - return NULL; - } - Bit8u *fileData = new Bit8u[size]; - if (fileData == NULL) { - return NULL; - } - ifsp.seekg(0); - ifsp.read(reinterpret_cast(fileData), std::streamsize(size)); - if (size_t(ifsp.tellg()) != size) { - delete[] fileData; - return NULL; - } - data = fileData; - close(); - return data; -} - -bool FileStream::open(const char *filename) { - ifsp.clear(); - ifsp.open(filename, ios_base::in | ios_base::binary); - return !ifsp.fail(); -} - -void FileStream::close() { - ifsp.close(); - ifsp.clear(); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/FileStream.h b/src - Cópia/sound/munt/FileStream.h deleted file mode 100644 index ea5de6952..000000000 --- a/src - Cópia/sound/munt/FileStream.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_FILE_STREAM_H -#define MT32EMU_FILE_STREAM_H - -#include - -#include "globals.h" -#include "Types.h" -#include "File.h" - -namespace MT32Emu { - -class FileStream : public AbstractFile { -public: - MT32EMU_EXPORT FileStream(); - MT32EMU_EXPORT ~FileStream(); - MT32EMU_EXPORT size_t getSize(); - MT32EMU_EXPORT const Bit8u *getData(); - MT32EMU_EXPORT bool open(const char *filename); - MT32EMU_EXPORT void close(); - -private: - std::ifstream &ifsp; - const Bit8u *data; - size_t size; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_FILE_STREAM_H diff --git a/src - Cópia/sound/munt/LA32FloatWaveGenerator.cpp b/src - Cópia/sound/munt/LA32FloatWaveGenerator.cpp deleted file mode 100644 index 6ff4aa37b..000000000 --- a/src - Cópia/sound/munt/LA32FloatWaveGenerator.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "LA32FloatWaveGenerator.h" -#include "mmath.h" -#include "Tables.h" - -namespace MT32Emu { - -static const float MIDDLE_CUTOFF_VALUE = 128.0f; -static const float RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE = 144.0f; -static const float MAX_CUTOFF_VALUE = 240.0f; - -float LA32FloatWaveGenerator::getPCMSample(unsigned int position) { - if (position >= pcmWaveLength) { - if (!pcmWaveLooped) { - return 0; - } - position = position % pcmWaveLength; - } - Bit16s pcmSample = pcmWaveAddress[position]; - float sampleValue = EXP2F(((pcmSample & 32767) - 32787.0f) / 2048.0f); - return ((pcmSample & 32768) == 0) ? sampleValue : -sampleValue; -} - -void LA32FloatWaveGenerator::initSynth(const bool useSawtoothWaveform, const Bit8u usePulseWidth, const Bit8u useResonance) { - sawtoothWaveform = useSawtoothWaveform; - pulseWidth = usePulseWidth; - resonance = useResonance; - - wavePos = 0.0f; - lastFreq = 0.0f; - - pcmWaveAddress = NULL; - active = true; -} - -void LA32FloatWaveGenerator::initPCM(const Bit16s * const usePCMWaveAddress, const Bit32u usePCMWaveLength, const bool usePCMWaveLooped, const bool usePCMWaveInterpolated) { - pcmWaveAddress = usePCMWaveAddress; - pcmWaveLength = usePCMWaveLength; - pcmWaveLooped = usePCMWaveLooped; - pcmWaveInterpolated = usePCMWaveInterpolated; - - pcmPosition = 0.0f; - active = true; -} - -// ampVal - Logarithmic amp of the wave generator -// pitch - Logarithmic frequency of the resulting wave -// cutoffRampVal - Composed of the base cutoff in range [78..178] left-shifted by 18 bits and the TVF modifier -float LA32FloatWaveGenerator::generateNextSample(const Bit32u ampVal, const Bit16u pitch, const Bit32u cutoffRampVal) { - if (!active) { - return 0.0f; - } - - float sample = 0.0f; - - // SEMI-CONFIRMED: From sample analysis: - // (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc. - // This gives results within +/- 2 at the output (before any DAC bitshifting) - // when sustaining at levels 156 - 255 with no modifiers. - // (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255. - // This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces - // positive amps, so negative still needs to be explored, as well as lower levels. - // - // Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing. - - float amp = EXP2F(ampVal / -1024.0f / 4096.0f); - float freq = EXP2F(pitch / 4096.0f - 16.0f) * SAMPLE_RATE; - - if (isPCMWave()) { - // Render PCM waveform - int len = pcmWaveLength; - int intPCMPosition = int(pcmPosition); - if (intPCMPosition >= len && !pcmWaveLooped) { - // We're now past the end of a non-looping PCM waveform so it's time to die. - deactivate(); - return 0.0f; - } - float positionDelta = freq * 2048.0f / SAMPLE_RATE; - - // Linear interpolation - float firstSample = getPCMSample(intPCMPosition); - // We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial. - // It's assumed that the multiplication circuitry intended to perform the interpolation on the slave PCM partial - // is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair). - if (pcmWaveInterpolated) { - sample = firstSample + (getPCMSample(intPCMPosition + 1) - firstSample) * (pcmPosition - intPCMPosition); - } else { - sample = firstSample; - } - - float newPCMPosition = pcmPosition + positionDelta; - if (pcmWaveLooped) { - newPCMPosition = fmod(newPCMPosition, float(pcmWaveLength)); - } - pcmPosition = newPCMPosition; - } else { - // Render synthesised waveform - wavePos *= lastFreq / freq; - lastFreq = freq; - - float resAmp = EXP2F(1.0f - (32 - resonance) / 4.0f); - { - //static const float resAmpFactor = EXP2F(-7); - //resAmp = EXP2I(resonance << 10) * resAmpFactor; - } - - // The cutoffModifier may not be supposed to be directly added to the cutoff - - // it may for example need to be multiplied in some way. - // The 240 cutoffVal limit was determined via sample analysis (internal Munt capture IDs: glop3, glop4). - // More research is needed to be sure that this is correct, however. - float cutoffVal = cutoffRampVal / 262144.0f; - if (cutoffVal > MAX_CUTOFF_VALUE) { - cutoffVal = MAX_CUTOFF_VALUE; - } - - // Wave length in samples - float waveLen = SAMPLE_RATE / freq; - - // Init cosineLen - float cosineLen = 0.5f * waveLen; - if (cutoffVal > MIDDLE_CUTOFF_VALUE) { - cosineLen *= EXP2F((cutoffVal - MIDDLE_CUTOFF_VALUE) / -16.0f); // found from sample analysis - } - - // Start playing in center of first cosine segment - // relWavePos is shifted by a half of cosineLen - float relWavePos = wavePos + 0.5f * cosineLen; - if (relWavePos > waveLen) { - relWavePos -= waveLen; - } - - // Ratio of positive segment to wave length - float pulseLen = 0.5f; - if (pulseWidth > 128) { - pulseLen = EXP2F((64 - pulseWidth) / 64.0f); - //static const float pulseLenFactor = EXP2F(-192 / 64); - //pulseLen = EXP2I((256 - pulseWidthVal) << 6) * pulseLenFactor; - } - pulseLen *= waveLen; - - float hLen = pulseLen - cosineLen; - - // Ignore pulsewidths too high for given freq - if (hLen < 0.0f) { - hLen = 0.0f; - } - - // Correct resAmp for cutoff in range 50..66 - if ((cutoffVal >= MIDDLE_CUTOFF_VALUE) && (cutoffVal < RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE)) { - resAmp *= sin(FLOAT_PI * (cutoffVal - MIDDLE_CUTOFF_VALUE) / 32.0f); - } - - // Produce filtered square wave with 2 cosine waves on slopes - - // 1st cosine segment - if (relWavePos < cosineLen) { - sample = -cos(FLOAT_PI * relWavePos / cosineLen); - } else - - // high linear segment - if (relWavePos < (cosineLen + hLen)) { - sample = 1.f; - } else - - // 2nd cosine segment - if (relWavePos < (2 * cosineLen + hLen)) { - sample = cos(FLOAT_PI * (relWavePos - (cosineLen + hLen)) / cosineLen); - } else { - - // low linear segment - sample = -1.f; - } - - if (cutoffVal < MIDDLE_CUTOFF_VALUE) { - - // Attenuate samples below cutoff 50 - // Found by sample analysis - sample *= EXP2F(-0.125f * (MIDDLE_CUTOFF_VALUE - cutoffVal)); - } else { - - // Add resonance sine. Effective for cutoff > 50 only - float resSample = 1.0f; - - // Resonance decay speed factor - float resAmpDecayFactor = Tables::getInstance().resAmpDecayFactor[resonance >> 2]; - - // Now relWavePos counts from the middle of first cosine - relWavePos = wavePos; - - // negative segments - if (!(relWavePos < (cosineLen + hLen))) { - resSample = -resSample; - relWavePos -= cosineLen + hLen; - - // From the digital captures, the decaying speed of the resonance sine is found a bit different for the positive and the negative segments - resAmpDecayFactor += 0.25f; - } - - // Resonance sine WG - resSample *= sin(FLOAT_PI * relWavePos / cosineLen); - - // Resonance sine amp - float resAmpFadeLog2 = -0.125f * resAmpDecayFactor * (relWavePos / cosineLen); // seems to be exact - float resAmpFade = EXP2F(resAmpFadeLog2); - - // Now relWavePos set negative to the left from center of any cosine - relWavePos = wavePos; - - // negative segment - if (!(wavePos < (waveLen - 0.5f * cosineLen))) { - relWavePos -= waveLen; - } else - - // positive segment - if (!(wavePos < (hLen + 0.5f * cosineLen))) { - relWavePos -= cosineLen + hLen; - } - - // To ensure the output wave has no breaks, two different windows are appied to the beginning and the ending of the resonance sine segment - if (relWavePos < 0.5f * cosineLen) { - float syncSine = sin(FLOAT_PI * relWavePos / cosineLen); - if (relWavePos < 0.0f) { - // The window is synchronous square sine here - resAmpFade *= syncSine * syncSine; - } else { - // The window is synchronous sine here - resAmpFade *= syncSine; - } - } - - sample += resSample * resAmp * resAmpFade; - } - - // sawtooth waves - if (sawtoothWaveform) { - sample *= cos(FLOAT_2PI * wavePos / waveLen); - } - - wavePos++; - - // wavePos isn't supposed to be > waveLen - if (wavePos > waveLen) { - wavePos -= waveLen; - } - } - - // Multiply sample with current TVA value - sample *= amp; - return sample; -} - -void LA32FloatWaveGenerator::deactivate() { - active = false; -} - -bool LA32FloatWaveGenerator::isActive() const { - return active; -} - -bool LA32FloatWaveGenerator::isPCMWave() const { - return pcmWaveAddress != NULL; -} - -void LA32FloatPartialPair::init(const bool useRingModulated, const bool useMixed) { - ringModulated = useRingModulated; - mixed = useMixed; - masterOutputSample = 0.0f; - slaveOutputSample = 0.0f; -} - -void LA32FloatPartialPair::initSynth(const PairType useMaster, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) { - if (useMaster == MASTER) { - master.initSynth(sawtoothWaveform, pulseWidth, resonance); - } else { - slave.initSynth(sawtoothWaveform, pulseWidth, resonance); - } -} - -void LA32FloatPartialPair::initPCM(const PairType useMaster, const Bit16s *pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) { - if (useMaster == MASTER) { - master.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, true); - } else { - slave.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, !ringModulated); - } -} - -void LA32FloatPartialPair::generateNextSample(const PairType useMaster, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff) { - if (useMaster == MASTER) { - masterOutputSample = master.generateNextSample(amp, pitch, cutoff); - } else { - slaveOutputSample = slave.generateNextSample(amp, pitch, cutoff); - } -} - -static inline float produceDistortedSample(float sample) { - if (sample < -1.0f) { - return sample + 2.0f; - } else if (1.0f < sample) { - return sample - 2.0f; - } - return sample; -} - -float LA32FloatPartialPair::nextOutSample() { - // Note, LA32FloatWaveGenerator produces each sample normalised in terms of a single playing partial, - // so the unity sample corresponds to the internal LA32 logarithmic fixed-point unity sample. - // However, each logarithmic sample is then unlogged to a 14-bit signed integer value, i.e. the max absolute value is 8192. - // Thus, considering that samples are further mapped to a 16-bit signed integer, - // we apply a conversion factor 0.25 to produce properly normalised float samples. - if (!ringModulated) { - return 0.25f * (masterOutputSample + slaveOutputSample); - } - /* - * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion. - * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191. - * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case. - * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space, - * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication. - * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning. - */ - float ringModulatedSample = produceDistortedSample(masterOutputSample) * produceDistortedSample(slaveOutputSample); - return 0.25f * (mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample); -} - -void LA32FloatPartialPair::deactivate(const PairType useMaster) { - if (useMaster == MASTER) { - master.deactivate(); - masterOutputSample = 0.0f; - } else { - slave.deactivate(); - slaveOutputSample = 0.0f; - } -} - -bool LA32FloatPartialPair::isActive(const PairType useMaster) const { - return useMaster == MASTER ? master.isActive() : slave.isActive(); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/LA32FloatWaveGenerator.h b/src - Cópia/sound/munt/LA32FloatWaveGenerator.h deleted file mode 100644 index 7e92d0a67..000000000 --- a/src - Cópia/sound/munt/LA32FloatWaveGenerator.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H -#define MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H - -#include "globals.h" -#include "internals.h" -#include "Types.h" -#include "LA32WaveGenerator.h" - -namespace MT32Emu { - -/** - * LA32WaveGenerator is aimed to represent the exact model of LA32 wave generator. - * The output square wave is created by adding high / low linear segments in-between - * the rising and falling cosine segments. Basically, it's very similar to the phase distortion synthesis. - * Behaviour of a true resonance filter is emulated by adding decaying sine wave. - * The beginning and the ending of the resonant sine is multiplied by a cosine window. - * To synthesise sawtooth waves, the resulting square wave is multiplied by synchronous cosine wave. - */ -class LA32FloatWaveGenerator { - //*************************************************************************** - // The local copy of partial parameters below - //*************************************************************************** - - bool active; - - // True means the resulting square wave is to be multiplied by the synchronous cosine - bool sawtoothWaveform; - - // Values in range [1..31] - // Value 1 correspong to the minimum resonance - Bit8u resonance; - - // Processed value in range [0..255] - // Values in range [0..128] have no effect and the resulting wave remains symmetrical - // Value 255 corresponds to the maximum possible asymmetric of the resulting wave - Bit8u pulseWidth; - - // Logarithmic PCM sample start address - const Bit16s *pcmWaveAddress; - - // Logarithmic PCM sample length - Bit32u pcmWaveLength; - - // true for looped logarithmic PCM samples - bool pcmWaveLooped; - - // false for slave PCM partials in the structures with the ring modulation - bool pcmWaveInterpolated; - - //*************************************************************************** - // Internal variables below - //*************************************************************************** - - float wavePos; - float lastFreq; - float pcmPosition; - - float getPCMSample(unsigned int position); - -public: - // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters - void initSynth(const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); - - // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters - void initPCM(const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped, const bool pcmWaveInterpolated); - - // Update parameters with respect to TVP, TVA and TVF, and generate next sample - float generateNextSample(const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); - - // Deactivate the WG engine - void deactivate(); - - // Return active state of the WG engine - bool isActive() const; - - // Return true if the WG engine generates PCM wave samples - bool isPCMWave() const; -}; // class LA32FloatWaveGenerator - -class LA32FloatPartialPair : public LA32PartialPair { - LA32FloatWaveGenerator master; - LA32FloatWaveGenerator slave; - bool ringModulated; - bool mixed; - float masterOutputSample; - float slaveOutputSample; - -public: - // ringModulated should be set to false for the structures with mixing or stereo output - // ringModulated should be set to true for the structures with ring modulation - // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output - void init(const bool ringModulated, const bool mixed); - - // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters - void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); - - // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters - void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped); - - // Update parameters with respect to TVP, TVA and TVF, and generate next sample - void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); - - // Perform mixing / ring modulation and return the result - float nextOutSample(); - - // Deactivate the WG engine - void deactivate(const PairType master); - - // Return active state of the WG engine - bool isActive(const PairType master) const; -}; // class LA32FloatPartialPair - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H diff --git a/src - Cópia/sound/munt/LA32Ramp.cpp b/src - Cópia/sound/munt/LA32Ramp.cpp deleted file mode 100644 index 9dcf143fb..000000000 --- a/src - Cópia/sound/munt/LA32Ramp.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/* -Some notes on this class: - -This emulates the LA-32's implementation of "ramps". A ramp in this context is a smooth transition from one value to another, handled entirely within the LA-32. -The LA-32 provides this feature for amplitude and filter cutoff values. - -The 8095 starts ramps on the LA-32 by setting two values in memory-mapped registers: - -(1) The target value (between 0 and 255) for the ramp to end on. This is represented by the "target" argument to startRamp(). -(2) The speed at which that value should be approached. This is represented by the "increment" argument to startRamp(). - -Once the ramp target value has been hit, the LA-32 raises an interrupt. - -Note that the starting point of the ramp is whatever internal value the LA-32 had when the registers were set. This is usually the end point of a previously completed ramp. - -Our handling of the "target" and "increment" values is based on sample analysis and a little guesswork. -Here's what we're pretty confident about: - - The most significant bit of "increment" indicates the direction that the LA32's current internal value ("current" in our emulation) should change in. - Set means downward, clear means upward. - - The lower 7 bits of "increment" indicate how quickly "current" should be changed. - - If "increment" is 0, no change to "current" is made and no interrupt is raised. [SEMI-CONFIRMED by sample analysis] - - Otherwise, if the MSb is set: - - If "current" already corresponds to a value <= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised. - - Otherwise, "current" is gradually reduced (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised. - - Otherwise (the MSb is unset): - - If "current" already corresponds to a value >= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised. - - Otherwise, "current" is gradually increased (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised. - -We haven't fully explored: - - Values when ramping between levels (though this is probably correct). - - Transition timing (may not be 100% accurate, especially for very fast ramps). -*/ - -#include "internals.h" - -#include "LA32Ramp.h" -#include "Tables.h" - -namespace MT32Emu { - -// SEMI-CONFIRMED from sample analysis. -const unsigned int TARGET_SHIFTS = 18; -const unsigned int MAX_CURRENT = 0xFF << TARGET_SHIFTS; - -// We simulate the delay in handling "target was reached" interrupts by waiting -// this many samples before setting interruptRaised. -// FIXME: This should vary with the sample rate, but doesn't. -// SEMI-CONFIRMED: Since this involves asynchronous activity between the LA32 -// and the 8095, a good value is hard to pin down. -// This one matches observed behaviour on a few digital captures I had handy, -// and should be double-checked. We may also need a more sophisticated delay -// scheme eventually. -const int INTERRUPT_TIME = 7; - -LA32Ramp::LA32Ramp() : - current(0), - largeTarget(0), - largeIncrement(0), - interruptCountdown(0), - interruptRaised(false) { -} - -void LA32Ramp::startRamp(Bit8u target, Bit8u increment) { - // CONFIRMED: From sample analysis, this appears to be very accurate. - if (increment == 0) { - largeIncrement = 0; - } else { - // Three bits in the fractional part, no need to interpolate - // (unsigned int)(EXP2F(((increment & 0x7F) + 24) / 8.0f) + 0.125f) - Bit32u expArg = increment & 0x7F; - largeIncrement = 8191 - Tables::getInstance().exp9[~(expArg << 6) & 511]; - largeIncrement <<= expArg >> 3; - largeIncrement += 64; - largeIncrement >>= 9; - } - descending = (increment & 0x80) != 0; - if (descending) { - // CONFIRMED: From sample analysis, descending increments are slightly faster - largeIncrement++; - } - - largeTarget = target << TARGET_SHIFTS; - interruptCountdown = 0; - interruptRaised = false; -} - -Bit32u LA32Ramp::nextValue() { - if (interruptCountdown > 0) { - if (--interruptCountdown == 0) { - interruptRaised = true; - } - } else if (largeIncrement != 0) { - // CONFIRMED from sample analysis: When increment is 0, the LA32 does *not* change the current value at all (and of course doesn't fire an interrupt). - if (descending) { - // Lowering current value - if (largeIncrement > current) { - current = largeTarget; - interruptCountdown = INTERRUPT_TIME; - } else { - current -= largeIncrement; - if (current <= largeTarget) { - current = largeTarget; - interruptCountdown = INTERRUPT_TIME; - } - } - } else { - // Raising current value - if (MAX_CURRENT - current < largeIncrement) { - current = largeTarget; - interruptCountdown = INTERRUPT_TIME; - } else { - current += largeIncrement; - if (current >= largeTarget) { - current = largeTarget; - interruptCountdown = INTERRUPT_TIME; - } - } - } - } - return current; -} - -bool LA32Ramp::checkInterrupt() { - bool wasRaised = interruptRaised; - interruptRaised = false; - return wasRaised; -} - -void LA32Ramp::reset() { - current = 0; - largeTarget = 0; - largeIncrement = 0; - descending = false; - interruptCountdown = 0; - interruptRaised = false; -} - -// This is actually beyond the LA32 ramp interface. -// Instead of polling the current value, MCU receives an interrupt when a ramp completes. -// However, this is a simple way to work around the specific behaviour of TVA -// when in sustain phase which one normally wants to avoid. -// See TVA::recalcSustain() for details. -bool LA32Ramp::isBelowCurrent(Bit8u target) const { - return Bit32u(target << TARGET_SHIFTS) < current; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/LA32Ramp.h b/src - Cópia/sound/munt/LA32Ramp.h deleted file mode 100644 index 959a1ad37..000000000 --- a/src - Cópia/sound/munt/LA32Ramp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_LA32RAMP_H -#define MT32EMU_LA32RAMP_H - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -class LA32Ramp { -private: - Bit32u current; - unsigned int largeTarget; - unsigned int largeIncrement; - bool descending; - - int interruptCountdown; - bool interruptRaised; - -public: - LA32Ramp(); - void startRamp(Bit8u target, Bit8u increment); - Bit32u nextValue(); - bool checkInterrupt(); - void reset(); - bool isBelowCurrent(Bit8u target) const; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_LA32RAMP_H diff --git a/src - Cópia/sound/munt/LA32WaveGenerator.cpp b/src - Cópia/sound/munt/LA32WaveGenerator.cpp deleted file mode 100644 index f6f692880..000000000 --- a/src - Cópia/sound/munt/LA32WaveGenerator.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "LA32WaveGenerator.h" -#include "Tables.h" - -namespace MT32Emu { - -static const Bit32u SINE_SEGMENT_RELATIVE_LENGTH = 1 << 18; -static const Bit32u MIDDLE_CUTOFF_VALUE = 128 << 18; -static const Bit32u RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE = 144 << 18; -static const Bit32u MAX_CUTOFF_VALUE = 240 << 18; -static const LogSample SILENCE = {65535, LogSample::POSITIVE}; - -Bit16u LA32Utilites::interpolateExp(const Bit16u fract) { - Bit16u expTabIndex = fract >> 3; - Bit16u extraBits = ~fract & 7; - Bit16u expTabEntry2 = 8191 - Tables::getInstance().exp9[expTabIndex]; - Bit16u expTabEntry1 = expTabIndex == 0 ? 8191 : (8191 - Tables::getInstance().exp9[expTabIndex - 1]); - return expTabEntry2 + (((expTabEntry1 - expTabEntry2) * extraBits) >> 3); -} - -Bit16s LA32Utilites::unlog(const LogSample &logSample) { - //Bit16s sample = (Bit16s)EXP2F(13.0f - logSample.logValue / 1024.0f); - Bit32u intLogValue = logSample.logValue >> 12; - Bit16u fracLogValue = logSample.logValue & 4095; - Bit16s sample = interpolateExp(fracLogValue) >> intLogValue; - return logSample.sign == LogSample::POSITIVE ? sample : -sample; -} - -void LA32Utilites::addLogSamples(LogSample &logSample1, const LogSample &logSample2) { - Bit32u logSampleValue = logSample1.logValue + logSample2.logValue; - logSample1.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; - logSample1.sign = logSample1.sign == logSample2.sign ? LogSample::POSITIVE : LogSample::NEGATIVE; -} - -Bit32u LA32WaveGenerator::getSampleStep() { - // sampleStep = EXP2F(pitch / 4096.0f + 4.0f) - Bit32u sampleStep = LA32Utilites::interpolateExp(~pitch & 4095); - sampleStep <<= pitch >> 12; - sampleStep >>= 8; - sampleStep &= ~1; - return sampleStep; -} - -Bit32u LA32WaveGenerator::getResonanceWaveLengthFactor(Bit32u effectiveCutoffValue) { - // resonanceWaveLengthFactor = (Bit32u)EXP2F(12.0f + effectiveCutoffValue / 4096.0f); - Bit32u resonanceWaveLengthFactor = LA32Utilites::interpolateExp(~effectiveCutoffValue & 4095); - resonanceWaveLengthFactor <<= effectiveCutoffValue >> 12; - return resonanceWaveLengthFactor; -} - -Bit32u LA32WaveGenerator::getHighLinearLength(Bit32u effectiveCutoffValue) { - // Ratio of positive segment to wave length - Bit32u effectivePulseWidthValue = 0; - if (pulseWidth > 128) { - effectivePulseWidthValue = (pulseWidth - 128) << 6; - } - - Bit32u highLinearLength = 0; - // highLinearLength = EXP2F(19.0f - effectivePulseWidthValue / 4096.0f + effectiveCutoffValue / 4096.0f) - 2 * SINE_SEGMENT_RELATIVE_LENGTH; - if (effectivePulseWidthValue < effectiveCutoffValue) { - Bit32u expArg = effectiveCutoffValue - effectivePulseWidthValue; - highLinearLength = LA32Utilites::interpolateExp(~expArg & 4095); - highLinearLength <<= 7 + (expArg >> 12); - highLinearLength -= 2 * SINE_SEGMENT_RELATIVE_LENGTH; - } - return highLinearLength; -} - -void LA32WaveGenerator::computePositions(Bit32u highLinearLength, Bit32u lowLinearLength, Bit32u resonanceWaveLengthFactor) { - // Assuming 12-bit multiplication used here - squareWavePosition = resonanceSinePosition = (wavePosition >> 8) * (resonanceWaveLengthFactor >> 4); - if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { - phase = POSITIVE_RISING_SINE_SEGMENT; - return; - } - squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; - if (squareWavePosition < highLinearLength) { - phase = POSITIVE_LINEAR_SEGMENT; - return; - } - squareWavePosition -= highLinearLength; - if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { - phase = POSITIVE_FALLING_SINE_SEGMENT; - return; - } - squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; - resonanceSinePosition = squareWavePosition; - if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { - phase = NEGATIVE_FALLING_SINE_SEGMENT; - return; - } - squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; - if (squareWavePosition < lowLinearLength) { - phase = NEGATIVE_LINEAR_SEGMENT; - return; - } - squareWavePosition -= lowLinearLength; - phase = NEGATIVE_RISING_SINE_SEGMENT; -} - -void LA32WaveGenerator::advancePosition() { - wavePosition += getSampleStep(); - wavePosition %= 4 * SINE_SEGMENT_RELATIVE_LENGTH; - - Bit32u effectiveCutoffValue = (cutoffVal > MIDDLE_CUTOFF_VALUE) ? (cutoffVal - MIDDLE_CUTOFF_VALUE) >> 10 : 0; - Bit32u resonanceWaveLengthFactor = getResonanceWaveLengthFactor(effectiveCutoffValue); - Bit32u highLinearLength = getHighLinearLength(effectiveCutoffValue); - Bit32u lowLinearLength = (resonanceWaveLengthFactor << 8) - 4 * SINE_SEGMENT_RELATIVE_LENGTH - highLinearLength; - computePositions(highLinearLength, lowLinearLength, resonanceWaveLengthFactor); - - resonancePhase = ResonancePhase(((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3); -} - -void LA32WaveGenerator::generateNextSquareWaveLogSample() { - Bit32u logSampleValue; - switch (phase) { - case POSITIVE_RISING_SINE_SEGMENT: - case NEGATIVE_FALLING_SINE_SEGMENT: - logSampleValue = Tables::getInstance().logsin9[(squareWavePosition >> 9) & 511]; - break; - case POSITIVE_FALLING_SINE_SEGMENT: - case NEGATIVE_RISING_SINE_SEGMENT: - logSampleValue = Tables::getInstance().logsin9[~(squareWavePosition >> 9) & 511]; - break; - case POSITIVE_LINEAR_SEGMENT: - case NEGATIVE_LINEAR_SEGMENT: - default: - logSampleValue = 0; - break; - } - logSampleValue <<= 2; - logSampleValue += amp >> 10; - if (cutoffVal < MIDDLE_CUTOFF_VALUE) { - logSampleValue += (MIDDLE_CUTOFF_VALUE - cutoffVal) >> 9; - } - - squareLogSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; - squareLogSample.sign = phase < NEGATIVE_FALLING_SINE_SEGMENT ? LogSample::POSITIVE : LogSample::NEGATIVE; -} - -void LA32WaveGenerator::generateNextResonanceWaveLogSample() { - Bit32u logSampleValue; - if (resonancePhase == POSITIVE_FALLING_RESONANCE_SINE_SEGMENT || resonancePhase == NEGATIVE_RISING_RESONANCE_SINE_SEGMENT) { - logSampleValue = Tables::getInstance().logsin9[~(resonanceSinePosition >> 9) & 511]; - } else { - logSampleValue = Tables::getInstance().logsin9[(resonanceSinePosition >> 9) & 511]; - } - logSampleValue <<= 2; - logSampleValue += amp >> 10; - - // From the digital captures, the decaying speed of the resonance sine is found a bit different for the positive and the negative segments - Bit32u decayFactor = phase < NEGATIVE_FALLING_SINE_SEGMENT ? resAmpDecayFactor : resAmpDecayFactor + 1; - // Unsure about resonanceSinePosition here. It's possible that dedicated counter & decrement are used. Although, cutoff is finely ramped, so maybe not. - logSampleValue += resonanceAmpSubtraction + (((resonanceSinePosition >> 4) * decayFactor) >> 8); - - // To ensure the output wave has no breaks, two different windows are appied to the beginning and the ending of the resonance sine segment - if (phase == POSITIVE_RISING_SINE_SEGMENT || phase == NEGATIVE_FALLING_SINE_SEGMENT) { - // The window is synchronous sine here - logSampleValue += Tables::getInstance().logsin9[(squareWavePosition >> 9) & 511] << 2; - } else if (phase == POSITIVE_FALLING_SINE_SEGMENT || phase == NEGATIVE_RISING_SINE_SEGMENT) { - // The window is synchronous square sine here - logSampleValue += Tables::getInstance().logsin9[~(squareWavePosition >> 9) & 511] << 3; - } - - if (cutoffVal < MIDDLE_CUTOFF_VALUE) { - // For the cutoff values below the cutoff middle point, it seems the amp of the resonance wave is expotentially decayed - logSampleValue += 31743 + ((MIDDLE_CUTOFF_VALUE - cutoffVal) >> 9); - } else if (cutoffVal < RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE) { - // For the cutoff values below this point, the amp of the resonance wave is sinusoidally decayed - Bit32u sineIx = (cutoffVal - MIDDLE_CUTOFF_VALUE) >> 13; - logSampleValue += Tables::getInstance().logsin9[sineIx] << 2; - } - - // After all the amp decrements are added, it should be safe now to adjust the amp of the resonance wave to what we see on captures - logSampleValue -= 1 << 12; - - resonanceLogSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; - resonanceLogSample.sign = resonancePhase < NEGATIVE_FALLING_RESONANCE_SINE_SEGMENT ? LogSample::POSITIVE : LogSample::NEGATIVE; -} - -void LA32WaveGenerator::generateNextSawtoothCosineLogSample(LogSample &logSample) const { - Bit32u sawtoothCosinePosition = wavePosition + (1 << 18); - if ((sawtoothCosinePosition & (1 << 18)) > 0) { - logSample.logValue = Tables::getInstance().logsin9[~(sawtoothCosinePosition >> 9) & 511]; - } else { - logSample.logValue = Tables::getInstance().logsin9[(sawtoothCosinePosition >> 9) & 511]; - } - logSample.logValue <<= 2; - logSample.sign = ((sawtoothCosinePosition & (1 << 19)) == 0) ? LogSample::POSITIVE : LogSample::NEGATIVE; -} - -void LA32WaveGenerator::pcmSampleToLogSample(LogSample &logSample, const Bit16s pcmSample) const { - Bit32u logSampleValue = (32787 - (pcmSample & 32767)) << 1; - logSampleValue += amp >> 10; - logSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; - logSample.sign = pcmSample < 0 ? LogSample::NEGATIVE : LogSample::POSITIVE; -} - -void LA32WaveGenerator::generateNextPCMWaveLogSamples() { - // This should emulate the ladder we see in the PCM captures for pitches 01, 02, 07, etc. - // The most probable cause is the factor in the interpolation formula is one bit less - // accurate than the sample position counter - pcmInterpolationFactor = (wavePosition & 255) >> 1; - Bit32u pcmWaveTableIx = wavePosition >> 8; - pcmSampleToLogSample(firstPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); - if (pcmWaveInterpolated) { - pcmWaveTableIx++; - if (pcmWaveTableIx < pcmWaveLength) { - pcmSampleToLogSample(secondPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); - } else { - if (pcmWaveLooped) { - pcmWaveTableIx -= pcmWaveLength; - pcmSampleToLogSample(secondPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); - } else { - secondPCMLogSample = SILENCE; - } - } - } else { - secondPCMLogSample = SILENCE; - } - // pcmSampleStep = (Bit32u)EXP2F(pitch / 4096.0f + 3.0f); - Bit32u pcmSampleStep = LA32Utilites::interpolateExp(~pitch & 4095); - pcmSampleStep <<= pitch >> 12; - // Seeing the actual lengths of the PCM wave for pitches 00..12, - // the pcmPosition counter can be assumed to have 8-bit fractions - pcmSampleStep >>= 9; - wavePosition += pcmSampleStep; - if (wavePosition >= (pcmWaveLength << 8)) { - if (pcmWaveLooped) { - wavePosition -= pcmWaveLength << 8; - } else { - deactivate(); - } - } -} - -void LA32WaveGenerator::initSynth(const bool useSawtoothWaveform, const Bit8u usePulseWidth, const Bit8u useResonance) { - sawtoothWaveform = useSawtoothWaveform; - pulseWidth = usePulseWidth; - resonance = useResonance; - - wavePosition = 0; - - squareWavePosition = 0; - phase = POSITIVE_RISING_SINE_SEGMENT; - - resonanceSinePosition = 0; - resonancePhase = POSITIVE_RISING_RESONANCE_SINE_SEGMENT; - resonanceAmpSubtraction = (32 - resonance) << 10; - resAmpDecayFactor = Tables::getInstance().resAmpDecayFactor[resonance >> 2] << 2; - - pcmWaveAddress = NULL; - active = true; -} - -void LA32WaveGenerator::initPCM(const Bit16s * const usePCMWaveAddress, const Bit32u usePCMWaveLength, const bool usePCMWaveLooped, const bool usePCMWaveInterpolated) { - pcmWaveAddress = usePCMWaveAddress; - pcmWaveLength = usePCMWaveLength; - pcmWaveLooped = usePCMWaveLooped; - pcmWaveInterpolated = usePCMWaveInterpolated; - - wavePosition = 0; - active = true; -} - -void LA32WaveGenerator::generateNextSample(const Bit32u useAmp, const Bit16u usePitch, const Bit32u useCutoffVal) { - if (!active) { - return; - } - - amp = useAmp; - pitch = usePitch; - - if (isPCMWave()) { - generateNextPCMWaveLogSamples(); - return; - } - - // The 240 cutoffVal limit was determined via sample analysis (internal Munt capture IDs: glop3, glop4). - // More research is needed to be sure that this is correct, however. - cutoffVal = (useCutoffVal > MAX_CUTOFF_VALUE) ? MAX_CUTOFF_VALUE : useCutoffVal; - - generateNextSquareWaveLogSample(); - generateNextResonanceWaveLogSample(); - if (sawtoothWaveform) { - LogSample cosineLogSample; - generateNextSawtoothCosineLogSample(cosineLogSample); - LA32Utilites::addLogSamples(squareLogSample, cosineLogSample); - LA32Utilites::addLogSamples(resonanceLogSample, cosineLogSample); - } - advancePosition(); -} - -LogSample LA32WaveGenerator::getOutputLogSample(const bool first) const { - if (!isActive()) { - return SILENCE; - } - if (isPCMWave()) { - return first ? firstPCMLogSample : secondPCMLogSample; - } - return first ? squareLogSample : resonanceLogSample; -} - -void LA32WaveGenerator::deactivate() { - active = false; -} - -bool LA32WaveGenerator::isActive() const { - return active; -} - -bool LA32WaveGenerator::isPCMWave() const { - return pcmWaveAddress != NULL; -} - -Bit32u LA32WaveGenerator::getPCMInterpolationFactor() const { - return pcmInterpolationFactor; -} - -void LA32IntPartialPair::init(const bool useRingModulated, const bool useMixed) { - ringModulated = useRingModulated; - mixed = useMixed; -} - -void LA32IntPartialPair::initSynth(const PairType useMaster, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) { - if (useMaster == MASTER) { - master.initSynth(sawtoothWaveform, pulseWidth, resonance); - } else { - slave.initSynth(sawtoothWaveform, pulseWidth, resonance); - } -} - -void LA32IntPartialPair::initPCM(const PairType useMaster, const Bit16s *pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) { - if (useMaster == MASTER) { - master.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, true); - } else { - slave.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, !ringModulated); - } -} - -void LA32IntPartialPair::generateNextSample(const PairType useMaster, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff) { - if (useMaster == MASTER) { - master.generateNextSample(amp, pitch, cutoff); - } else { - slave.generateNextSample(amp, pitch, cutoff); - } -} - -Bit16s LA32IntPartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg) { - if (!wg.isActive()) { - return 0; - } - Bit16s firstSample = LA32Utilites::unlog(wg.getOutputLogSample(true)); - Bit16s secondSample = LA32Utilites::unlog(wg.getOutputLogSample(false)); - if (wg.isPCMWave()) { - return Bit16s(firstSample + (((Bit32s(secondSample) - Bit32s(firstSample)) * wg.getPCMInterpolationFactor()) >> 7)); - } - return firstSample + secondSample; -} - -static inline Bit16s produceDistortedSample(Bit16s sample) { - return ((sample & 0x2000) == 0) ? Bit16s(sample & 0x1fff) : Bit16s(sample | ~0x1fff); -} - -Bit16s LA32IntPartialPair::nextOutSample() { - if (!ringModulated) { - return unlogAndMixWGOutput(master) + unlogAndMixWGOutput(slave); - } - - Bit16s masterSample = unlogAndMixWGOutput(master); // Store master partial sample for further mixing - - /* SEMI-CONFIRMED from sample analysis: - * We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial. - * It's assumed that the multiplication circuitry intended to perform the interpolation on the slave PCM partial - * is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair). - */ - Bit16s slaveSample = slave.isPCMWave() ? LA32Utilites::unlog(slave.getOutputLogSample(true)) : unlogAndMixWGOutput(slave); - - /* SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion. - * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191. - * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case. - * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space, - * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication. - * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning. - */ - Bit16s ringModulatedSample = Bit16s((Bit32s(produceDistortedSample(masterSample)) * Bit32s(produceDistortedSample(slaveSample))) >> 13); - - return mixed ? masterSample + ringModulatedSample : ringModulatedSample; -} - -void LA32IntPartialPair::deactivate(const PairType useMaster) { - if (useMaster == MASTER) { - master.deactivate(); - } else { - slave.deactivate(); - } -} - -bool LA32IntPartialPair::isActive(const PairType useMaster) const { - return useMaster == MASTER ? master.isActive() : slave.isActive(); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/LA32WaveGenerator.h b/src - Cópia/sound/munt/LA32WaveGenerator.h deleted file mode 100644 index c206daa63..000000000 --- a/src - Cópia/sound/munt/LA32WaveGenerator.h +++ /dev/null @@ -1,266 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_LA32_WAVE_GENERATOR_H -#define MT32EMU_LA32_WAVE_GENERATOR_H - -#include "globals.h" -#include "internals.h" -#include "Types.h" - -namespace MT32Emu { - -/** - * LA32 performs wave generation in the log-space that allows replacing multiplications by cheap additions - * It's assumed that only low-bit multiplications occur in a few places which are unavoidable like these: - * - interpolation of exponent table (obvious, a delta value has 4 bits) - * - computation of resonance amp decay envelope (the table contains values with 1-2 "1" bits except the very first value 31 but this case can be found using inversion) - * - interpolation of PCM samples (obvious, the wave position counter is in the linear space, there is no log() table in the chip) - * and it seems to be implemented in the same way as in the Boss chip, i.e. right shifted additions which involved noticeable precision loss - * Subtraction is supposed to be replaced by simple inversion - * As the logarithmic sine is always negative, all the logarithmic values are treated as decrements - */ -struct LogSample { - // 16-bit fixed point value, includes 12-bit fractional part - // 4-bit integer part allows to present any 16-bit sample in the log-space - // Obviously, the log value doesn't contain the sign of the resulting sample - Bit16u logValue; - enum { - POSITIVE, - NEGATIVE - } sign; -}; - -class LA32Utilites { -public: - static Bit16u interpolateExp(const Bit16u fract); - static Bit16s unlog(const LogSample &logSample); - static void addLogSamples(LogSample &logSample1, const LogSample &logSample2); -}; - -/** - * LA32WaveGenerator is aimed to represent the exact model of LA32 wave generator. - * The output square wave is created by adding high / low linear segments in-between - * the rising and falling cosine segments. Basically, it's very similar to the phase distortion synthesis. - * Behaviour of a true resonance filter is emulated by adding decaying sine wave. - * The beginning and the ending of the resonant sine is multiplied by a cosine window. - * To synthesise sawtooth waves, the resulting square wave is multiplied by synchronous cosine wave. - */ -class LA32WaveGenerator { - //*************************************************************************** - // The local copy of partial parameters below - //*************************************************************************** - - bool active; - - // True means the resulting square wave is to be multiplied by the synchronous cosine - bool sawtoothWaveform; - - // Logarithmic amp of the wave generator - Bit32u amp; - - // Logarithmic frequency of the resulting wave - Bit16u pitch; - - // Values in range [1..31] - // Value 1 correspong to the minimum resonance - Bit8u resonance; - - // Processed value in range [0..255] - // Values in range [0..128] have no effect and the resulting wave remains symmetrical - // Value 255 corresponds to the maximum possible asymmetric of the resulting wave - Bit8u pulseWidth; - - // Composed of the base cutoff in range [78..178] left-shifted by 18 bits and the TVF modifier - Bit32u cutoffVal; - - // Logarithmic PCM sample start address - const Bit16s *pcmWaveAddress; - - // Logarithmic PCM sample length - Bit32u pcmWaveLength; - - // true for looped logarithmic PCM samples - bool pcmWaveLooped; - - // false for slave PCM partials in the structures with the ring modulation - bool pcmWaveInterpolated; - - //*************************************************************************** - // Internal variables below - //*************************************************************************** - - // Relative position within either the synth wave or the PCM sampled wave - // 0 - start of the positive rising sine segment of the square wave or start of the PCM sample - // 1048576 (2^20) - end of the negative rising sine segment of the square wave - // For PCM waves, the address of the currently playing sample equals (wavePosition / 256) - Bit32u wavePosition; - - // Relative position within a square wave phase: - // 0 - start of the phase - // 262144 (2^18) - end of a sine phase in the square wave - Bit32u squareWavePosition; - - // Relative position within the positive or negative wave segment: - // 0 - start of the corresponding positive or negative segment of the square wave - // 262144 (2^18) - corresponds to end of the first sine phase in the square wave - // The same increment sampleStep is used to indicate the current position - // since the length of the resonance wave is always equal to four square wave sine segments. - Bit32u resonanceSinePosition; - - // The amp of the resonance sine wave grows with the resonance value - // As the resonance value cannot change while the partial is active, it is initialised once - Bit32u resonanceAmpSubtraction; - - // The decay speed of resonance sine wave, depends on the resonance value - Bit32u resAmpDecayFactor; - - // Fractional part of the pcmPosition - Bit32u pcmInterpolationFactor; - - // Current phase of the square wave - enum { - POSITIVE_RISING_SINE_SEGMENT, - POSITIVE_LINEAR_SEGMENT, - POSITIVE_FALLING_SINE_SEGMENT, - NEGATIVE_FALLING_SINE_SEGMENT, - NEGATIVE_LINEAR_SEGMENT, - NEGATIVE_RISING_SINE_SEGMENT - } phase; - - // Current phase of the resonance wave - enum ResonancePhase { - POSITIVE_RISING_RESONANCE_SINE_SEGMENT, - POSITIVE_FALLING_RESONANCE_SINE_SEGMENT, - NEGATIVE_FALLING_RESONANCE_SINE_SEGMENT, - NEGATIVE_RISING_RESONANCE_SINE_SEGMENT - } resonancePhase; - - // Resulting log-space samples of the square and resonance waves - LogSample squareLogSample; - LogSample resonanceLogSample; - - // Processed neighbour log-space samples of the PCM wave - LogSample firstPCMLogSample; - LogSample secondPCMLogSample; - - //*************************************************************************** - // Internal methods below - //*************************************************************************** - - Bit32u getSampleStep(); - Bit32u getResonanceWaveLengthFactor(Bit32u effectiveCutoffValue); - Bit32u getHighLinearLength(Bit32u effectiveCutoffValue); - - void computePositions(Bit32u highLinearLength, Bit32u lowLinearLength, Bit32u resonanceWaveLengthFactor); - void advancePosition(); - - void generateNextSquareWaveLogSample(); - void generateNextResonanceWaveLogSample(); - void generateNextSawtoothCosineLogSample(LogSample &logSample) const; - - void pcmSampleToLogSample(LogSample &logSample, const Bit16s pcmSample) const; - void generateNextPCMWaveLogSamples(); - -public: - // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters - void initSynth(const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); - - // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters - void initPCM(const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped, const bool pcmWaveInterpolated); - - // Update parameters with respect to TVP, TVA and TVF, and generate next sample - void generateNextSample(const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); - - // WG output in the log-space consists of two components which are to be added (or ring modulated) in the linear-space afterwards - LogSample getOutputLogSample(const bool first) const; - - // Deactivate the WG engine - void deactivate(); - - // Return active state of the WG engine - bool isActive() const; - - // Return true if the WG engine generates PCM wave samples - bool isPCMWave() const; - - // Return current PCM interpolation factor - Bit32u getPCMInterpolationFactor() const; -}; // class LA32WaveGenerator - -// LA32PartialPair contains a structure of two partials being mixed / ring modulated -class LA32PartialPair { -public: - enum PairType { - MASTER, - SLAVE - }; - - virtual ~LA32PartialPair() {} - - // ringModulated should be set to false for the structures with mixing or stereo output - // ringModulated should be set to true for the structures with ring modulation - // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output - virtual void init(const bool ringModulated, const bool mixed) = 0; - - // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters - virtual void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) = 0; - - // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters - virtual void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) = 0; - - // Deactivate the WG engine - virtual void deactivate(const PairType master) = 0; -}; // class LA32PartialPair - -class LA32IntPartialPair : public LA32PartialPair { - LA32WaveGenerator master; - LA32WaveGenerator slave; - bool ringModulated; - bool mixed; - - static Bit16s unlogAndMixWGOutput(const LA32WaveGenerator &wg); - -public: - // ringModulated should be set to false for the structures with mixing or stereo output - // ringModulated should be set to true for the structures with ring modulation - // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output - void init(const bool ringModulated, const bool mixed); - - // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters - void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); - - // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters - void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped); - - // Update parameters with respect to TVP, TVA and TVF, and generate next sample - void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); - - // Perform mixing / ring modulation of WG output and return the result - // Although, LA32 applies panning itself, we assume it is applied in the mixer, not within a pair - Bit16s nextOutSample(); - - // Deactivate the WG engine - void deactivate(const PairType master); - - // Return active state of the WG engine - bool isActive(const PairType master) const; -}; // class LA32IntPartialPair - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H diff --git a/src - Cópia/sound/munt/MemoryRegion.h b/src - Cópia/sound/munt/MemoryRegion.h deleted file mode 100644 index 807f14782..000000000 --- a/src - Cópia/sound/munt/MemoryRegion.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_MEMORY_REGION_H -#define MT32EMU_MEMORY_REGION_H - -#include - -#include "globals.h" -#include "Types.h" -#include "Structures.h" - -namespace MT32Emu { - -enum MemoryRegionType { - MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset -}; - -class Synth; - -class MemoryRegion { -private: - Synth *synth; - Bit8u *realMemory; - Bit8u *maxTable; -public: - MemoryRegionType type; - Bit32u startAddr, entrySize, entries; - - MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) { - synth = useSynth; - realMemory = useRealMemory; - maxTable = useMaxTable; - type = useType; - startAddr = useStartAddr; - entrySize = useEntrySize; - entries = useEntries; - } - int lastTouched(Bit32u addr, Bit32u len) const { - return (offset(addr) + len - 1) / entrySize; - } - int firstTouchedOffset(Bit32u addr) const { - return offset(addr) % entrySize; - } - int firstTouched(Bit32u addr) const { - return offset(addr) / entrySize; - } - Bit32u regionEnd() const { - return startAddr + entrySize * entries; - } - bool contains(Bit32u addr) const { - return addr >= startAddr && addr < regionEnd(); - } - int offset(Bit32u addr) const { - return addr - startAddr; - } - Bit32u getClampedLen(Bit32u addr, Bit32u len) const { - if (addr + len > regionEnd()) - return regionEnd() - addr; - return len; - } - Bit32u next(Bit32u addr, Bit32u len) const { - if (addr + len > regionEnd()) { - return regionEnd() - addr; - } - return 0; - } - Bit8u getMaxValue(int off) const { - if (maxTable == NULL) - return 0xFF; - return maxTable[off % entrySize]; - } - Bit8u *getRealMemory() const { - return realMemory; - } - bool isReadable() const { - return getRealMemory() != NULL; - } - void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const; - void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const; -}; // class MemoryRegion - -class PatchTempMemoryRegion : public MemoryRegion { -public: - PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {} -}; -class RhythmTempMemoryRegion : public MemoryRegion { -public: - RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {} -}; -class TimbreTempMemoryRegion : public MemoryRegion { -public: - TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {} -}; -class PatchesMemoryRegion : public MemoryRegion { -public: - PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {} -}; -class TimbresMemoryRegion : public MemoryRegion { -public: - TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {} -}; -class SystemMemoryRegion : public MemoryRegion { -public: - SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {} -}; -class DisplayMemoryRegion : public MemoryRegion { -public: - DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), SYSEX_BUFFER_SIZE - 1, 1) {} -}; -class ResetMemoryRegion : public MemoryRegion { -public: - ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {} -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_MEMORY_REGION_H diff --git a/src - Cópia/sound/munt/MidiEventQueue.h b/src - Cópia/sound/munt/MidiEventQueue.h deleted file mode 100644 index c5174d6cc..000000000 --- a/src - Cópia/sound/munt/MidiEventQueue.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_MIDI_EVENT_QUEUE_H -#define MT32EMU_MIDI_EVENT_QUEUE_H - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -/** - * Used to safely store timestamped MIDI events in a local queue. - */ -struct MidiEvent { - Bit32u shortMessageData; - const Bit8u *sysexData; - Bit32u sysexLength; - Bit32u timestamp; - - ~MidiEvent(); - void setShortMessage(Bit32u shortMessageData, Bit32u timestamp); - void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); -}; - -/** - * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it. - * It is intended to: - * - get rid of prerenderer while retaining graceful partial abortion - * - add fair emulation of the MIDI interface delays - * - extend the synth interface with the default implementation of a typical rendering loop. - * THREAD SAFETY: - * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading - * and one performs only writing. More complicated usage requires external synchronisation. - */ -class MidiEventQueue { -private: - MidiEvent * const ringBuffer; - const Bit32u ringBufferMask; - volatile Bit32u startPosition; - volatile Bit32u endPosition; - -public: - MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2 - ~MidiEventQueue(); - void reset(); - bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp); - bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); - const MidiEvent *peekMidiEvent(); - void dropMidiEvent(); - bool isFull() const; - bool inline isEmpty() const; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_MIDI_EVENT_QUEUE_H diff --git a/src - Cópia/sound/munt/MidiStreamParser.cpp b/src - Cópia/sound/munt/MidiStreamParser.cpp deleted file mode 100644 index a426a20cc..000000000 --- a/src - Cópia/sound/munt/MidiStreamParser.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "internals.h" - -#include "MidiStreamParser.h" -#include "Synth.h" - -using namespace MT32Emu; - -DefaultMidiStreamParser::DefaultMidiStreamParser(Synth &useSynth, Bit32u initialStreamBufferCapacity) : - MidiStreamParser(initialStreamBufferCapacity), synth(useSynth), timestampSet(false) {} - -void DefaultMidiStreamParser::setTimestamp(const Bit32u useTimestamp) { - timestampSet = true; - timestamp = useTimestamp; -} - -void DefaultMidiStreamParser::resetTimestamp() { - timestampSet = false; -} - -void DefaultMidiStreamParser::handleShortMessage(const Bit32u message) { - do { - if (timestampSet) { - if (synth.playMsg(message, timestamp)) return; - } - else { - if (synth.playMsg(message)) return; - } - } while (synth.reportHandler->onMIDIQueueOverflow()); -} - -void DefaultMidiStreamParser::handleSysex(const Bit8u *stream, const Bit32u length) { - do { - if (timestampSet) { - if (synth.playSysex(stream, length, timestamp)) return; - } - else { - if (synth.playSysex(stream, length)) return; - } - } while (synth.reportHandler->onMIDIQueueOverflow()); -} - -void DefaultMidiStreamParser::handleSystemRealtimeMessage(const Bit8u realtime) { - synth.reportHandler->onMIDISystemRealtime(realtime); -} - -void DefaultMidiStreamParser::printDebug(const char *debugMessage) { - synth.printDebug("%s", debugMessage); -} - -MidiStreamParser::MidiStreamParser(Bit32u initialStreamBufferCapacity) : - MidiStreamParserImpl(*this, *this, initialStreamBufferCapacity) {} - -MidiStreamParserImpl::MidiStreamParserImpl(MidiReceiver &useReceiver, MidiReporter &useReporter, Bit32u initialStreamBufferCapacity) : - midiReceiver(useReceiver), midiReporter(useReporter) -{ - if (initialStreamBufferCapacity < SYSEX_BUFFER_SIZE) initialStreamBufferCapacity = SYSEX_BUFFER_SIZE; - if (MAX_STREAM_BUFFER_SIZE < initialStreamBufferCapacity) initialStreamBufferCapacity = MAX_STREAM_BUFFER_SIZE; - streamBufferCapacity = initialStreamBufferCapacity; - streamBuffer = new Bit8u[streamBufferCapacity]; - streamBufferSize = 0; - runningStatus = 0; - - reserved = NULL; -} - -MidiStreamParserImpl::~MidiStreamParserImpl() { - delete[] streamBuffer; -} - -void MidiStreamParserImpl::parseStream(const Bit8u *stream, Bit32u length) { - while (length > 0) { - Bit32u parsedMessageLength = 0; - if (0xF8 <= *stream) { - // Process System Realtime immediately and go on - midiReceiver.handleSystemRealtimeMessage(*stream); - parsedMessageLength = 1; - // No effect on the running status - } else if (streamBufferSize > 0) { - // Check if there is something in streamBuffer waiting for being processed - if (*streamBuffer == 0xF0) { - parsedMessageLength = parseSysexFragment(stream, length); - } else { - parsedMessageLength = parseShortMessageDataBytes(stream, length); - } - } else { - if (*stream == 0xF0) { - runningStatus = 0; // SysEx clears the running status - parsedMessageLength = parseSysex(stream, length); - } else { - parsedMessageLength = parseShortMessageStatus(stream); - } - } - - // Parsed successfully - stream += parsedMessageLength; - length -= parsedMessageLength; - } -} - -void MidiStreamParserImpl::processShortMessage(const Bit32u message) { - // Adds running status to the MIDI message if it doesn't contain one - Bit8u status = Bit8u(message & 0xFF); - if (0xF8 <= status) { - midiReceiver.handleSystemRealtimeMessage(status); - } else if (processStatusByte(status)) { - midiReceiver.handleShortMessage((message << 8) | status); - } else if (0x80 <= status) { // If no running status available yet, skip this message - midiReceiver.handleShortMessage(message); - } -} - -// We deal with SysEx messages below 512 bytes long in most cases. Nevertheless, it seems reasonable to support a possibility -// to load bulk dumps using a single message. However, this is known to fail with a real device due to limited input buffer size. -bool MidiStreamParserImpl::checkStreamBufferCapacity(const bool preserveContent) { - if (streamBufferSize < streamBufferCapacity) return true; - if (streamBufferCapacity < MAX_STREAM_BUFFER_SIZE) { - Bit8u *oldStreamBuffer = streamBuffer; - streamBufferCapacity = MAX_STREAM_BUFFER_SIZE; - streamBuffer = new Bit8u[streamBufferCapacity]; - if (preserveContent) memcpy(streamBuffer, oldStreamBuffer, streamBufferSize); - delete[] oldStreamBuffer; - return true; - } - return false; -} - -// Checks input byte whether it is a status byte. If not, replaces it with running status when available. -// Returns true if the input byte was changed to running status. -bool MidiStreamParserImpl::processStatusByte(Bit8u &status) { - if (status < 0x80) { - // First byte isn't status, try running status - if (runningStatus < 0x80) { - // No running status available yet - midiReporter.printDebug("processStatusByte: No valid running status yet, MIDI message ignored"); - return false; - } - status = runningStatus; - return true; - } else if (status < 0xF0) { - // Store current status as running for a Voice message - runningStatus = status; - } else if (status < 0xF8) { - // System Common clears running status - runningStatus = 0; - } // System Realtime doesn't affect running status - return false; -} - -// Returns # of bytes parsed -Bit32u MidiStreamParserImpl::parseShortMessageStatus(const Bit8u stream[]) { - Bit8u status = *stream; - Bit32u parsedLength = processStatusByte(status) ? 0 : 1; - if (0x80 <= status) { // If no running status available yet, skip one byte - *streamBuffer = status; - ++streamBufferSize; - } - return parsedLength; -} - -// Returns # of bytes parsed -Bit32u MidiStreamParserImpl::parseShortMessageDataBytes(const Bit8u stream[], Bit32u length) { - const Bit32u shortMessageLength = Synth::getShortMessageLength(*streamBuffer); - Bit32u parsedLength = 0; - - // Append incoming bytes to streamBuffer - while ((streamBufferSize < shortMessageLength) && (length-- > 0)) { - Bit8u dataByte = *(stream++); - if (dataByte < 0x80) { - // Add data byte to streamBuffer - streamBuffer[streamBufferSize++] = dataByte; - } else if (dataByte < 0xF8) { - // Discard invalid bytes and start over - char s[128]; - sprintf(s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); - midiReporter.printDebug(s); - streamBufferSize = 0; // Clear streamBuffer - return parsedLength; - } else { - // Bypass System Realtime message - midiReceiver.handleSystemRealtimeMessage(dataByte); - } - ++parsedLength; - } - if (streamBufferSize < shortMessageLength) return parsedLength; // Still lacks data bytes - - // Assemble short message - Bit32u shortMessage = streamBuffer[0]; - for (Bit32u i = 1; i < shortMessageLength; ++i) { - shortMessage |= streamBuffer[i] << (i << 3); - } - midiReceiver.handleShortMessage(shortMessage); - streamBufferSize = 0; // Clear streamBuffer - return parsedLength; -} - -// Returns # of bytes parsed -Bit32u MidiStreamParserImpl::parseSysex(const Bit8u stream[], const Bit32u length) { - // Find SysEx length - Bit32u sysexLength = 1; - while (sysexLength < length) { - Bit8u nextByte = stream[sysexLength++]; - if (0x80 <= nextByte) { - if (nextByte == 0xF7) { - // End of SysEx - midiReceiver.handleSysex(stream, sysexLength); - return sysexLength; - } - if (0xF8 <= nextByte) { - // The System Realtime message must be processed right after return - // but the SysEx is actually fragmented and to be reconstructed in streamBuffer - --sysexLength; - break; - } - // Illegal status byte in SysEx message, aborting - midiReporter.printDebug("parseSysex: SysEx message lacks end-of-sysex (0xf7), ignored"); - // Continue parsing from that point - return sysexLength - 1; - } - } - - // Store incomplete SysEx message for further processing - streamBufferSize = sysexLength; - if (checkStreamBufferCapacity(false)) { - memcpy(streamBuffer, stream, sysexLength); - } else { - // Not enough buffer capacity, don't care about the real buffer content, just mark the first byte - *streamBuffer = *stream; - streamBufferSize = streamBufferCapacity; - } - return sysexLength; -} - -// Returns # of bytes parsed -Bit32u MidiStreamParserImpl::parseSysexFragment(const Bit8u stream[], const Bit32u length) { - Bit32u parsedLength = 0; - while (parsedLength < length) { - Bit8u nextByte = stream[parsedLength++]; - if (nextByte < 0x80) { - // Add SysEx data byte to streamBuffer - if (checkStreamBufferCapacity(true)) streamBuffer[streamBufferSize++] = nextByte; - continue; - } - if (0xF8 <= nextByte) { - // Bypass System Realtime message - midiReceiver.handleSystemRealtimeMessage(nextByte); - continue; - } - if (nextByte != 0xF7) { - // Illegal status byte in SysEx message, aborting - midiReporter.printDebug("parseSysexFragment: SysEx message lacks end-of-sysex (0xf7), ignored"); - // Clear streamBuffer and continue parsing from that point - streamBufferSize = 0; - --parsedLength; - break; - } - // End of SysEx - if (checkStreamBufferCapacity(true)) { - streamBuffer[streamBufferSize++] = nextByte; - midiReceiver.handleSysex(streamBuffer, streamBufferSize); - streamBufferSize = 0; // Clear streamBuffer - break; - } - // Encountered streamBuffer overrun - midiReporter.printDebug("parseSysexFragment: streamBuffer overrun while receiving SysEx message, ignored. Max allowed size of fragmented SysEx is 32768 bytes."); - streamBufferSize = 0; // Clear streamBuffer - break; - } - return parsedLength; -} diff --git a/src - Cópia/sound/munt/MidiStreamParser.h b/src - Cópia/sound/munt/MidiStreamParser.h deleted file mode 100644 index 881ec032f..000000000 --- a/src - Cópia/sound/munt/MidiStreamParser.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_MIDI_STREAM_PARSER_H -#define MT32EMU_MIDI_STREAM_PARSER_H - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -class Synth; - -// Interface for a user-supplied class to receive parsed well-formed MIDI messages. -class MT32EMU_EXPORT MidiReceiver { -public: - // Invoked when a complete short MIDI message is parsed in the input MIDI stream. - virtual void handleShortMessage(const Bit32u message) = 0; - - // Invoked when a complete well-formed System Exclusive MIDI message is parsed in the input MIDI stream. - virtual void handleSysex(const Bit8u stream[], const Bit32u length) = 0; - - // Invoked when a System Realtime MIDI message is parsed in the input MIDI stream. - virtual void handleSystemRealtimeMessage(const Bit8u realtime) = 0; - -protected: - ~MidiReceiver() {} -}; - -// Interface for a user-supplied class to receive notifications of input MIDI stream parse errors. -class MT32EMU_EXPORT MidiReporter { -public: - // Invoked when an error occurs during processing the input MIDI stream. - virtual void printDebug(const char *debugMessage) = 0; - -protected: - ~MidiReporter() {} -}; - -// Provides a context for parsing a stream of MIDI events coming from a single source. -// There can be multiple MIDI sources feeding MIDI events to a single Synth object. -// NOTE: Calls from multiple threads which feed a single Synth object with data must be explicitly synchronised, -// although, no synchronisation is required with the rendering thread. -class MT32EMU_EXPORT MidiStreamParserImpl { -public: - // The first two arguments provide for implementations of essential interfaces needed. - // The third argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected. - // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes). - // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use. - MidiStreamParserImpl(MidiReceiver &, MidiReporter &, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); - virtual ~MidiStreamParserImpl(); - - // Parses a block of raw MIDI bytes. All the parsed MIDI messages are sent in sequence to the user-supplied methods for further processing. - // SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. - // NOTE: the total length of a SysEx message being fragmented shall not exceed MAX_STREAM_BUFFER_SIZE (32768 bytes). - void parseStream(const Bit8u *stream, Bit32u length); - - // Convenience method which accepts a Bit32u-encoded short MIDI message and sends it to the user-supplied method for further processing. - // The short MIDI message may contain no status byte, the running status is used in this case. - void processShortMessage(const Bit32u message); - -private: - Bit8u runningStatus; - Bit8u *streamBuffer; - Bit32u streamBufferCapacity; - Bit32u streamBufferSize; - MidiReceiver &midiReceiver; - MidiReporter &midiReporter; - - // Binary compatibility helper. - void *reserved; - - bool checkStreamBufferCapacity(const bool preserveContent); - bool processStatusByte(Bit8u &status); - Bit32u parseShortMessageStatus(const Bit8u stream[]); - Bit32u parseShortMessageDataBytes(const Bit8u stream[], Bit32u length); - Bit32u parseSysex(const Bit8u stream[], const Bit32u length); - Bit32u parseSysexFragment(const Bit8u stream[], const Bit32u length); -}; // class MidiStreamParserImpl - -// An abstract class that provides a context for parsing a stream of MIDI events coming from a single source. -class MT32EMU_EXPORT MidiStreamParser : public MidiStreamParserImpl, protected MidiReceiver, protected MidiReporter { -public: - // The argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected. - // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes). - // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use. - explicit MidiStreamParser(Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); -}; - -class MT32EMU_EXPORT DefaultMidiStreamParser : public MidiStreamParser { -public: - explicit DefaultMidiStreamParser(Synth &synth, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); - void setTimestamp(const Bit32u useTimestamp); - void resetTimestamp(); - -protected: - void handleShortMessage(const Bit32u message); - void handleSysex(const Bit8u *stream, const Bit32u length); - void handleSystemRealtimeMessage(const Bit8u realtime); - void printDebug(const char *debugMessage); - -private: - Synth &synth; - bool timestampSet; - Bit32u timestamp; -}; - -} // namespace MT32Emu - -#endif // MT32EMU_MIDI_STREAM_PARSER_H diff --git a/src - Cópia/sound/munt/Part.cpp b/src - Cópia/sound/munt/Part.cpp deleted file mode 100644 index 9c85ce559..000000000 --- a/src - Cópia/sound/munt/Part.cpp +++ /dev/null @@ -1,702 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "internals.h" - -#include "Part.h" -#include "Partial.h" -#include "PartialManager.h" -#include "Poly.h" -#include "Synth.h" - -namespace MT32Emu { - -static const Bit8u PartialStruct[13] = { - 0, 0, 2, 2, 1, 3, - 3, 0, 3, 0, 2, 1, 3 -}; - -static const Bit8u PartialMixStruct[13] = { - 0, 1, 0, 1, 1, 0, - 1, 3, 3, 2, 2, 2, 2 -}; - -RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) { - strcpy(name, "Rhythm"); - rhythmTemp = &synth->mt32ram.rhythmTemp[0]; - refresh(); -} - -Part::Part(Synth *useSynth, unsigned int usePartNum) { - synth = useSynth; - partNum = usePartNum; - patchCache[0].dirty = true; - holdpedal = false; - patchTemp = &synth->mt32ram.patchTemp[partNum]; - if (usePartNum == 8) { - // Nasty hack for rhythm - timbreTemp = NULL; - } else { - sprintf(name, "Part %d", partNum + 1); - timbreTemp = &synth->mt32ram.timbreTemp[partNum]; - } - currentInstr[0] = 0; - currentInstr[10] = 0; - modulation = 0; - expression = 100; - pitchBend = 0; - activePartialCount = 0; - memset(patchCache, 0, sizeof(patchCache)); -} - -Part::~Part() { - while (!activePolys.isEmpty()) { - delete activePolys.takeFirst(); - } -} - -void Part::setDataEntryMSB(unsigned char midiDataEntryMSB) { - if (nrpn) { - // The last RPN-related control change was for an NRPN, - // which the real synths don't support. - return; - } - if (rpn != 0) { - // The RPN has been set to something other than 0, - // which is the only RPN that these synths support - return; - } - patchTemp->patch.benderRange = midiDataEntryMSB > 24 ? 24 : midiDataEntryMSB; - updatePitchBenderRange(); -} - -void Part::setNRPN() { - nrpn = true; -} - -void Part::setRPNLSB(unsigned char midiRPNLSB) { - nrpn = false; - rpn = (rpn & 0xFF00) | midiRPNLSB; -} - -void Part::setRPNMSB(unsigned char midiRPNMSB) { - nrpn = false; - rpn = (rpn & 0x00FF) | (midiRPNMSB << 8); -} - -void Part::setHoldPedal(bool pressed) { - if (holdpedal && !pressed) { - holdpedal = false; - stopPedalHold(); - } else { - holdpedal = pressed; - } -} - -Bit32s Part::getPitchBend() const { - return pitchBend; -} - -void Part::setBend(unsigned int midiBend) { - // CONFIRMED: - pitchBend = ((signed(midiBend) - 8192) * pitchBenderRange) >> 14; // PORTABILITY NOTE: Assumes arithmetic shift -} - -Bit8u Part::getModulation() const { - return modulation; -} - -void Part::setModulation(unsigned int midiModulation) { - modulation = Bit8u(midiModulation); -} - -void Part::resetAllControllers() { - modulation = 0; - expression = 100; - pitchBend = 0; - setHoldPedal(false); -} - -void Part::reset() { - resetAllControllers(); - allSoundOff(); - rpn = 0xFFFF; -} - -void RhythmPart::refresh() { - // (Re-)cache all the mapped timbres ahead of time - for (unsigned int drumNum = 0; drumNum < synth->controlROMMap->rhythmSettingsCount; drumNum++) { - int drumTimbreNum = rhythmTemp[drumNum].timbre; - if (drumTimbreNum >= 127) { // 94 on MT-32 - continue; - } - PatchCache *cache = drumCache[drumNum]; - backupCacheToPartials(cache); - for (int t = 0; t < 4; t++) { - // Common parameters, stored redundantly - cache[t].dirty = true; - cache[t].reverb = rhythmTemp[drumNum].reverbSwitch > 0; - } - } - updatePitchBenderRange(); -} - -void Part::refresh() { - backupCacheToPartials(patchCache); - for (int t = 0; t < 4; t++) { - // Common parameters, stored redundantly - patchCache[t].dirty = true; - patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0; - } - memcpy(currentInstr, timbreTemp->common.name, 10); - synth->newTimbreSet(partNum, patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, currentInstr); - updatePitchBenderRange(); -} - -const char *Part::getCurrentInstr() const { - return ¤tInstr[0]; -} - -void RhythmPart::refreshTimbre(unsigned int absTimbreNum) { - for (int m = 0; m < 85; m++) { - if (rhythmTemp[m].timbre == absTimbreNum - 128) { - drumCache[m][0].dirty = true; - } - } -} - -void Part::refreshTimbre(unsigned int absTimbreNum) { - if (getAbsTimbreNum() == absTimbreNum) { - memcpy(currentInstr, timbreTemp->common.name, 10); - patchCache[0].dirty = true; - } -} - -void Part::setPatch(const PatchParam *patch) { - patchTemp->patch = *patch; -} - -void RhythmPart::setTimbre(TimbreParam * /*timbre*/) { - synth->printDebug("%s: Attempted to call setTimbre() - doesn't make sense for rhythm", name); -} - -void Part::setTimbre(TimbreParam *timbre) { - *timbreTemp = *timbre; -} - -unsigned int RhythmPart::getAbsTimbreNum() const { - synth->printDebug("%s: Attempted to call getAbsTimbreNum() - doesn't make sense for rhythm", name); - return 0; -} - -unsigned int Part::getAbsTimbreNum() const { - return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum; -} - -#if MT32EMU_MONITOR_MIDI > 0 -void RhythmPart::setProgram(unsigned int patchNum) { - synth->printDebug("%s: Attempt to set program (%d) on rhythm is invalid", name, patchNum); -} -#else -void RhythmPart::setProgram(unsigned int) { } -#endif - -void Part::setProgram(unsigned int patchNum) { - setPatch(&synth->mt32ram.patches[patchNum]); - holdpedal = false; - allSoundOff(); - setTimbre(&synth->mt32ram.timbres[getAbsTimbreNum()].timbre); - refresh(); -} - -void Part::updatePitchBenderRange() { - pitchBenderRange = patchTemp->patch.benderRange * 683; -} - -void Part::backupCacheToPartials(PatchCache cache[4]) { - // check if any partials are still playing with the old patch cache - // if so then duplicate the cached data from the part to the partial so that - // we can change the part's cache without affecting the partial. - // We delay this until now to avoid a copy operation with every note played - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - poly->backupCacheToPartials(cache); - } -} - -void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) { - backupCacheToPartials(cache); - int partialCount = 0; - for (int t = 0; t < 4; t++) { - if (((timbre->common.partialMute >> t) & 0x1) == 1) { - cache[t].playPartial = true; - partialCount++; - } else { - cache[t].playPartial = false; - continue; - } - - // Calculate and cache common parameters - cache[t].srcPartial = timbre->partial[t]; - - cache[t].pcm = timbre->partial[t].wg.pcmWave; - - switch (t) { - case 0: - cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure12)] & 0x2) ? true : false; - cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure12)]; - cache[t].structurePosition = 0; - cache[t].structurePair = 1; - break; - case 1: - cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure12)] & 0x1) ? true : false; - cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure12)]; - cache[t].structurePosition = 1; - cache[t].structurePair = 0; - break; - case 2: - cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure34)] & 0x2) ? true : false; - cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure34)]; - cache[t].structurePosition = 0; - cache[t].structurePair = 3; - break; - case 3: - cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure34)] & 0x1) ? true : false; - cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure34)]; - cache[t].structurePosition = 1; - cache[t].structurePair = 2; - break; - default: - break; - } - - cache[t].partialParam = &timbre->partial[t]; - - cache[t].waveform = timbre->partial[t].wg.waveform; - } - for (int t = 0; t < 4; t++) { - // Common parameters, stored redundantly - cache[t].dirty = false; - cache[t].partialCount = partialCount; - cache[t].sustain = (timbre->common.noSustain == 0); - } - //synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", cache[0].waveform, cache[1].waveform, cache[2].waveform, cache[3].waveform); - -#if MT32EMU_MONITOR_INSTRUMENTS > 0 - synth->printDebug("%s (%s): Recached timbre", name, currentInstr); - for (int i = 0; i < 4; i++) { - synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, cache[i].playPartial ? "YES" : "NO", cache[i].PCMPartial ? "YES" : "NO", timbre->partial[i].wg.pcmWave, timbre->partial[i].wg.waveform); - } -#endif -} - -const char *Part::getName() const { - return name; -} - -void Part::setVolume(unsigned int midiVolume) { - // CONFIRMED: This calculation matches the table used in the control ROM - patchTemp->outputLevel = Bit8u(midiVolume * 100 / 127); - //synth->printDebug("%s (%s): Set volume to %d", name, currentInstr, midiVolume); -} - -Bit8u Part::getVolume() const { - return patchTemp->outputLevel; -} - -Bit8u Part::getExpression() const { - return expression; -} - -void Part::setExpression(unsigned int midiExpression) { - // CONFIRMED: This calculation matches the table used in the control ROM - expression = Bit8u(midiExpression * 100 / 127); -} - -void RhythmPart::setPan(unsigned int midiPan) { - // CONFIRMED: This does change patchTemp, but has no actual effect on playback. -#if MT32EMU_MONITOR_MIDI > 0 - synth->printDebug("%s: Pointlessly setting pan (%d) on rhythm part", name, midiPan); -#endif - Part::setPan(midiPan); -} - -void Part::setPan(unsigned int midiPan) { - // NOTE: Panning is inverted compared to GM. - - if (synth->controlROMFeatures->quirkPanMult) { - // MT-32: Divide by 9 - patchTemp->panpot = Bit8u(midiPan / 9); - } else { - // CM-32L: Divide by 8.5 - patchTemp->panpot = Bit8u((midiPan << 3) / 68); - } - - //synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot); -} - -/** - * Applies key shift to a MIDI key and converts it into an internal key value in the range 12-108. - */ -unsigned int Part::midiKeyToKey(unsigned int midiKey) { - if (synth->controlROMFeatures->quirkKeyShift) { - // NOTE: On MT-32 GEN0, key isn't adjusted, and keyShift is applied further in TVP, unlike newer units: - return midiKey; - } - int key = midiKey + patchTemp->patch.keyShift; - if (key < 36) { - // After keyShift is applied, key < 36, so move up by octaves - while (key < 36) { - key += 12; - } - } else if (key > 132) { - // After keyShift is applied, key > 132, so move down by octaves - while (key > 132) { - key -= 12; - } - } - key -= 24; - return key; -} - -void RhythmPart::noteOn(unsigned int midiKey, unsigned int velocity) { - if (midiKey < 24 || midiKey > 108) { /*> 87 on MT-32)*/ - synth->printDebug("%s: Attempted to play invalid key %d (velocity %d)", name, midiKey, velocity); - return; - } - unsigned int key = midiKey; - unsigned int drumNum = key - 24; - int drumTimbreNum = rhythmTemp[drumNum].timbre; - const int drumTimbreCount = 64 + synth->controlROMMap->timbreRCount; // 94 on MT-32, 128 on LAPC-I/CM32-L - if (drumTimbreNum == 127 || drumTimbreNum >= drumTimbreCount) { // timbre #127 is OFF, no sense to play it - synth->printDebug("%s: Attempted to play unmapped key %d (velocity %d)", name, midiKey, velocity); - return; - } - // CONFIRMED: Two special cases described by Mok - if (drumTimbreNum == 64 + 6) { - noteOff(0); - key = 1; - } else if (drumTimbreNum == 64 + 7) { - // This noteOff(0) is not performed on MT-32, only LAPC-I - noteOff(0); - key = 0; - } - int absTimbreNum = drumTimbreNum + 128; - TimbreParam *timbre = &synth->mt32ram.timbres[absTimbreNum].timbre; - memcpy(currentInstr, timbre->common.name, 10); - if (drumCache[drumNum][0].dirty) { - cacheTimbre(drumCache[drumNum], timbre); - } -#if MT32EMU_MONITOR_INSTRUMENTS > 0 - synth->printDebug("%s (%s): Start poly (drum %d, timbre %d): midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, drumNum, absTimbreNum, midiKey, key, velocity, modulation, expression, pitchBend); -#if MT32EMU_MONITOR_INSTRUMENTS > 1 - // According to info from Mok, keyShift does not appear to affect anything on rhythm part on LAPC-I, but may do on MT-32 - needs investigation - synth->printDebug(" Patch: (timbreGroup %u), (timbreNum %u), (keyShift %u), fineTune %u, benderRange %u, assignMode %u, (reverbSwitch %u)", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch); - synth->printDebug(" PatchTemp: outputLevel %u, (panpot %u)", patchTemp->outputLevel, patchTemp->panpot); - synth->printDebug(" RhythmTemp: timbre %u, outputLevel %u, panpot %u, reverbSwitch %u", rhythmTemp[drumNum].timbre, rhythmTemp[drumNum].outputLevel, rhythmTemp[drumNum].panpot, rhythmTemp[drumNum].reverbSwitch); -#endif -#endif - playPoly(drumCache[drumNum], &rhythmTemp[drumNum], midiKey, key, velocity); -} - -void Part::noteOn(unsigned int midiKey, unsigned int velocity) { - unsigned int key = midiKeyToKey(midiKey); - if (patchCache[0].dirty) { - cacheTimbre(patchCache, timbreTemp); - } -#if MT32EMU_MONITOR_INSTRUMENTS > 0 - synth->printDebug("%s (%s): Start poly: midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, midiKey, key, velocity, modulation, expression, pitchBend); -#if MT32EMU_MONITOR_INSTRUMENTS > 1 - synth->printDebug(" Patch: timbreGroup %u, timbreNum %u, keyShift %u, fineTune %u, benderRange %u, assignMode %u, reverbSwitch %u", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch); - synth->printDebug(" PatchTemp: outputLevel %u, panpot %u", patchTemp->outputLevel, patchTemp->panpot); -#endif -#endif - playPoly(patchCache, NULL, midiKey, key, velocity); -} - -bool Part::abortFirstPoly(unsigned int key) { - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - if (poly->getKey() == key) { - return poly->startAbort(); - } - } - return false; -} - -bool Part::abortFirstPoly(PolyState polyState) { - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - if (poly->getState() == polyState) { - return poly->startAbort(); - } - } - return false; -} - -bool Part::abortFirstPolyPreferHeld() { - if (abortFirstPoly(POLY_Held)) { - return true; - } - return abortFirstPoly(); -} - -bool Part::abortFirstPoly() { - if (activePolys.isEmpty()) { - return false; - } - return activePolys.getFirst()->startAbort(); -} - -void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity) { - // CONFIRMED: Even in single-assign mode, we don't abort playing polys if the timbre to play is completely muted. - unsigned int needPartials = cache[0].partialCount; - if (needPartials == 0) { - synth->printDebug("%s (%s): Completely muted instrument", name, currentInstr); - return; - } - - if ((patchTemp->patch.assignMode & 2) == 0) { - // Single-assign mode - abortFirstPoly(key); - if (synth->isAbortingPoly()) return; - } - - if (!synth->partialManager->freePartials(needPartials, partNum)) { -#if MT32EMU_MONITOR_PARTIALS > 0 - synth->printDebug("%s (%s): Insufficient free partials to play key %d (velocity %d); needed=%d, free=%d, assignMode=%d", name, currentInstr, midiKey, velocity, needPartials, synth->partialManager->getFreePartialCount(), patchTemp->patch.assignMode); - synth->printPartialUsage(); -#endif - return; - } - if (synth->isAbortingPoly()) return; - - Poly *poly = synth->partialManager->assignPolyToPart(this); - if (poly == NULL) { - synth->printDebug("%s (%s): No free poly to play key %d (velocity %d)", name, currentInstr, midiKey, velocity); - return; - } - if (patchTemp->patch.assignMode & 1) { - // Priority to data first received - activePolys.prepend(poly); - } else { - activePolys.append(poly); - } - - Partial *partials[4]; - for (int x = 0; x < 4; x++) { - if (cache[x].playPartial) { - partials[x] = synth->partialManager->allocPartial(partNum); - activePartialCount++; - } else { - partials[x] = NULL; - } - } - poly->reset(key, velocity, cache[0].sustain, partials); - - for (int x = 0; x < 4; x++) { - if (partials[x] != NULL) { -#if MT32EMU_MONITOR_PARTIALS > 2 - synth->printDebug("%s (%s): Allocated partial %d", name, currentInstr, partials[x]->debugGetPartialNum()); -#endif - partials[x]->startPartial(this, poly, &cache[x], rhythmTemp, partials[cache[x].structurePair]); - } - } -#if MT32EMU_MONITOR_PARTIALS > 1 - synth->printPartialUsage(); -#endif - synth->reportHandler->onPolyStateChanged(Bit8u(partNum)); -} - -void Part::allNotesOff() { - // The MIDI specification states - and Mok confirms - that all notes off (0x7B) - // should treat the hold pedal as usual. - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - // FIXME: This has special handling of key 0 in NoteOff that Mok has not yet confirmed applies to AllNotesOff. - // if (poly->canSustain() || poly->getKey() == 0) { - // FIXME: The real devices are found to be ignoring non-sustaining polys while processing AllNotesOff. Need to be confirmed. - if (poly->canSustain()) { - poly->noteOff(holdpedal); - } - } -} - -void Part::allSoundOff() { - // MIDI "All sound off" (0x78) should release notes immediately regardless of the hold pedal. - // This controller is not actually implemented by the synths, though (according to the docs and Mok) - - // we're only using this method internally. - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - poly->startDecay(); - } -} - -void Part::stopPedalHold() { - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - poly->stopPedalHold(); - } -} - -void RhythmPart::noteOff(unsigned int midiKey) { - stopNote(midiKey); -} - -void Part::noteOff(unsigned int midiKey) { - stopNote(midiKeyToKey(midiKey)); -} - -void Part::stopNote(unsigned int key) { -#if MT32EMU_MONITOR_INSTRUMENTS > 0 - synth->printDebug("%s (%s): stopping key %d", name, currentInstr, key); -#endif - - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - // Generally, non-sustaining instruments ignore note off. They die away eventually anyway. - // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held. - if (poly->getKey() == key && (poly->canSustain() || key == 0)) { - if (poly->noteOff(holdpedal && key != 0)) { - break; - } - } - } -} - -const MemParams::PatchTemp *Part::getPatchTemp() const { - return patchTemp; -} - -unsigned int Part::getActivePartialCount() const { - return activePartialCount; -} - -const Poly *Part::getFirstActivePoly() const { - return activePolys.getFirst(); -} - -unsigned int Part::getActiveNonReleasingPartialCount() const { - unsigned int activeNonReleasingPartialCount = 0; - for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { - if (poly->getState() != POLY_Releasing) { - activeNonReleasingPartialCount += poly->getActivePartialCount(); - } - } - return activeNonReleasingPartialCount; -} - -Synth *Part::getSynth() const { - return synth; -} - -void Part::partialDeactivated(Poly *poly) { - activePartialCount--; - if (!poly->isActive()) { - activePolys.remove(poly); - synth->partialManager->polyFreed(poly); - synth->reportHandler->onPolyStateChanged(Bit8u(partNum)); - } -} - -PolyList::PolyList() : firstPoly(NULL), lastPoly(NULL) {} - -bool PolyList::isEmpty() const { -#ifdef MT32EMU_POLY_LIST_DEBUG - if ((firstPoly == NULL || lastPoly == NULL) && firstPoly != lastPoly) { - printf("PolyList: desynchronised firstPoly & lastPoly pointers\n"); - } -#endif - return firstPoly == NULL && lastPoly == NULL; -} - -Poly *PolyList::getFirst() const { - return firstPoly; -} - -Poly *PolyList::getLast() const { - return lastPoly; -} - -void PolyList::prepend(Poly *poly) { -#ifdef MT32EMU_POLY_LIST_DEBUG - if (poly->getNext() != NULL) { - printf("PolyList: Non-NULL next field in a Poly being prepended is ignored\n"); - } -#endif - poly->setNext(firstPoly); - firstPoly = poly; - if (lastPoly == NULL) { - lastPoly = poly; - } -} - -void PolyList::append(Poly *poly) { -#ifdef MT32EMU_POLY_LIST_DEBUG - if (poly->getNext() != NULL) { - printf("PolyList: Non-NULL next field in a Poly being appended is ignored\n"); - } -#endif - poly->setNext(NULL); - if (lastPoly != NULL) { -#ifdef MT32EMU_POLY_LIST_DEBUG - if (lastPoly->getNext() != NULL) { - printf("PolyList: Non-NULL next field in the lastPoly\n"); - } -#endif - lastPoly->setNext(poly); - } - lastPoly = poly; - if (firstPoly == NULL) { - firstPoly = poly; - } -} - -Poly *PolyList::takeFirst() { - Poly *oldFirst = firstPoly; - firstPoly = oldFirst->getNext(); - if (firstPoly == NULL) { -#ifdef MT32EMU_POLY_LIST_DEBUG - if (lastPoly != oldFirst) { - printf("PolyList: firstPoly != lastPoly in a list with a single Poly\n"); - } -#endif - lastPoly = NULL; - } - oldFirst->setNext(NULL); - return oldFirst; -} - -void PolyList::remove(Poly * const polyToRemove) { - if (polyToRemove == firstPoly) { - takeFirst(); - return; - } - for (Poly *poly = firstPoly; poly != NULL; poly = poly->getNext()) { - if (poly->getNext() == polyToRemove) { - if (polyToRemove == lastPoly) { -#ifdef MT32EMU_POLY_LIST_DEBUG - if (lastPoly->getNext() != NULL) { - printf("PolyList: Non-NULL next field in the lastPoly\n"); - } -#endif - lastPoly = poly; - } - poly->setNext(polyToRemove->getNext()); - polyToRemove->setNext(NULL); - break; - } - } -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Part.h b/src - Cópia/sound/munt/Part.h deleted file mode 100644 index a4de1060b..000000000 --- a/src - Cópia/sound/munt/Part.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_PART_H -#define MT32EMU_PART_H - -#include "globals.h" -#include "internals.h" -#include "Types.h" -#include "Structures.h" - -namespace MT32Emu { - -class Poly; -class Synth; - -class PolyList { -private: - Poly *firstPoly; - Poly *lastPoly; - -public: - PolyList(); - bool isEmpty() const; - Poly *getFirst() const; - Poly *getLast() const; - void prepend(Poly *poly); - void append(Poly *poly); - Poly *takeFirst(); - void remove(Poly * const poly); -}; - -class Part { -private: - // Direct pointer to sysex-addressable memory dedicated to this part (valid for parts 1-8, NULL for rhythm) - TimbreParam *timbreTemp; - - // 0=Part 1, .. 7=Part 8, 8=Rhythm - unsigned int partNum; - - bool holdpedal; - - unsigned int activePartialCount; - PatchCache patchCache[4]; - PolyList activePolys; - - void setPatch(const PatchParam *patch); - unsigned int midiKeyToKey(unsigned int midiKey); - - bool abortFirstPoly(unsigned int key); - -protected: - Synth *synth; - // Direct pointer into sysex-addressable memory - MemParams::PatchTemp *patchTemp; - char name[8]; // "Part 1".."Part 8", "Rhythm" - char currentInstr[11]; - Bit8u modulation; - Bit8u expression; - Bit32s pitchBend; - bool nrpn; - Bit16u rpn; - Bit16u pitchBenderRange; // (patchTemp->patch.benderRange * 683) at the time of the last MIDI program change or MIDI data entry. - - void backupCacheToPartials(PatchCache cache[4]); - void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre); - void playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity); - void stopNote(unsigned int key); - const char *getName() const; - -public: - Part(Synth *synth, unsigned int usePartNum); - virtual ~Part(); - void reset(); - void setDataEntryMSB(unsigned char midiDataEntryMSB); - void setNRPN(); - void setRPNLSB(unsigned char midiRPNLSB); - void setRPNMSB(unsigned char midiRPNMSB); - void resetAllControllers(); - virtual void noteOn(unsigned int midiKey, unsigned int velocity); - virtual void noteOff(unsigned int midiKey); - void allNotesOff(); - void allSoundOff(); - Bit8u getVolume() const; // Internal volume, 0-100, exposed for use by ExternalInterface - void setVolume(unsigned int midiVolume); - Bit8u getModulation() const; - void setModulation(unsigned int midiModulation); - Bit8u getExpression() const; - void setExpression(unsigned int midiExpression); - virtual void setPan(unsigned int midiPan); - Bit32s getPitchBend() const; - void setBend(unsigned int midiBend); - virtual void setProgram(unsigned int midiProgram); - void setHoldPedal(bool pedalval); - void stopPedalHold(); - void updatePitchBenderRange(); - virtual void refresh(); - virtual void refreshTimbre(unsigned int absTimbreNum); - virtual void setTimbre(TimbreParam *timbre); - virtual unsigned int getAbsTimbreNum() const; - const char *getCurrentInstr() const; - const Poly *getFirstActivePoly() const; - unsigned int getActivePartialCount() const; - unsigned int getActiveNonReleasingPartialCount() const; - Synth *getSynth() const; - - const MemParams::PatchTemp *getPatchTemp() const; - - // This should only be called by Poly - void partialDeactivated(Poly *poly); - - // These are rather specialised, and should probably only be used by PartialManager - bool abortFirstPoly(PolyState polyState); - // Abort the first poly in PolyState_HELD, or if none exists, the first active poly in any state. - bool abortFirstPolyPreferHeld(); - bool abortFirstPoly(); -}; // class Part - -class RhythmPart: public Part { - // Pointer to the area of the MT-32's memory dedicated to rhythm - const MemParams::RhythmTemp *rhythmTemp; - - // This caches the timbres/settings in use by the rhythm part - PatchCache drumCache[85][4]; -public: - RhythmPart(Synth *synth, unsigned int usePartNum); - void refresh(); - void refreshTimbre(unsigned int timbreNum); - void setTimbre(TimbreParam *timbre); - void noteOn(unsigned int key, unsigned int velocity); - void noteOff(unsigned int midiKey); - unsigned int getAbsTimbreNum() const; - void setPan(unsigned int midiPan); - void setProgram(unsigned int patchNum); -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_PART_H diff --git a/src - Cópia/sound/munt/Partial.cpp b/src - Cópia/sound/munt/Partial.cpp deleted file mode 100644 index 0b7231122..000000000 --- a/src - Cópia/sound/munt/Partial.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "Partial.h" -#include "Part.h" -#include "Poly.h" -#include "Synth.h" -#include "Tables.h" -#include "TVA.h" -#include "TVF.h" -#include "TVP.h" - -namespace MT32Emu { - -static const Bit8u PAN_NUMERATOR_MASTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7}; -static const Bit8u PAN_NUMERATOR_SLAVE[] = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7}; - -// We assume the pan is applied using the same 13-bit multiplier circuit that is also used for ring modulation -// because of the observed sample overflow, so the panSetting values are likely mapped in a similar way via a LUT. -// FIXME: Sample analysis suggests that the use of panSetting is linear, but there are some quirks that still need to be resolved. -static Bit32s getPANFactor(Bit32s panSetting) { - static const Bit32s PAN_FACTORS_COUNT = 15; - static Bit32s PAN_FACTORS[PAN_FACTORS_COUNT]; - static bool firstRun = true; - - if (firstRun) { - firstRun = false; - for (Bit32u i = 1; i < (Bit32u)PAN_FACTORS_COUNT; i++) { - PAN_FACTORS[i] = Bit32s(0.5 + i * 8192.0 / double(PAN_FACTORS_COUNT - 1)); - } - } - return PAN_FACTORS[panSetting]; -} - -Partial::Partial(Synth *useSynth, int useDebugPartialNum) : - synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0), - floatMode(useSynth->getSelectedRendererType() == RendererType_FLOAT) { - // Initialisation of tva, tvp and tvf uses 'this' pointer - // and thus should not be in the initializer list to avoid a compiler warning - tva = new TVA(this, &Ramp); - tvp = new TVP(this); - tvf = new TVF(this, &cutoffModifierRamp); - ownerPart = -1; - poly = NULL; - pair = NULL; - switch (synth->getSelectedRendererType()) { - case RendererType_BIT16S: - la32Pair = new LA32IntPartialPair; - break; - case RendererType_FLOAT: - la32Pair = new LA32FloatPartialPair; - break; - default: - la32Pair = NULL; - } -} - -Partial::~Partial() { - delete la32Pair; - delete tva; - delete tvp; - delete tvf; -} - -// Only used for debugging purposes -int Partial::debugGetPartialNum() const { - return debugPartialNum; -} - -// Only used for debugging purposes -Bit32u Partial::debugGetSampleNum() const { - return sampleNum; -} - -int Partial::getOwnerPart() const { - return ownerPart; -} - -bool Partial::isActive() const { - return ownerPart > -1; -} - -const Poly *Partial::getPoly() const { - return poly; -} - -void Partial::activate(int part) { - // This just marks the partial as being assigned to a part - ownerPart = part; -} - -void Partial::deactivate() { - if (!isActive()) { - return; - } - ownerPart = -1; - if (poly != NULL) { - poly->partialDeactivated(this); - } -#if MT32EMU_MONITOR_PARTIALS > 2 - synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum); - synth->printPartialUsage(sampleNum); -#endif - if (isRingModulatingSlave()) { - pair->la32Pair->deactivate(LA32PartialPair::SLAVE); - } else { - la32Pair->deactivate(LA32PartialPair::MASTER); - if (hasRingModulatingSlave()) { - pair->deactivate(); - pair = NULL; - } - } - if (pair != NULL) { - pair->pair = NULL; - } -} - -void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *usePatchCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial) { - if (usePoly == NULL || usePatchCache == NULL) { - synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", debugPartialNum, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK"); - return; - } - patchCache = usePatchCache; - poly = usePoly; - mixType = patchCache->structureMix; - structurePosition = patchCache->structurePosition; - - Bit8u panSetting = rhythmTemp != NULL ? rhythmTemp->panpot : part->getPatchTemp()->panpot; - if (mixType == 3) { - if (structurePosition == 0) { - panSetting = PAN_NUMERATOR_MASTER[panSetting] << 1; - } else { - panSetting = PAN_NUMERATOR_SLAVE[panSetting] << 1; - } - // Do a normal mix independent of any pair partial. - mixType = 0; - pairPartial = NULL; - } else { - // Mok wanted an option for smoother panning, and we love Mok. -#ifndef INACCURATE_SMOOTH_PAN - // CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32. - panSetting &= 0x0E; -#endif - } - - leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting; - rightPanValue = 14 - leftPanValue; - - if (!floatMode) { - leftPanValue = getPANFactor(leftPanValue); - rightPanValue = getPANFactor(rightPanValue); - } - - // SEMI-CONFIRMED: From sample analysis: - // Found that timbres with 3 or 4 partials (i.e. one using two partial pairs) are mixed in two different ways. - // Either partial pairs are added or subtracted, it depends on how the partial pairs are allocated. - // It seems that partials are grouped into quarters and if the partial pairs are allocated in different quarters the subtraction happens. - // Though, this matters little for the majority of timbres, it becomes crucial for timbres which contain several partials that sound very close. - // In this case that timbre can sound totally different depending of the way it is mixed up. - // Most easily this effect can be displayed with the help of a special timbre consisting of several identical square wave partials (3 or 4). - // Say, it is 3-partial timbre. Just play any two notes simultaneously and the polys very probably are mixed differently. - // Moreover, the partial allocator retains the last partial assignment it did and all the subsequent notes will sound the same as the last released one. - // The situation is better with 4-partial timbres since then a whole quarter is assigned for each poly. However, if a 3-partial timbre broke the normal - // whole-quarter assignment or after some partials got aborted, even 4-partial timbres can be found sounding differently. - // This behaviour is also confirmed with two more special timbres: one with identical sawtooth partials, and one with PCM wave 02. - // For my personal taste, this behaviour rather enriches the sounding and should be emulated. - // Also, the current partial allocator model probably needs to be refined. - if (debugPartialNum & 8) { - leftPanValue = -leftPanValue; - rightPanValue = -rightPanValue; - } - - if (patchCache->PCMPartial) { - pcmNum = patchCache->pcm; - if (synth->controlROMMap->pcmCount > 128) { - // CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter. - if (patchCache->waveform > 1) { - pcmNum += 128; - } - } - pcmWave = &synth->pcmWaves[pcmNum]; - } else { - pcmWave = NULL; - } - - // CONFIRMED: pulseWidthVal calculation is based on information from Mok - pulseWidthVal = (poly->getVelocity() - 64) * (patchCache->srcPartial.wg.pulseWidthVeloSensitivity - 7) + Tables::getInstance().pulseWidth100To255[patchCache->srcPartial.wg.pulseWidth]; - if (pulseWidthVal < 0) { - pulseWidthVal = 0; - } else if (pulseWidthVal > 255) { - pulseWidthVal = 255; - } - - pair = pairPartial; - alreadyOutputed = false; - tva->reset(part, patchCache->partialParam, rhythmTemp); - tvp->reset(part, patchCache->partialParam); - tvf->reset(patchCache->partialParam, tvp->getBasePitch()); - - LA32PartialPair::PairType pairType; - LA32PartialPair *useLA32Pair; - if (isRingModulatingSlave()) { - pairType = LA32PartialPair::SLAVE; - useLA32Pair = pair->la32Pair; - } else { - pairType = LA32PartialPair::MASTER; - la32Pair->init(hasRingModulatingSlave(), mixType == 1); - useLA32Pair = la32Pair; - } - if (isPCM()) { - useLA32Pair->initPCM(pairType, &synth->pcmROMData[pcmWave->addr], pcmWave->len, pcmWave->loop); - } else { - useLA32Pair->initSynth(pairType, (patchCache->waveform & 1) != 0, pulseWidthVal, patchCache->srcPartial.tvf.resonance + 1); - } - if (!hasRingModulatingSlave()) { - la32Pair->deactivate(LA32PartialPair::SLAVE); - } -} - -Bit32u Partial::getAmpValue() { - // SEMI-CONFIRMED: From sample analysis: - // (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc. - // This gives results within +/- 2 at the output (before any DAC bitshifting) - // when sustaining at levels 156 - 255 with no modifiers. - // (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255. - // This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces - // positive amps, so negative still needs to be explored, as well as lower levels. - // - // Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing. - // TODO: The tests above were performed using the float model, to be refined - Bit32u ampRampVal = 67117056 - ampRamp.nextValue(); - if (ampRamp.checkInterrupt()) { - tva->handleInterrupt(); - } - return ampRampVal; -} - -Bit32u Partial::getCutoffValue() { - if (isPCM()) { - return 0; - } - Bit32u cutoffModifierRampVal = cutoffModifierRamp.nextValue(); - if (cutoffModifierRamp.checkInterrupt()) { - tvf->handleInterrupt(); - } - return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal; -} - -bool Partial::hasRingModulatingSlave() const { - return pair != NULL && structurePosition == 0 && (mixType == 1 || mixType == 2); -} - -bool Partial::isRingModulatingSlave() const { - return pair != NULL && structurePosition == 1 && (mixType == 1 || mixType == 2); -} - -bool Partial::isRingModulatingNoMix() const { - return pair != NULL && ((structurePosition == 1 && mixType == 1) || mixType == 2); -} - -bool Partial::isPCM() const { - return pcmWave != NULL; -} - -const ControlROMPCMStruct *Partial::getControlROMPCMStruct() const { - if (pcmWave != NULL) { - return pcmWave->controlROMPCMStruct; - } - return NULL; -} - -Synth *Partial::getSynth() const { - return synth; -} - -TVA *Partial::getTVA() const { - return tva; -} - -void Partial::backupCache(const PatchCache &cache) { - if (patchCache == &cache) { - cachebackup = cache; - patchCache = &cachebackup; - } -} - -bool Partial::canProduceOutput() { - if (!isActive() || alreadyOutputed || isRingModulatingSlave()) { - return false; - } - if (poly == NULL) { - synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum); - return false; - } - return true; -} - -template -bool Partial::generateNextSample(LA32PairImpl *la32PairImpl) { - if (!tva->isPlaying() || !la32PairImpl->isActive(LA32PartialPair::MASTER)) { - deactivate(); - return false; - } - la32PairImpl->generateNextSample(LA32PartialPair::MASTER, getAmpValue(), tvp->nextPitch(), getCutoffValue()); - if (hasRingModulatingSlave()) { - la32PairImpl->generateNextSample(LA32PartialPair::SLAVE, pair->getAmpValue(), pair->tvp->nextPitch(), pair->getCutoffValue()); - if (!pair->tva->isPlaying() || !la32PairImpl->isActive(LA32PartialPair::SLAVE)) { - pair->deactivate(); - if (mixType == 2) { - deactivate(); - return false; - } - } - } - return true; -} - -void Partial::produceAndMixSample(IntSample *&leftBuf, IntSample *&rightBuf, LA32IntPartialPair *la32IntPair) { - IntSampleEx sample = la32IntPair->nextOutSample(); - - // FIXME: LA32 may produce distorted sound in case if the absolute value of maximal amplitude of the input exceeds 8191 - // when the panning value is non-zero. Most probably the distortion occurs in the same way it does with ring modulation, - // and it seems to be caused by limited precision of the common multiplication circuit. - // From analysis of this overflow, it is obvious that the right channel output is actually found - // by subtraction of the left channel output from the input. - // Though, it is unknown whether this overflow is exploited somewhere. - - IntSampleEx leftOut = ((sample * leftPanValue) >> 13) + IntSampleEx(*leftBuf); - IntSampleEx rightOut = ((sample * rightPanValue) >> 13) + IntSampleEx(*rightBuf); - *(leftBuf++) = Synth::clipSampleEx(leftOut); - *(rightBuf++) = Synth::clipSampleEx(rightOut); -} - -void Partial::produceAndMixSample(FloatSample *&leftBuf, FloatSample *&rightBuf, LA32FloatPartialPair *la32FloatPair) { - FloatSample sample = la32FloatPair->nextOutSample(); - FloatSample leftOut = (sample * leftPanValue) / 14.0f; - FloatSample rightOut = (sample * rightPanValue) / 14.0f; - *(leftBuf++) += leftOut; - *(rightBuf++) += rightOut; -} - -template -bool Partial::doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length, LA32PairImpl *la32PairImpl) { - if (!canProduceOutput()) return false; - alreadyOutputed = true; - - for (sampleNum = 0; sampleNum < length; sampleNum++) { - if (!generateNextSample(la32PairImpl)) break; - produceAndMixSample(leftBuf, rightBuf, la32PairImpl); - } - sampleNum = 0; - return true; -} - -bool Partial::produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length) { - if (floatMode) { - synth->printDebug("Partial: Invalid call to produceOutput()! Renderer = %d\n", synth->getSelectedRendererType()); - return false; - } - return doProduceOutput(leftBuf, rightBuf, length, static_cast(la32Pair)); -} - -bool Partial::produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length) { - if (!floatMode) { - synth->printDebug("Partial: Invalid call to produceOutput()! Renderer = %d\n", synth->getSelectedRendererType()); - return false; - } - return doProduceOutput(leftBuf, rightBuf, length, static_cast(la32Pair)); -} - -bool Partial::shouldReverb() { - if (!isActive()) { - return false; - } - return patchCache->reverb; -} - -void Partial::startAbort() { - // This is called when the partial manager needs to terminate partials for re-use by a new Poly. - tva->startAbort(); -} - -void Partial::startDecayAll() { - tva->startDecay(); - tvp->startDecay(); - tvf->startDecay(); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Partial.h b/src - Cópia/sound/munt/Partial.h deleted file mode 100644 index 95f4c3fc2..000000000 --- a/src - Cópia/sound/munt/Partial.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_PARTIAL_H -#define MT32EMU_PARTIAL_H - -#include "globals.h" -#include "internals.h" -#include "Types.h" -#include "Structures.h" -#include "LA32Ramp.h" -#include "LA32WaveGenerator.h" -#include "LA32FloatWaveGenerator.h" - -namespace MT32Emu { - -class Part; -class Poly; -class Synth; -class TVA; -class TVF; -class TVP; -struct ControlROMPCMStruct; - -// A partial represents one of up to four waveform generators currently playing within a poly. -class Partial { -private: - Synth *synth; - const int debugPartialNum; // Only used for debugging - // Number of the sample currently being rendered by produceOutput(), or 0 if no run is in progress - // This is only kept available for debugging purposes. - Bit32u sampleNum; - - // Actually, this is a 4-bit register but we abuse this to emulate inverted mixing. - // Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK. - Bit32s leftPanValue, rightPanValue; - - int ownerPart; // -1 if unassigned - int mixType; - int structurePosition; // 0 or 1 of a structure pair - - // Only used for PCM partials - int pcmNum; - // FIXME: Give this a better name (e.g. pcmWaveInfo) - PCMWaveEntry *pcmWave; - - // Final pulse width value, with velfollow applied, matching what is sent to the LA32. - // Range: 0-255 - int pulseWidthVal; - - Poly *poly; - Partial *pair; - - TVA *tva; - TVP *tvp; - TVF *tvf; - - LA32Ramp ampRamp; - LA32Ramp cutoffModifierRamp; - - // TODO: This should be owned by PartialPair - LA32PartialPair *la32Pair; - const bool floatMode; - - const PatchCache *patchCache; - PatchCache cachebackup; - - Bit32u getAmpValue(); - Bit32u getCutoffValue(); - - template - bool doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length, LA32PairImpl *la32PairImpl); - bool canProduceOutput(); - template - bool generateNextSample(LA32PairImpl *la32PairImpl); - void produceAndMixSample(IntSample *&leftBuf, IntSample *&rightBuf, LA32IntPartialPair *la32IntPair); - void produceAndMixSample(FloatSample *&leftBuf, FloatSample *&rightBuf, LA32FloatPartialPair *la32FloatPair); - -public: - bool alreadyOutputed; - - Partial(Synth *synth, int debugPartialNum); - ~Partial(); - - int debugGetPartialNum() const; - Bit32u debugGetSampleNum() const; - - int getOwnerPart() const; - const Poly *getPoly() const; - bool isActive() const; - void activate(int part); - void deactivate(void); - void startPartial(const Part *part, Poly *usePoly, const PatchCache *useCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial); - void startAbort(); - void startDecayAll(); - bool shouldReverb(); - bool isRingModulatingNoMix() const; - bool hasRingModulatingSlave() const; - bool isRingModulatingSlave() const; - bool isPCM() const; - const ControlROMPCMStruct *getControlROMPCMStruct() const; - Synth *getSynth() const; - TVA *getTVA() const; - - void backupCache(const PatchCache &cache); - - // Returns true only if data written to buffer - // These functions produce processed stereo samples - // made from combining this single partial with its pair, if it has one. - bool produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length); - bool produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length); -}; // class Partial - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_PARTIAL_H diff --git a/src - Cópia/sound/munt/PartialManager.cpp b/src - Cópia/sound/munt/PartialManager.cpp deleted file mode 100644 index 6c622a9aa..000000000 --- a/src - Cópia/sound/munt/PartialManager.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "internals.h" - -#include "PartialManager.h" -#include "Part.h" -#include "Partial.h" -#include "Poly.h" -#include "Synth.h" - -namespace MT32Emu { - -PartialManager::PartialManager(Synth *useSynth, Part **useParts) { - synth = useSynth; - parts = useParts; - partialTable = new Partial *[synth->getPartialCount()]; - freePolys = new Poly *[synth->getPartialCount()]; - firstFreePolyIndex = 0; - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - partialTable[i] = new Partial(synth, i); - freePolys[i] = new Poly(); - } -} - -PartialManager::~PartialManager(void) { - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - delete partialTable[i]; - if (freePolys[i] != NULL) delete freePolys[i]; - } - delete[] partialTable; - delete[] freePolys; -} - -void PartialManager::clearAlreadyOutputed() { - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - partialTable[i]->alreadyOutputed = false; - } -} - -bool PartialManager::shouldReverb(int i) { - return partialTable[i]->shouldReverb(); -} - -bool PartialManager::produceOutput(int i, IntSample *leftBuf, IntSample *rightBuf, Bit32u bufferLength) { - return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength); -} - -bool PartialManager::produceOutput(int i, FloatSample *leftBuf, FloatSample *rightBuf, Bit32u bufferLength) { - return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength); -} - -void PartialManager::deactivateAll() { - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - partialTable[i]->deactivate(); - } -} - -unsigned int PartialManager::setReserve(Bit8u *rset) { - unsigned int pr = 0; - for (int x = 0; x <= 8; x++) { - numReservedPartialsForPart[x] = rset[x]; - pr += rset[x]; - } - return pr; -} - -Partial *PartialManager::allocPartial(int partNum) { - Partial *outPartial = NULL; - - // Get the first inactive partial - for (unsigned int partialNum = 0; partialNum < synth->getPartialCount(); partialNum++) { - if (!partialTable[partialNum]->isActive()) { - outPartial = partialTable[partialNum]; - break; - } - } - if (outPartial != NULL) { - outPartial->activate(partNum); - } - return outPartial; -} - -unsigned int PartialManager::getFreePartialCount(void) { - int count = 0; - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - if (!partialTable[i]->isActive()) { - count++; - } - } - return count; -} - -// This function is solely used to gather data for debug output at the moment. -void PartialManager::getPerPartPartialUsage(unsigned int perPartPartialUsage[9]) { - memset(perPartPartialUsage, 0, 9 * sizeof(unsigned int)); - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - if (partialTable[i]->isActive()) { - perPartPartialUsage[partialTable[i]->getOwnerPart()]++; - } - } -} - -// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly -// in POLY_Releasing, then kills its first releasing poly. -// Parts with higher priority than minPart are not checked. -// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date. -bool PartialManager::abortFirstReleasingPolyWhereReserveExceeded(int minPart) { - if (minPart == 8) { - // Rhythm is highest priority - minPart = -1; - } - for (int partNum = 7; partNum >= minPart; partNum--) { - int usePartNum = partNum == -1 ? 8 : partNum; - if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) { - // This part has exceeded its reserved partial count. - // If it has any releasing polys, kill its first one and we're done. - if (parts[usePartNum]->abortFirstPoly(POLY_Releasing)) { - return true; - } - } - } - return false; -} - -// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly, then kills -// its first poly in POLY_Held - or failing that, its first poly in any state. -// Parts with higher priority than minPart are not checked. -// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date. -bool PartialManager::abortFirstPolyPreferHeldWhereReserveExceeded(int minPart) { - if (minPart == 8) { - // Rhythm is highest priority - minPart = -1; - } - for (int partNum = 7; partNum >= minPart; partNum--) { - int usePartNum = partNum == -1 ? 8 : partNum; - if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) { - // This part has exceeded its reserved partial count. - // If it has any polys, kill its first (preferably held) one and we're done. - if (parts[usePartNum]->abortFirstPolyPreferHeld()) { - return true; - } - } - } - return false; -} - -bool PartialManager::freePartials(unsigned int needed, int partNum) { - // CONFIRMED: Barring bugs, this matches the real LAPC-I according to information from Mok. - - // BUG: There's a bug in the LAPC-I implementation: - // When allocating for rhythm part, or when allocating for a part that is using fewer partials than it has reserved, - // held and playing polys on the rhythm part can potentially be aborted before releasing polys on the rhythm part. - // This bug isn't present on MT-32. - // I consider this to be a bug because I think that playing polys should always have priority over held polys, - // and held polys should always have priority over releasing polys. - - // NOTE: This code generally aborts polys in parts (according to certain conditions) in the following order: - // 7, 6, 5, 4, 3, 2, 1, 0, 8 (rhythm) - // (from lowest priority, meaning most likely to have polys aborted, to highest priority, meaning least likely) - - if (needed == 0) { - return true; - } - - // Note that calling getFreePartialCount() also ensures that numReservedPartialsPerPart is up-to-date - if (getFreePartialCount() >= needed) { - return true; - } - - // Note: These #ifdefs are temporary until we have proper "quirk" configuration. - // Also, the MT-32 version isn't properly confirmed yet. -#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32 - // On MT-32, we bail out before even killing releasing partials if the allocating part has exceeded its reserve and is configured for priority-to-earlier-polys. - if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum] && (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1)) { - return false; - } -#endif - - for (;;) { -#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32 - // Abort releasing polys in parts that have exceeded their partial reservation (working backwards from part 7, with rhythm last) - if (!abortFirstReleasingPolyWhereReserveExceeded(-1)) { - break; - } -#else - // Abort releasing polys in non-rhythm parts that have exceeded their partial reservation (working backwards from part 7) - if (!abortFirstReleasingPolyWhereReserveExceeded(0)) { - break; - } -#endif - if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { - return true; - } - } - - if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum]) { - // With the new partials we're freeing for, we would end up using more partials than we have reserved. - if (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1) { - // Priority is given to earlier polys, so just give up - return false; - } - // Only abort held polys in the target part and parts that have a lower priority - // (higher part number = lower priority, except for rhythm, which has the highest priority). - for (;;) { - if (!abortFirstPolyPreferHeldWhereReserveExceeded(partNum)) { - break; - } - if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { - return true; - } - } - if (needed > numReservedPartialsForPart[partNum]) { - return false; - } - } else { - // At this point, we're certain that we've reserved enough partials to play our poly. - // Check all parts from lowest to highest priority to see whether they've exceeded their - // reserve, and abort their polys until until we have enough free partials or they're within - // their reserve allocation. - for (;;) { - if (!abortFirstPolyPreferHeldWhereReserveExceeded(-1)) { - break; - } - if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { - return true; - } - } - } - - // Abort polys in the target part until there are enough free partials for the new one - for (;;) { - if (!parts[partNum]->abortFirstPolyPreferHeld()) { - break; - } - if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { - return true; - } - } - - // Aww, not enough partials for you. - return false; -} - -const Partial *PartialManager::getPartial(unsigned int partialNum) const { - if (partialNum > synth->getPartialCount() - 1) { - return NULL; - } - return partialTable[partialNum]; -} - -Poly *PartialManager::assignPolyToPart(Part *part) { - if (firstFreePolyIndex < synth->getPartialCount()) { - Poly *poly = freePolys[firstFreePolyIndex]; - freePolys[firstFreePolyIndex] = NULL; - firstFreePolyIndex++; - poly->setPart(part); - return poly; - } - return NULL; -} - -void PartialManager::polyFreed(Poly *poly) { - if (0 == firstFreePolyIndex) { - synth->printDebug("Cannot return freed poly, currently active polys:\n"); - for (Bit32u partNum = 0; partNum < 9; partNum++) { - const Poly *activePoly = synth->getPart(partNum)->getFirstActivePoly(); - Bit32u polyCount = 0; - while (activePoly != NULL) { - activePoly = activePoly->getNext(); - polyCount++; - } - synth->printDebug("Part: %i, active poly count: %i\n", partNum, polyCount); - } - } - poly->setPart(NULL); - firstFreePolyIndex--; - freePolys[firstFreePolyIndex] = poly; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/PartialManager.h b/src - Cópia/sound/munt/PartialManager.h deleted file mode 100644 index 46d8eeb98..000000000 --- a/src - Cópia/sound/munt/PartialManager.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_PARTIALMANAGER_H -#define MT32EMU_PARTIALMANAGER_H - -#include "globals.h" -#include "internals.h" -#include "Types.h" - -namespace MT32Emu { - -class Part; -class Partial; -class Poly; -class Synth; - -class PartialManager { -private: - Synth *synth; - Part **parts; - Poly **freePolys; - Partial **partialTable; - Bit8u numReservedPartialsForPart[9]; - Bit32u firstFreePolyIndex; - - bool abortFirstReleasingPolyWhereReserveExceeded(int minPart); - bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart); - -public: - PartialManager(Synth *synth, Part **parts); - ~PartialManager(); - Partial *allocPartial(int partNum); - unsigned int getFreePartialCount(void); - void getPerPartPartialUsage(unsigned int perPartPartialUsage[9]); - bool freePartials(unsigned int needed, int partNum); - unsigned int setReserve(Bit8u *rset); - void deactivateAll(); - bool produceOutput(int i, IntSample *leftBuf, IntSample *rightBuf, Bit32u bufferLength); - bool produceOutput(int i, FloatSample *leftBuf, FloatSample *rightBuf, Bit32u bufferLength); - bool shouldReverb(int i); - void clearAlreadyOutputed(); - const Partial *getPartial(unsigned int partialNum) const; - Poly *assignPolyToPart(Part *part); - void polyFreed(Poly *poly); -}; // class PartialManager - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_PARTIALMANAGER_H diff --git a/src - Cópia/sound/munt/Poly.cpp b/src - Cópia/sound/munt/Poly.cpp deleted file mode 100644 index 44b8d2446..000000000 --- a/src - Cópia/sound/munt/Poly.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "Poly.h" -#include "Part.h" -#include "Partial.h" -#include "Synth.h" - -namespace MT32Emu { - -Poly::Poly() { - part = NULL; - key = 255; - velocity = 255; - sustain = false; - activePartialCount = 0; - for (int i = 0; i < 4; i++) { - partials[i] = NULL; - } - state = POLY_Inactive; - next = NULL; -} - -void Poly::setPart(Part *usePart) { - part = usePart; -} - -void Poly::reset(unsigned int newKey, unsigned int newVelocity, bool newSustain, Partial **newPartials) { - if (isActive()) { - // This should never happen - part->getSynth()->printDebug("Resetting active poly. Active partial count: %i\n", activePartialCount); - for (int i = 0; i < 4; i++) { - if (partials[i] != NULL && partials[i]->isActive()) { - partials[i]->deactivate(); - activePartialCount--; - } - } - state = POLY_Inactive; - } - - key = newKey; - velocity = newVelocity; - sustain = newSustain; - - activePartialCount = 0; - for (int i = 0; i < 4; i++) { - partials[i] = newPartials[i]; - if (newPartials[i] != NULL) { - activePartialCount++; - state = POLY_Playing; - } - } -} - -bool Poly::noteOff(bool pedalHeld) { - // Generally, non-sustaining instruments ignore note off. They die away eventually anyway. - // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held. - if (state == POLY_Inactive || state == POLY_Releasing) { - return false; - } - if (pedalHeld) { - if (state == POLY_Held) { - return false; - } - state = POLY_Held; - } else { - startDecay(); - } - return true; -} - -bool Poly::stopPedalHold() { - if (state != POLY_Held) { - return false; - } - return startDecay(); -} - -bool Poly::startDecay() { - if (state == POLY_Inactive || state == POLY_Releasing) { - return false; - } - state = POLY_Releasing; - - for (int t = 0; t < 4; t++) { - Partial *partial = partials[t]; - if (partial != NULL) { - partial->startDecayAll(); - } - } - return true; -} - -bool Poly::startAbort() { - if (state == POLY_Inactive || part->getSynth()->isAbortingPoly()) { - return false; - } - for (int t = 0; t < 4; t++) { - Partial *partial = partials[t]; - if (partial != NULL) { - partial->startAbort(); - part->getSynth()->abortingPoly = this; - } - } - return true; -} - -void Poly::backupCacheToPartials(PatchCache cache[4]) { - for (int partialNum = 0; partialNum < 4; partialNum++) { - Partial *partial = partials[partialNum]; - if (partial != NULL) { - partial->backupCache(cache[partialNum]); - } - } -} - -/** - * Returns the internal key identifier. - * For non-rhythm, this is within the range 12 to 108. - * For rhythm on MT-32, this is 0 or 1 (special cases) or within the range 24 to 87. - * For rhythm on devices with extended PCM sounds (e.g. CM-32L), this is 0, 1 or 24 to 108 - */ -unsigned int Poly::getKey() const { - return key; -} - -unsigned int Poly::getVelocity() const { - return velocity; -} - -bool Poly::canSustain() const { - return sustain; -} - -PolyState Poly::getState() const { - return state; -} - -unsigned int Poly::getActivePartialCount() const { - return activePartialCount; -} - -bool Poly::isActive() const { - return state != POLY_Inactive; -} - -// This is called by Partial to inform the poly that the Partial has deactivated -void Poly::partialDeactivated(Partial *partial) { - for (int i = 0; i < 4; i++) { - if (partials[i] == partial) { - partials[i] = NULL; - activePartialCount--; - } - } - if (activePartialCount == 0) { - state = POLY_Inactive; - if (part->getSynth()->abortingPoly == this) { - part->getSynth()->abortingPoly = NULL; - } - } - part->partialDeactivated(this); -} - -Poly *Poly::getNext() const { - return next; -} - -void Poly::setNext(Poly *poly) { - next = poly; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Poly.h b/src - Cópia/sound/munt/Poly.h deleted file mode 100644 index b2d4eceaf..000000000 --- a/src - Cópia/sound/munt/Poly.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_POLY_H -#define MT32EMU_POLY_H - -#include "globals.h" -#include "internals.h" - -namespace MT32Emu { - -class Part; -class Partial; -struct PatchCache; - -class Poly { -private: - Part *part; - unsigned int key; - unsigned int velocity; - unsigned int activePartialCount; - bool sustain; - - PolyState state; - - Partial *partials[4]; - - Poly *next; - -public: - Poly(); - void setPart(Part *usePart); - void reset(unsigned int key, unsigned int velocity, bool sustain, Partial **partials); - bool noteOff(bool pedalHeld); - bool stopPedalHold(); - bool startDecay(); - bool startAbort(); - - void backupCacheToPartials(PatchCache cache[4]); - - unsigned int getKey() const; - unsigned int getVelocity() const; - bool canSustain() const; - PolyState getState() const; - unsigned int getActivePartialCount() const; - bool isActive() const; - - void partialDeactivated(Partial *partial); - - Poly *getNext() const; - void setNext(Poly *poly); -}; // class Poly - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_POLY_H diff --git a/src - Cópia/sound/munt/ROMInfo.cpp b/src - Cópia/sound/munt/ROMInfo.cpp deleted file mode 100644 index 8c813a4e6..000000000 --- a/src - Cópia/sound/munt/ROMInfo.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "ROMInfo.h" - -namespace MT32Emu { - -static const ROMInfo *getKnownROMInfoFromList(Bit32u index) { - // Known ROMs - static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_MT32_V1_05 = {65536, "e17a3a6d265bf1fa150312061134293d2b58288c", ROMInfo::Control, "ctrl_mt32_1_05", "MT-32 Control v1.05", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_MT32_V1_06 = {65536, "a553481f4e2794c10cfe597fef154eef0d8257de", ROMInfo::Control, "ctrl_mt32_1_06", "MT-32 Control v1.06", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL}; - - static const ROMInfo CTRL_MT32_V2_04 = {131072, "2c16432b6c73dd2a3947cba950a0f4c19d6180eb", ROMInfo::Control, "ctrl_mt32_2_04", "MT-32 Control v2.04", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL}; - static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL}; - - static const ROMInfo PCM_MT32 = {524288, "f6b1eebc4b2d200ec6d3d21d51325d5b48c60252", ROMInfo::PCM, "pcm_mt32", "MT-32 PCM ROM", ROMInfo::Full, NULL}; - static const ROMInfo PCM_CM32L = {1048576, "289cc298ad532b702461bfc738009d9ebe8025ea", ROMInfo::PCM, "pcm_cm32l", "CM-32L/CM-64/LAPC-I PCM ROM", ROMInfo::Full, NULL}; - - static const ROMInfo * const ROM_INFOS[] = { - &CTRL_MT32_V1_04, - &CTRL_MT32_V1_05, - &CTRL_MT32_V1_06, - &CTRL_MT32_V1_07, - &CTRL_MT32_BLUER, - &CTRL_MT32_V2_04, - &CTRL_CM32L_V1_00, - &CTRL_CM32L_V1_02, - &PCM_MT32, - &PCM_CM32L, - NULL}; - - return ROM_INFOS[index]; -} - -const ROMInfo* ROMInfo::getROMInfo(File *file) { - size_t fileSize = file->getSize(); - for (Bit32u i = 0; getKnownROMInfoFromList(i) != NULL; i++) { - const ROMInfo *romInfo = getKnownROMInfoFromList(i); - if (fileSize == romInfo->fileSize && !strcmp(file->getSHA1(), romInfo->sha1Digest)) { - return romInfo; - } - } - return NULL; -} - -void ROMInfo::freeROMInfo(const ROMInfo *romInfo) { - (void) romInfo; -} - -static Bit32u getROMCount() { - Bit32u count; - for(count = 0; getKnownROMInfoFromList(count) != NULL; count++) { - } - return count; -} - -const ROMInfo** ROMInfo::getROMInfoList(Bit32u types, Bit32u pairTypes) { - const ROMInfo **romInfoList = new const ROMInfo*[getROMCount() + 1]; - const ROMInfo **currentROMInList = romInfoList; - for (Bit32u i = 0; getKnownROMInfoFromList(i) != NULL; i++) { - const ROMInfo *romInfo = getKnownROMInfoFromList(i); - if ((types & (1 << romInfo->type)) && (pairTypes & (1 << romInfo->pairType))) { - *currentROMInList++ = romInfo; - } - } - *currentROMInList = NULL; - return romInfoList; -} - -void ROMInfo::freeROMInfoList(const ROMInfo **romInfoList) { - delete[] romInfoList; -} - -ROMImage::ROMImage(File *useFile) : file(useFile), romInfo(ROMInfo::getROMInfo(file)) -{} - -ROMImage::~ROMImage() { - ROMInfo::freeROMInfo(romInfo); -} - -const ROMImage* ROMImage::makeROMImage(File *file) { - return new ROMImage(file); -} - -void ROMImage::freeROMImage(const ROMImage *romImage) { - delete romImage; -} - -File* ROMImage::getFile() const { - return file; -} - -const ROMInfo* ROMImage::getROMInfo() const { - return romInfo; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/ROMInfo.h b/src - Cópia/sound/munt/ROMInfo.h deleted file mode 100644 index cd4a1c5ac..000000000 --- a/src - Cópia/sound/munt/ROMInfo.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_ROMINFO_H -#define MT32EMU_ROMINFO_H - -#include - -#include "globals.h" -#include "File.h" - -namespace MT32Emu { - -// Defines vital info about ROM file to be used by synth and applications - -struct ROMInfo { -public: - size_t fileSize; - const File::SHA1Digest &sha1Digest; - enum Type {PCM, Control, Reverb} type; - const char *shortName; - const char *description; - enum PairType {Full, FirstHalf, SecondHalf, Mux0, Mux1} pairType; - ROMInfo *pairROMInfo; - - // Returns a ROMInfo struct by inspecting the size and the SHA1 hash - MT32EMU_EXPORT static const ROMInfo* getROMInfo(File *file); - - // Currently no-op - MT32EMU_EXPORT static void freeROMInfo(const ROMInfo *romInfo); - - // Allows retrieving a NULL-terminated list of ROMInfos for a range of types and pairTypes - // (specified by bitmasks) - // Useful for GUI/console app to output information on what ROMs it supports - MT32EMU_EXPORT static const ROMInfo** getROMInfoList(Bit32u types, Bit32u pairTypes); - - // Frees the list of ROMInfos given - MT32EMU_EXPORT static void freeROMInfoList(const ROMInfo **romInfos); -}; - -// Synth::open() is to require a full control ROMImage and a full PCM ROMImage to work - -class ROMImage { -private: - File * const file; - const ROMInfo * const romInfo; - - ROMImage(File *file); - ~ROMImage(); - -public: - // Creates a ROMImage object given a ROMInfo and a File. Keeps a reference - // to the File and ROMInfo given, which must be freed separately by the user - // after the ROMImage is freed - MT32EMU_EXPORT static const ROMImage* makeROMImage(File *file); - - // Must only be done after all Synths using the ROMImage are deleted - MT32EMU_EXPORT static void freeROMImage(const ROMImage *romImage); - - MT32EMU_EXPORT File *getFile() const; - MT32EMU_EXPORT const ROMInfo *getROMInfo() const; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_ROMINFO_H diff --git a/src - Cópia/sound/munt/SampleRateConverter.cpp b/src - Cópia/sound/munt/SampleRateConverter.cpp deleted file mode 100644 index 2d7866ba6..000000000 --- a/src - Cópia/sound/munt/SampleRateConverter.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "SampleRateConverter.h" - -#if MT32EMU_WITH_LIBSOXR_RESAMPLER -#include "srchelper/SoxrAdapter.h" -#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER -#include "srchelper/SamplerateAdapter.h" -#else -#include "srchelper/InternalResampler.h" -#endif - -#include "Synth.h" - -using namespace MT32Emu; - -static inline void *createDelegate(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality) { -#if MT32EMU_WITH_LIBSOXR_RESAMPLER - return new SoxrAdapter(synth, targetSampleRate, quality); -#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER - return new SamplerateAdapter(synth, targetSampleRate, quality); -#else - return new InternalResampler(synth, targetSampleRate, quality); -#endif -} - -AnalogOutputMode SampleRateConverter::getBestAnalogOutputMode(double targetSampleRate) { - if (Synth::getStereoOutputSampleRate(AnalogOutputMode_ACCURATE) < targetSampleRate) { - return AnalogOutputMode_OVERSAMPLED; - } else if (Synth::getStereoOutputSampleRate(AnalogOutputMode_COARSE) < targetSampleRate) { - return AnalogOutputMode_ACCURATE; - } - return AnalogOutputMode_COARSE; -} - -SampleRateConverter::SampleRateConverter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality useQuality) : - synthInternalToTargetSampleRateRatio(SAMPLE_RATE / targetSampleRate), - useSynthDelegate(useSynth.getStereoOutputSampleRate() == targetSampleRate), - srcDelegate(useSynthDelegate ? &useSynth : createDelegate(useSynth, targetSampleRate, useQuality)) -{} - -SampleRateConverter::~SampleRateConverter() { - if (!useSynthDelegate) { -#if MT32EMU_WITH_LIBSOXR_RESAMPLER - delete static_cast(srcDelegate); -#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER - delete static_cast(srcDelegate); -#else - delete static_cast(srcDelegate); -#endif - } -} - -void SampleRateConverter::getOutputSamples(float *buffer, unsigned int length) { - if (useSynthDelegate) { - static_cast(srcDelegate)->render(buffer, length); - return; - } - -#if MT32EMU_WITH_LIBSOXR_RESAMPLER - static_cast(srcDelegate)->getOutputSamples(buffer, length); -#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER - static_cast(srcDelegate)->getOutputSamples(buffer, length); -#else - static_cast(srcDelegate)->getOutputSamples(buffer, length); -#endif -} - -void SampleRateConverter::getOutputSamples(Bit16s *outBuffer, unsigned int length) { - static const unsigned int CHANNEL_COUNT = 2; - - if (useSynthDelegate) { - static_cast(srcDelegate)->render(outBuffer, length); - return; - } - - float floatBuffer[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]; - while (length > 0) { - const unsigned int size = MAX_SAMPLES_PER_RUN < length ? MAX_SAMPLES_PER_RUN : length; - getOutputSamples(floatBuffer, size); - float *outs = floatBuffer; - float *ends = floatBuffer + CHANNEL_COUNT * size; - while (outs < ends) { - *(outBuffer++) = Synth::convertSample(*(outs++)); - } - length -= size; - } -} - -double SampleRateConverter::convertOutputToSynthTimestamp(double outputTimestamp) const { - return outputTimestamp * synthInternalToTargetSampleRateRatio; -} - -double SampleRateConverter::convertSynthToOutputTimestamp(double synthTimestamp) const { - return synthTimestamp / synthInternalToTargetSampleRateRatio; -} diff --git a/src - Cópia/sound/munt/SampleRateConverter.h b/src - Cópia/sound/munt/SampleRateConverter.h deleted file mode 100644 index 437f9b29f..000000000 --- a/src - Cópia/sound/munt/SampleRateConverter.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_SAMPLE_RATE_CONVERTER_H -#define MT32EMU_SAMPLE_RATE_CONVERTER_H - -#include "globals.h" -#include "Types.h" -#include "Enumerations.h" - -namespace MT32Emu { - -class Synth; - -/* SampleRateConverter class allows to convert the synthesiser output to any desired sample rate. - * It processes the completely mixed stereo output signal as it passes the analogue circuit emulation, - * so emulating the synthesiser output signal passing further through an ADC. - * Several conversion quality options are provided which allow to trade-off the conversion speed vs. the passband width. - * All the options except FASTEST guarantee full suppression of the aliasing noise in terms of the 16-bit integer samples. - */ -class MT32EMU_EXPORT SampleRateConverter { -public: - // Returns the value of AnalogOutputMode for which the output signal may retain its full frequency spectrum - // at the sample rate specified by the targetSampleRate argument. - static AnalogOutputMode getBestAnalogOutputMode(double targetSampleRate); - - // Creates a SampleRateConverter instance that converts output signal from the synth to the given sample rate - // with the specified conversion quality. - SampleRateConverter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); - ~SampleRateConverter(); - - // Fills the provided output buffer with the results of the sample rate conversion. - // The input samples are automatically retrieved from the synth as necessary. - void getOutputSamples(MT32Emu::Bit16s *buffer, unsigned int length); - - // Fills the provided output buffer with the results of the sample rate conversion. - // The input samples are automatically retrieved from the synth as necessary. - void getOutputSamples(float *buffer, unsigned int length); - - // Returns the number of samples produced at the internal synth sample rate (32000 Hz) - // that correspond to the number of samples at the target sample rate. - // Intended to facilitate audio time synchronisation. - double convertOutputToSynthTimestamp(double outputTimestamp) const; - - // Returns the number of samples produced at the target sample rate - // that correspond to the number of samples at the internal synth sample rate (32000 Hz). - // Intended to facilitate audio time synchronisation. - double convertSynthToOutputTimestamp(double synthTimestamp) const; - -private: - const double synthInternalToTargetSampleRateRatio; - const bool useSynthDelegate; - void * const srcDelegate; -}; // class SampleRateConverter - -} // namespace MT32Emu - -#endif // MT32EMU_SAMPLE_RATE_CONVERTER_H diff --git a/src - Cópia/sound/munt/SampleRateConverter_dummy.cpp b/src - Cópia/sound/munt/SampleRateConverter_dummy.cpp deleted file mode 100644 index 9094f1514..000000000 --- a/src - Cópia/sound/munt/SampleRateConverter_dummy.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include -#include "../../plat.h" -#include "SampleRateConverter.h" - -#include "Synth.h" - -using namespace MT32Emu; - -static inline void *createDelegate(UNUSED(Synth &synth), UNUSED(double targetSampleRate), UNUSED(SamplerateConversionQuality quality)) { - return 0; -} - -AnalogOutputMode SampleRateConverter::getBestAnalogOutputMode(UNUSED(double targetSampleRate)) { - return AnalogOutputMode_COARSE; -} - -SampleRateConverter::SampleRateConverter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality useQuality) : - synthInternalToTargetSampleRateRatio(SAMPLE_RATE / targetSampleRate), - useSynthDelegate(useSynth.getStereoOutputSampleRate() == targetSampleRate), - srcDelegate(useSynthDelegate ? &useSynth : createDelegate(useSynth, targetSampleRate, useQuality)) -{} - -SampleRateConverter::~SampleRateConverter() { -} - -void SampleRateConverter::getOutputSamples(float *buffer, unsigned int length) { - if (useSynthDelegate) { - static_cast(srcDelegate)->render(buffer, length); - return; - } -} - -void SampleRateConverter::getOutputSamples(Bit16s *outBuffer, unsigned int length) { - if (useSynthDelegate) { - static_cast(srcDelegate)->render(outBuffer, length); - return; - } -} - -double SampleRateConverter::convertOutputToSynthTimestamp(double outputTimestamp) const { - return outputTimestamp * synthInternalToTargetSampleRateRatio; -} - -double SampleRateConverter::convertSynthToOutputTimestamp(double synthTimestamp) const { - return synthTimestamp / synthInternalToTargetSampleRateRatio; -} diff --git a/src - Cópia/sound/munt/Structures.h b/src - Cópia/sound/munt/Structures.h deleted file mode 100644 index d116aaeb4..000000000 --- a/src - Cópia/sound/munt/Structures.h +++ /dev/null @@ -1,265 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_STRUCTURES_H -#define MT32EMU_STRUCTURES_H - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -// MT32EMU_MEMADDR() converts from sysex-padded, MT32EMU_SYSEXMEMADDR converts to it -// Roland provides documentation using the sysex-padded addresses, so we tend to use that in code and output -#define MT32EMU_MEMADDR(x) ((((x) & 0x7f0000) >> 2) | (((x) & 0x7f00) >> 1) | ((x) & 0x7f)) -#define MT32EMU_SYSEXMEMADDR(x) ((((x) & 0x1FC000) << 2) | (((x) & 0x3F80) << 1) | ((x) & 0x7f)) - -#ifdef _MSC_VER -#define MT32EMU_ALIGN_PACKED __declspec(align(1)) -#else -#define MT32EMU_ALIGN_PACKED __attribute__((packed)) -#endif - -// The following structures represent the MT-32's memory -// Since sysex allows this memory to be written to in blocks of bytes, -// we keep this packed so that we can copy data into the various -// banks directly -#if defined(_MSC_VER) || defined(__MINGW32__) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif - -struct TimbreParam { - struct CommonParam { - char name[10]; - Bit8u partialStructure12; // 1 & 2 0-12 (1-13) - Bit8u partialStructure34; // 3 & 4 0-12 (1-13) - Bit8u partialMute; // 0-15 (0000-1111) - Bit8u noSustain; // ENV MODE 0-1 (Normal, No sustain) - } MT32EMU_ALIGN_PACKED common; - - struct PartialParam { - struct WGParam { - Bit8u pitchCoarse; // 0-96 (C1,C#1-C9) - Bit8u pitchFine; // 0-100 (-50 to +50 (cents - confirmed by Mok)) - Bit8u pitchKeyfollow; // 0-16 (-1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2) - Bit8u pitchBenderEnabled; // 0-1 (OFF, ON) - Bit8u waveform; // MT-32: 0-1 (SQU/SAW); LAPC-I: WG WAVEFORM/PCM BANK 0 - 3 (SQU/1, SAW/1, SQU/2, SAW/2) - Bit8u pcmWave; // 0-127 (1-128) - Bit8u pulseWidth; // 0-100 - Bit8u pulseWidthVeloSensitivity; // 0-14 (-7 - +7) - } MT32EMU_ALIGN_PACKED wg; - - struct PitchEnvParam { - Bit8u depth; // 0-10 - Bit8u veloSensitivity; // 0-100 - Bit8u timeKeyfollow; // 0-4 - Bit8u time[4]; // 0-100 - Bit8u level[5]; // 0-100 (-50 - +50) // [3]: SUSTAIN LEVEL, [4]: END LEVEL - } MT32EMU_ALIGN_PACKED pitchEnv; - - struct PitchLFOParam { - Bit8u rate; // 0-100 - Bit8u depth; // 0-100 - Bit8u modSensitivity; // 0-100 - } MT32EMU_ALIGN_PACKED pitchLFO; - - struct TVFParam { - Bit8u cutoff; // 0-100 - Bit8u resonance; // 0-30 - Bit8u keyfollow; // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2 - Bit8u biasPoint; // 0-127 (<1A-<7C >1A-7C) - Bit8u biasLevel; // 0-14 (-7 - +7) - Bit8u envDepth; // 0-100 - Bit8u envVeloSensitivity; // 0-100 - Bit8u envDepthKeyfollow; // DEPTH KEY FOLL0W 0-4 - Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4 - Bit8u envTime[5]; // 0-100 - Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL - } MT32EMU_ALIGN_PACKED tvf; - - struct TVAParam { - Bit8u level; // 0-100 - Bit8u veloSensitivity; // 0-100 - Bit8u biasPoint1; // 0-127 (<1A-<7C >1A-7C) - Bit8u biasLevel1; // 0-12 (-12 - 0) - Bit8u biasPoint2; // 0-127 (<1A-<7C >1A-7C) - Bit8u biasLevel2; // 0-12 (-12 - 0) - Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4 - Bit8u envTimeVeloSensitivity; // VELOS KEY FOLL0W 0-4 - Bit8u envTime[5]; // 0-100 - Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL - } MT32EMU_ALIGN_PACKED tva; - } MT32EMU_ALIGN_PACKED partial[4]; // struct PartialParam -} MT32EMU_ALIGN_PACKED; // struct TimbreParam - -struct PatchParam { - Bit8u timbreGroup; // TIMBRE GROUP 0-3 (group A, group B, Memory, Rhythm) - Bit8u timbreNum; // TIMBRE NUMBER 0-63 - Bit8u keyShift; // KEY SHIFT 0-48 (-24 - +24 semitones) - Bit8u fineTune; // FINE TUNE 0-100 (-50 - +50 cents) - Bit8u benderRange; // BENDER RANGE 0-24 - Bit8u assignMode; // ASSIGN MODE 0-3 (POLY1, POLY2, POLY3, POLY4) - Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON) - Bit8u dummy; // (DUMMY) -} MT32EMU_ALIGN_PACKED; - -const unsigned int SYSTEM_MASTER_TUNE_OFF = 0; -const unsigned int SYSTEM_REVERB_MODE_OFF = 1; -const unsigned int SYSTEM_REVERB_TIME_OFF = 2; -const unsigned int SYSTEM_REVERB_LEVEL_OFF = 3; -const unsigned int SYSTEM_RESERVE_SETTINGS_START_OFF = 4; -const unsigned int SYSTEM_RESERVE_SETTINGS_END_OFF = 12; -const unsigned int SYSTEM_CHAN_ASSIGN_START_OFF = 13; -const unsigned int SYSTEM_CHAN_ASSIGN_END_OFF = 21; -const unsigned int SYSTEM_MASTER_VOL_OFF = 22; - -struct MemParams { - // NOTE: The MT-32 documentation only specifies PatchTemp areas for parts 1-8. - // The LAPC-I documentation specified an additional area for rhythm at the end, - // where all parameters but fine tune, assign mode and output level are ignored - struct PatchTemp { - PatchParam patch; - Bit8u outputLevel; // OUTPUT LEVEL 0-100 - Bit8u panpot; // PANPOT 0-14 (R-L) - Bit8u dummyv[6]; - } MT32EMU_ALIGN_PACKED patchTemp[9]; - - struct RhythmTemp { - Bit8u timbre; // TIMBRE 0-94 (M1-M64,R1-30,OFF); LAPC-I: 0-127 (M01-M64,R01-R63) - Bit8u outputLevel; // OUTPUT LEVEL 0-100 - Bit8u panpot; // PANPOT 0-14 (R-L) - Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON) - } MT32EMU_ALIGN_PACKED rhythmTemp[85]; - - TimbreParam timbreTemp[8]; - - PatchParam patches[128]; - - // NOTE: There are only 30 timbres in the "rhythm" bank for MT-32; the additional 34 are for LAPC-I and above - struct PaddedTimbre { - TimbreParam timbre; - Bit8u padding[10]; - } MT32EMU_ALIGN_PACKED timbres[64 + 64 + 64 + 64]; // Group A, Group B, Memory, Rhythm - - struct System { - Bit8u masterTune; // MASTER TUNE 0-127 432.1-457.6Hz - Bit8u reverbMode; // REVERB MODE 0-3 (room, hall, plate, tap delay) - Bit8u reverbTime; // REVERB TIME 0-7 (1-8) - Bit8u reverbLevel; // REVERB LEVEL 0-7 (1-8) - Bit8u reserveSettings[9]; // PARTIAL RESERVE (PART 1) 0-32 - Bit8u chanAssign[9]; // MIDI CHANNEL (PART1) 0-16 (1-16,OFF) - Bit8u masterVol; // MASTER VOLUME 0-100 - } MT32EMU_ALIGN_PACKED system; -}; // struct MemParams - -struct SoundGroup { - Bit8u timbreNumberTableAddrLow; - Bit8u timbreNumberTableAddrHigh; - Bit8u displayPosition; - Bit8u name[9]; - Bit8u timbreCount; - Bit8u pad; -} MT32EMU_ALIGN_PACKED; - -#if defined(_MSC_VER) || defined(__MINGW32__) -#pragma pack(pop) -#else -#pragma pack() -#endif - -struct ControlROMFeatureSet { - unsigned int quirkBasePitchOverflow : 1; - unsigned int quirkPitchEnvelopeOverflow : 1; - unsigned int quirkRingModulationNoMix : 1; - unsigned int quirkTVAZeroEnvLevels : 1; - unsigned int quirkPanMult : 1; - unsigned int quirkKeyShift : 1; - unsigned int quirkTVFBaseCutoffLimit : 1; - - // Features below don't actually depend on control ROM version, which is used to identify hardware model - unsigned int defaultReverbMT32Compatible : 1; - unsigned int oldMT32AnalogLPF : 1; -}; - -struct ControlROMMap { - const char *shortName; - const ControlROMFeatureSet &featureSet; - Bit16u pcmTable; // 4 * pcmCount bytes - Bit16u pcmCount; - Bit16u timbreAMap; // 128 bytes - Bit16u timbreAOffset; - bool timbreACompressed; - Bit16u timbreBMap; // 128 bytes - Bit16u timbreBOffset; - bool timbreBCompressed; - Bit16u timbreRMap; // 2 * timbreRCount bytes - Bit16u timbreRCount; - Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes - Bit16u rhythmSettingsCount; - Bit16u reserveSettings; // 9 bytes - Bit16u panSettings; // 8 bytes - Bit16u programSettings; // 8 bytes - Bit16u rhythmMaxTable; // 4 bytes - Bit16u patchMaxTable; // 16 bytes - Bit16u systemMaxTable; // 23 bytes - Bit16u timbreMaxTable; // 72 bytes - Bit16u soundGroupsTable; // 14 bytes each entry - Bit16u soundGroupsCount; -}; - -struct ControlROMPCMStruct { - Bit8u pos; - Bit8u len; - Bit8u pitchLSB; - Bit8u pitchMSB; -}; - -struct PCMWaveEntry { - Bit32u addr; - Bit32u len; - bool loop; - ControlROMPCMStruct *controlROMPCMStruct; -}; - -// This is basically a per-partial, pre-processed combination of timbre and patch/rhythm settings -struct PatchCache { - bool playPartial; - bool PCMPartial; - int pcm; - Bit8u waveform; - - Bit32u structureMix; - int structurePosition; - int structurePair; - - // The following fields are actually common to all partials in the timbre - bool dirty; - Bit32u partialCount; - bool sustain; - bool reverb; - - TimbreParam::PartialParam srcPartial; - - // The following directly points into live sysex-addressable memory - const TimbreParam::PartialParam *partialParam; -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_STRUCTURES_H diff --git a/src - Cópia/sound/munt/Synth.cpp b/src - Cópia/sound/munt/Synth.cpp deleted file mode 100644 index f4eda5c79..000000000 --- a/src - Cópia/sound/munt/Synth.cpp +++ /dev/null @@ -1,2359 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "Synth.h" -#include "Analog.h" -#include "BReverbModel.h" -#include "File.h" -#include "MemoryRegion.h" -#include "MidiEventQueue.h" -#include "Part.h" -#include "Partial.h" -#include "PartialManager.h" -#include "Poly.h" -#include "ROMInfo.h" -#include "TVA.h" - -#if MT32EMU_MONITOR_SYSEX > 0 -#include "mmath.h" -#endif - -namespace MT32Emu { - -// MIDI interface data transfer rate in samples. Used to simulate the transfer delay. -static const double MIDI_DATA_TRANSFER_RATE = double(SAMPLE_RATE) / 31250.0 * 8.0; - -// FIXME: there should be more specific feature sets for various MT-32 control ROM versions -static const ControlROMFeatureSet OLD_MT32_COMPATIBLE = { - true, // quirkBasePitchOverflow - true, // quirkPitchEnvelopeOverflow - true, // quirkRingModulationNoMix - true, // quirkTVAZeroEnvLevels - true, // quirkPanMult - true, // quirkKeyShift - true, // quirkTVFBaseCutoffLimit - true, // defaultReverbMT32Compatible - true // oldMT32AnalogLPF -}; -static const ControlROMFeatureSet CM32L_COMPATIBLE = { - false, // quirkBasePitchOverflow - false, // quirkPitchEnvelopeOverflow - false, // quirkRingModulationNoMix - false, // quirkTVAZeroEnvLevels - false, // quirkPanMult - false, // quirkKeyShift - false, // quirkTVFBaseCutoffLimit - false, // defaultReverbMT32Compatible - false // oldMT32AnalogLPF -}; - -static const ControlROMMap ControlROMMaps[8] = { - // ID Features PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax sndGrp sGC - { "ctrl_mt32_1_04", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x7064, 19 }, - { "ctrl_mt32_1_05", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x70CA, 19 }, - { "ctrl_mt32_1_06", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57F4, 0x57E2, 0x5264, 0x5270, 0x5280, 0x521C, 0x70CA, 19 }, - { "ctrl_mt32_1_07", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57CC, 0x57BA, 0x523C, 0x5248, 0x5258, 0x51F4, 0x70B0, 19 }, // MT-32 revision 1 - {"ctrl_mt32_bluer", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x741C, 85, 0x57E5, 0x5800, 0x57EE, 0x5270, 0x527C, 0x528C, 0x5228, 0x70CE, 19 }, // MT-32 Blue Ridge mod - {"ctrl_mt32_2_04", CM32L_COMPATIBLE, 0x8100, 128, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 30, 0x8580, 85, 0x4F5D, 0x4F78, 0x4F66, 0x4899, 0x489D, 0x48B6, 0x48CD, 0x5A58, 19 }, - {"ctrl_cm32l_1_00", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F65, 0x4F80, 0x4F6E, 0x48A1, 0x48A5, 0x48BE, 0x48D5, 0x5A6C, 19 }, - {"ctrl_cm32l_1_02", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4FAE, 0x4F9C, 0x48CB, 0x48CF, 0x48E8, 0x48FF, 0x5A96, 19 } // CM-32L - // (Note that old MT-32 ROMs actually have 86 entries for rhythmTemp) -}; - -static const PartialState PARTIAL_PHASE_TO_STATE[8] = { - PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, - PartialState_SUSTAIN, PartialState_SUSTAIN, PartialState_RELEASE, PartialState_INACTIVE -}; - -static inline PartialState getPartialState(PartialManager *partialManager, unsigned int partialNum) { - const Partial *partial = partialManager->getPartial(partialNum); - return partial->isActive() ? PARTIAL_PHASE_TO_STATE[partial->getTVA()->getPhase()] : PartialState_INACTIVE; -} - -template -static inline void convertSampleFormat(const I *inBuffer, O *outBuffer, const Bit32u len) { - if (inBuffer == NULL || outBuffer == NULL) return; - - const I *inBufferEnd = inBuffer + len; - while (inBuffer < inBufferEnd) { - *(outBuffer++) = Synth::convertSample(*(inBuffer++)); - } -} - -class Renderer { -protected: - Synth &synth; - - void printDebug(const char *msg) const { - synth.printDebug("%s", msg); - } - - bool isActivated() const { - return synth.activated; - } - - bool isAbortingPoly() const { - return synth.isAbortingPoly(); - } - - Analog &getAnalog() const { - return *synth.analog; - } - - MidiEventQueue &getMidiQueue() { - return *synth.midiQueue; - } - - PartialManager &getPartialManager() { - return *synth.partialManager; - } - - BReverbModel &getReverbModel() { - return *synth.reverbModel; - } - - Bit32u getRenderedSampleCount() { - return synth.renderedSampleCount; - } - - void incRenderedSampleCount(const Bit32u count) { - synth.renderedSampleCount += count; - } - -public: - Renderer(Synth &useSynth) : synth(useSynth) {} - - virtual ~Renderer() {} - - virtual void render(IntSample *stereoStream, Bit32u len) = 0; - virtual void render(FloatSample *stereoStream, Bit32u len) = 0; - virtual void renderStreams(const DACOutputStreams &streams, Bit32u len) = 0; - virtual void renderStreams(const DACOutputStreams &streams, Bit32u len) = 0; -}; - -template -class RendererImpl : public Renderer { - // These buffers are used for building the output streams as they are found at the DAC entrance. - // The output is mixed down to stereo interleaved further in the analog circuitry emulation. - Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN]; - Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN]; - Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN]; - - const DACOutputStreams tmpBuffers; - DACOutputStreams createTmpBuffers() { - DACOutputStreams buffers = { - tmpNonReverbLeft, tmpNonReverbRight, - tmpReverbDryLeft, tmpReverbDryRight, - tmpReverbWetLeft, tmpReverbWetRight - }; - return buffers; - } - -public: - RendererImpl(Synth &useSynth) : - Renderer(useSynth), - tmpBuffers(createTmpBuffers()) - {} - - void render(IntSample *stereoStream, Bit32u len); - void render(FloatSample *stereoStream, Bit32u len); - void renderStreams(const DACOutputStreams &streams, Bit32u len); - void renderStreams(const DACOutputStreams &streams, Bit32u len); - - template - void doRenderAndConvert(O *stereoStream, Bit32u len); - void doRender(Sample *stereoStream, Bit32u len); - - template - void doRenderAndConvertStreams(const DACOutputStreams &streams, Bit32u len); - void doRenderStreams(const DACOutputStreams &streams, Bit32u len); - void produceLA32Output(Sample *buffer, Bit32u len); - void convertSamplesToOutput(Sample *buffer, Bit32u len); - void produceStreams(const DACOutputStreams &streams, Bit32u len); -}; - -class Extensions { -public: - RendererType selectedRendererType; - Bit32s masterTunePitchDelta; - bool niceAmpRamp; -}; - -Bit32u Synth::getLibraryVersionInt() { - return (MT32EMU_VERSION_MAJOR << 16) | (MT32EMU_VERSION_MINOR << 8) | (MT32EMU_VERSION_PATCH); -} - -const char *Synth::getLibraryVersionString() { - return MT32EMU_VERSION; -} - -Bit8u Synth::calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum) { - unsigned int checksum = -initChecksum; - for (unsigned int i = 0; i < len; i++) { - checksum -= data[i]; - } - return Bit8u(checksum & 0x7f); -} - -Bit32u Synth::getStereoOutputSampleRate(AnalogOutputMode analogOutputMode) { - static const unsigned int SAMPLE_RATES[] = {SAMPLE_RATE, SAMPLE_RATE, SAMPLE_RATE * 3 / 2, SAMPLE_RATE * 3}; - - return SAMPLE_RATES[analogOutputMode]; -} - -Synth::Synth(ReportHandler *useReportHandler) : - mt32ram(*new MemParams), - mt32default(*new MemParams), - extensions(*new Extensions) -{ - opened = false; - reverbOverridden = false; - partialCount = DEFAULT_MAX_PARTIALS; - controlROMMap = NULL; - controlROMFeatures = NULL; - - if (useReportHandler == NULL) { - reportHandler = new ReportHandler; - isDefaultReportHandler = true; - } else { - reportHandler = useReportHandler; - isDefaultReportHandler = false; - } - - for (int i = 0; i < 4; i++) { - reverbModels[i] = NULL; - } - reverbModel = NULL; - analog = NULL; - renderer = NULL; - setDACInputMode(DACInputMode_NICE); - setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY); - setOutputGain(1.0f); - setReverbOutputGain(1.0f); - setReversedStereoEnabled(false); - setNiceAmpRampEnabled(true); - selectRendererType(RendererType_BIT16S); - - patchTempMemoryRegion = NULL; - rhythmTempMemoryRegion = NULL; - timbreTempMemoryRegion = NULL; - patchesMemoryRegion = NULL; - timbresMemoryRegion = NULL; - systemMemoryRegion = NULL; - displayMemoryRegion = NULL; - resetMemoryRegion = NULL; - paddedTimbreMaxTable = NULL; - - partialManager = NULL; - pcmWaves = NULL; - pcmROMData = NULL; - soundGroupNames = NULL; - midiQueue = NULL; - lastReceivedMIDIEventTimestamp = 0; - memset(parts, 0, sizeof(parts)); - renderedSampleCount = 0; -} - -Synth::~Synth() { - close(); // Make sure we're closed and everything is freed - if (isDefaultReportHandler) { - delete reportHandler; - } - delete &mt32ram; - delete &mt32default; - delete &extensions; -} - -void ReportHandler::showLCDMessage(const char *data) { - printf("WRITE-LCD: %s\n", data); -} - -void ReportHandler::printDebug(const char *fmt, va_list list) { - vprintf(fmt, list); - printf("\n"); -} - -void Synth::newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, const char patchName[]) { - const char *soundGroupName; - switch (timbreGroup) { - case 1: - timbreNumber += 64; - // Fall-through - case 0: - soundGroupName = soundGroupNames[soundGroupIx[timbreNumber]]; - break; - case 2: - soundGroupName = soundGroupNames[controlROMMap->soundGroupsCount - 2]; - break; - case 3: - soundGroupName = soundGroupNames[controlROMMap->soundGroupsCount - 1]; - break; - default: - soundGroupName = NULL; - break; - } - reportHandler->onProgramChanged(partNum, soundGroupName, patchName); -} - -void Synth::printDebug(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); -#if MT32EMU_DEBUG_SAMPLESTAMPS > 0 - reportHandler->printDebug("[%u]", (va_list)&renderedSampleCount); -#endif - reportHandler->printDebug(fmt, ap); - va_end(ap); -} - -void Synth::setReverbEnabled(bool newReverbEnabled) { - if (!opened) return; - if (isReverbEnabled() == newReverbEnabled) return; - if (newReverbEnabled) { - bool oldReverbOverridden = reverbOverridden; - reverbOverridden = false; - refreshSystemReverbParameters(); - reverbOverridden = oldReverbOverridden; - } else { -#if MT32EMU_REDUCE_REVERB_MEMORY - reverbModel->close(); -#endif - reverbModel = NULL; - } -} - -bool Synth::isReverbEnabled() const { - return reverbModel != NULL; -} - -void Synth::setReverbOverridden(bool newReverbOverridden) { - reverbOverridden = newReverbOverridden; -} - -bool Synth::isReverbOverridden() const { - return reverbOverridden; -} - -void Synth::setReverbCompatibilityMode(bool mt32CompatibleMode) { - if (!opened || (isMT32ReverbCompatibilityMode() == mt32CompatibleMode)) return; - bool oldReverbEnabled = isReverbEnabled(); - setReverbEnabled(false); - for (int i = 0; i < 4; i++) { - delete reverbModels[i]; - } - initReverbModels(mt32CompatibleMode); - setReverbEnabled(oldReverbEnabled); - setReverbOutputGain(reverbOutputGain); -} - -bool Synth::isMT32ReverbCompatibilityMode() const { - return opened && (reverbModels[REVERB_MODE_ROOM]->isMT32Compatible(REVERB_MODE_ROOM)); -} - -bool Synth::isDefaultReverbMT32Compatible() const { - return opened && controlROMFeatures->defaultReverbMT32Compatible; -} - -void Synth::setDACInputMode(DACInputMode mode) { - dacInputMode = mode; -} - -DACInputMode Synth::getDACInputMode() const { - return dacInputMode; -} - -void Synth::setMIDIDelayMode(MIDIDelayMode mode) { - midiDelayMode = mode; -} - -MIDIDelayMode Synth::getMIDIDelayMode() const { - return midiDelayMode; -} - -void Synth::setOutputGain(float newOutputGain) { - if (newOutputGain < 0.0f) newOutputGain = -newOutputGain; - outputGain = newOutputGain; - if (analog != NULL) analog->setSynthOutputGain(newOutputGain); -} - -float Synth::getOutputGain() const { - return outputGain; -} - -void Synth::setReverbOutputGain(float newReverbOutputGain) { - if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain; - reverbOutputGain = newReverbOutputGain; - if (analog != NULL) analog->setReverbOutputGain(newReverbOutputGain, isMT32ReverbCompatibilityMode()); -} - -float Synth::getReverbOutputGain() const { - return reverbOutputGain; -} - -void Synth::setReversedStereoEnabled(bool enabled) { - reversedStereoEnabled = enabled; -} - -bool Synth::isReversedStereoEnabled() const { - return reversedStereoEnabled; -} - -void Synth::setNiceAmpRampEnabled(bool enabled) { - extensions.niceAmpRamp = enabled; -} - -bool Synth::isNiceAmpRampEnabled() const { - return extensions.niceAmpRamp; -} - -bool Synth::loadControlROM(const ROMImage &controlROMImage) { - File *file = controlROMImage.getFile(); - const ROMInfo *controlROMInfo = controlROMImage.getROMInfo(); - if ((controlROMInfo == NULL) - || (controlROMInfo->type != ROMInfo::Control) - || (controlROMInfo->pairType != ROMInfo::Full)) { -#if MT32EMU_MONITOR_INIT - printDebug("Invalid Control ROM Info provided"); -#endif - return false; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Found Control ROM: %s, %s", controlROMInfo->shortName, controlROMInfo->description); -#endif - const Bit8u *fileData = file->getData(); - memcpy(controlROMData, fileData, CONTROL_ROM_SIZE); - - // Control ROM successfully loaded, now check whether it's a known type - controlROMMap = NULL; - controlROMFeatures = NULL; - for (unsigned int i = 0; i < sizeof(ControlROMMaps) / sizeof(ControlROMMaps[0]); i++) { - if (strcmp(controlROMInfo->shortName, ControlROMMaps[i].shortName) == 0) { - controlROMMap = &ControlROMMaps[i]; - controlROMFeatures = &controlROMMap->featureSet; - return true; - } - } -#if MT32EMU_MONITOR_INIT - printDebug("Control ROM failed to load"); -#endif - return false; -} - -bool Synth::loadPCMROM(const ROMImage &pcmROMImage) { - File *file = pcmROMImage.getFile(); - const ROMInfo *pcmROMInfo = pcmROMImage.getROMInfo(); - if ((pcmROMInfo == NULL) - || (pcmROMInfo->type != ROMInfo::PCM) - || (pcmROMInfo->pairType != ROMInfo::Full)) { - return false; - } -#if MT32EMU_MONITOR_INIT - printDebug("Found PCM ROM: %s, %s", pcmROMInfo->shortName, pcmROMInfo->description); -#endif - size_t fileSize = file->getSize(); - if (fileSize != (2 * pcmROMSize)) { -#if MT32EMU_MONITOR_INIT - printDebug("PCM ROM file has wrong size (expected %d, got %d)", 2 * pcmROMSize, fileSize); -#endif - return false; - } - const Bit8u *fileData = file->getData(); - for (size_t i = 0; i < pcmROMSize; i++) { - Bit8u s = *(fileData++); - Bit8u c = *(fileData++); - - int order[16] = {0, 9, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8}; - - Bit16s log = 0; - for (int u = 0; u < 15; u++) { - int bit; - if (order[u] < 8) { - bit = (s >> (7 - order[u])) & 0x1; - } else { - bit = (c >> (7 - (order[u] - 8))) & 0x1; - } - log = log | Bit16s(bit << (15 - u)); - } - pcmROMData[i] = log; - } - return true; -} - -bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) { - ControlROMPCMStruct *tps = reinterpret_cast(&controlROMData[mapAddress]); - for (int i = 0; i < count; i++) { - Bit32u rAddr = tps[i].pos * 0x800; - Bit32u rLenExp = (tps[i].len & 0x70) >> 4; - Bit32u rLen = 0x800 << rLenExp; - if (rAddr + rLen > pcmROMSize) { - printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen); - return false; - } - pcmWaves[i].addr = rAddr; - pcmWaves[i].len = rLen; - pcmWaves[i].loop = (tps[i].len & 0x80) != 0; - pcmWaves[i].controlROMPCMStruct = &tps[i]; - //int pitch = (tps[i].pitchMSB << 8) | tps[i].pitchLSB; - //bool unaffectedByMasterTune = (tps[i].len & 0x01) == 0; - //printDebug("PCM %d: pos=%d, len=%d, pitch=%d, loop=%s, unaffectedByMasterTune=%s", i, rAddr, rLen, pitch, pcmWaves[i].loop ? "YES" : "NO", unaffectedByMasterTune ? "YES" : "NO"); - } - return false; -} - -bool Synth::initCompressedTimbre(Bit16u timbreNum, const Bit8u *src, Bit32u srcLen) { - // "Compressed" here means that muted partials aren't present in ROM (except in the case of partial 0 being muted). - // Instead the data from the previous unmuted partial is used. - if (srcLen < sizeof(TimbreParam::CommonParam)) { - return false; - } - TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre; - timbresMemoryRegion->write(timbreNum, 0, src, sizeof(TimbreParam::CommonParam), true); - unsigned int srcPos = sizeof(TimbreParam::CommonParam); - unsigned int memPos = sizeof(TimbreParam::CommonParam); - for (int t = 0; t < 4; t++) { - if (t != 0 && ((timbre->common.partialMute >> t) & 0x1) == 0x00) { - // This partial is muted - we'll copy the previously copied partial, then - srcPos -= sizeof(TimbreParam::PartialParam); - } else if (srcPos + sizeof(TimbreParam::PartialParam) >= srcLen) { - return false; - } - timbresMemoryRegion->write(timbreNum, memPos, src + srcPos, sizeof(TimbreParam::PartialParam)); - srcPos += sizeof(TimbreParam::PartialParam); - memPos += sizeof(TimbreParam::PartialParam); - } - return true; -} - -bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u count, Bit16u startTimbre, bool compressed) { - const Bit8u *timbreMap = &controlROMData[mapAddress]; - for (Bit16u i = 0; i < count * 2; i += 2) { - Bit16u address = (timbreMap[i + 1] << 8) | timbreMap[i]; - if (!compressed && (address + offset + sizeof(TimbreParam) > CONTROL_ROM_SIZE)) { - printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre address 0x%04x", i, startTimbre, address); - return false; - } - address += offset; - if (compressed) { - if (!initCompressedTimbre(startTimbre, &controlROMData[address], CONTROL_ROM_SIZE - address)) { - printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre at 0x%04x", i, startTimbre, address); - return false; - } - } else { - timbresMemoryRegion->write(startTimbre, 0, &controlROMData[address], sizeof(TimbreParam), true); - } - startTimbre++; - } - return true; -} - -void Synth::initReverbModels(bool mt32CompatibleMode) { - reverbModels[REVERB_MODE_ROOM] = BReverbModel::createBReverbModel(REVERB_MODE_ROOM, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_HALL] = BReverbModel::createBReverbModel(REVERB_MODE_HALL, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_PLATE] = BReverbModel::createBReverbModel(REVERB_MODE_PLATE, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_TAP_DELAY] = BReverbModel::createBReverbModel(REVERB_MODE_TAP_DELAY, mt32CompatibleMode, getSelectedRendererType()); -#if !MT32EMU_REDUCE_REVERB_MEMORY - for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { - reverbModels[i]->open(); - } -#endif -} - -void Synth::initSoundGroups(char newSoundGroupNames[][9]) { - memcpy(soundGroupIx, &controlROMData[controlROMMap->soundGroupsTable - sizeof(soundGroupIx)], sizeof(soundGroupIx)); - const SoundGroup *table = reinterpret_cast(&controlROMData[controlROMMap->soundGroupsTable]); - for (unsigned int i = 0; i < controlROMMap->soundGroupsCount; i++) { - memcpy(&newSoundGroupNames[i][0], table[i].name, sizeof(table[i].name)); - } -} - -bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode) { - return open(controlROMImage, pcmROMImage, DEFAULT_MAX_PARTIALS, analogOutputMode); -} - -bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, Bit32u usePartialCount, AnalogOutputMode analogOutputMode) { - if (opened) { - return false; - } - partialCount = usePartialCount; - abortingPoly = NULL; - - // This is to help detect bugs - memset(&mt32ram, '?', sizeof(mt32ram)); - -#if MT32EMU_MONITOR_INIT - printDebug("Loading Control ROM"); -#endif - if (!loadControlROM(controlROMImage)) { - printDebug("Init Error - Missing or invalid Control ROM image"); - reportHandler->onErrorControlROM(); - dispose(); - return false; - } - - initMemoryRegions(); - - // 512KB PCM ROM for MT-32, etc. - // 1MB PCM ROM for CM-32L, LAPC-I, CM-64, CM-500 - // Note that the size below is given in samples (16-bit), not bytes - pcmROMSize = controlROMMap->pcmCount == 256 ? 512 * 1024 : 256 * 1024; - pcmROMData = new Bit16s[pcmROMSize]; - -#if MT32EMU_MONITOR_INIT - printDebug("Loading PCM ROM"); -#endif - if (!loadPCMROM(pcmROMImage)) { - printDebug("Init Error - Missing PCM ROM image"); - reportHandler->onErrorPCMROM(); - dispose(); - return false; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Reverb Models"); -#endif - bool mt32CompatibleReverb = controlROMFeatures->defaultReverbMT32Compatible; -#if MT32EMU_MONITOR_INIT - printDebug("Using %s Compatible Reverb Models", mt32CompatibleReverb ? "MT-32" : "CM-32L"); -#endif - initReverbModels(mt32CompatibleReverb); - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Timbre Bank A"); -#endif - if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0x40, 0, controlROMMap->timbreACompressed)) { - dispose(); - return false; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Timbre Bank B"); -#endif - if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 0x40, 64, controlROMMap->timbreBCompressed)) { - dispose(); - return false; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Timbre Bank R"); -#endif - if (!initTimbres(controlROMMap->timbreRMap, 0, controlROMMap->timbreRCount, 192, true)) { - dispose(); - return false; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Timbre Bank M"); -#endif - // CM-64 seems to initialise all bytes in this bank to 0. - memset(&mt32ram.timbres[128], 0, sizeof(mt32ram.timbres[128]) * 64); - - partialManager = new PartialManager(this, parts); - - pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount]; - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising PCM List"); -#endif - initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount); - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Rhythm Temp"); -#endif - memcpy(mt32ram.rhythmTemp, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4); - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising Patches"); -#endif - for (Bit8u i = 0; i < 128; i++) { - PatchParam *patch = &mt32ram.patches[i]; - patch->timbreGroup = i / 64; - patch->timbreNum = i % 64; - patch->keyShift = 24; - patch->fineTune = 50; - patch->benderRange = 12; - patch->assignMode = 0; - patch->reverbSwitch = 1; - patch->dummy = 0; - } - -#if MT32EMU_MONITOR_INIT - printDebug("Initialising System"); -#endif - // The MT-32 manual claims that "Standard pitch" is 442Hz. - mt32ram.system.masterTune = 0x4A; // Confirmed on CM-64 - mt32ram.system.reverbMode = 0; // Confirmed - mt32ram.system.reverbTime = 5; // Confirmed - mt32ram.system.reverbLevel = 3; // Confirmed - memcpy(mt32ram.system.reserveSettings, &controlROMData[controlROMMap->reserveSettings], 9); // Confirmed - for (Bit8u i = 0; i < 9; i++) { - // This is the default: {1, 2, 3, 4, 5, 6, 7, 8, 9} - // An alternative configuration can be selected by holding "Master Volume" - // and pressing "PART button 1" on the real MT-32's frontpanel. - // The channel assignment is then {0, 1, 2, 3, 4, 5, 6, 7, 9} - mt32ram.system.chanAssign[i] = i + 1; - } - mt32ram.system.masterVol = 100; // Confirmed - - bool oldReverbOverridden = reverbOverridden; - reverbOverridden = false; - refreshSystem(); - resetMasterTunePitchDelta(); - reverbOverridden = oldReverbOverridden; - - char(*writableSoundGroupNames)[9] = new char[controlROMMap->soundGroupsCount][9]; - soundGroupNames = writableSoundGroupNames; - initSoundGroups(writableSoundGroupNames); - - for (int i = 0; i < 9; i++) { - MemParams::PatchTemp *patchTemp = &mt32ram.patchTemp[i]; - - // Note that except for the rhythm part, these patch fields will be set in setProgram() below anyway. - patchTemp->patch.timbreGroup = 0; - patchTemp->patch.timbreNum = 0; - patchTemp->patch.keyShift = 24; - patchTemp->patch.fineTune = 50; - patchTemp->patch.benderRange = 12; - patchTemp->patch.assignMode = 0; - patchTemp->patch.reverbSwitch = 1; - patchTemp->patch.dummy = 0; - - patchTemp->outputLevel = 80; - patchTemp->panpot = controlROMData[controlROMMap->panSettings + i]; - memset(patchTemp->dummyv, 0, sizeof(patchTemp->dummyv)); - patchTemp->dummyv[1] = 127; - - if (i < 8) { - parts[i] = new Part(this, i); - parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]); - } else { - parts[i] = new RhythmPart(this, i); - } - } - - // For resetting mt32 mid-execution - mt32default = mt32ram; - - midiQueue = new MidiEventQueue(); - - analog = Analog::createAnalog(analogOutputMode, controlROMFeatures->oldMT32AnalogLPF, getSelectedRendererType()); -#if MT32EMU_MONITOR_INIT - static const char *ANALOG_OUTPUT_MODES[] = { "Digital only", "Coarse", "Accurate", "Oversampled2x" }; - printDebug("Using Analog output mode %s", ANALOG_OUTPUT_MODES[analogOutputMode]); -#endif - setOutputGain(outputGain); - setReverbOutputGain(reverbOutputGain); - - switch (getSelectedRendererType()) { - case RendererType_BIT16S: - renderer = new RendererImpl(*this); -#if MT32EMU_MONITOR_INIT - printDebug("Using integer 16-bit samples in renderer and wave generator"); -#endif - break; - case RendererType_FLOAT: - renderer = new RendererImpl(*this); -#if MT32EMU_MONITOR_INIT - printDebug("Using float 32-bit samples in renderer and wave generator"); -#endif - break; - default: - printDebug("Synth: Unknown renderer type %i\n", getSelectedRendererType()); - dispose(); - return false; - } - - opened = true; - activated = false; - -#if MT32EMU_MONITOR_INIT - printDebug("*** Initialisation complete ***"); -#endif - return true; -} - -void Synth::dispose() { - opened = false; - - delete midiQueue; - midiQueue = NULL; - - delete renderer; - renderer = NULL; - - delete analog; - analog = NULL; - - delete partialManager; - partialManager = NULL; - - for (int i = 0; i < 9; i++) { - delete parts[i]; - parts[i] = NULL; - } - - delete[] soundGroupNames; - soundGroupNames = NULL; - - delete[] pcmWaves; - pcmWaves = NULL; - - delete[] pcmROMData; - pcmROMData = NULL; - - deleteMemoryRegions(); - - for (int i = 0; i < 4; i++) { - delete reverbModels[i]; - reverbModels[i] = NULL; - } - reverbModel = NULL; - controlROMFeatures = NULL; - controlROMMap = NULL; -} - -void Synth::close() { - if (opened) { - dispose(); - } -} - -bool Synth::isOpen() const { - return opened; -} - -void Synth::flushMIDIQueue() { - if (midiQueue != NULL) { - for (;;) { - const MidiEvent *midiEvent = midiQueue->peekMidiEvent(); - if (midiEvent == NULL) break; - if (midiEvent->sysexData == NULL) { - playMsgNow(midiEvent->shortMessageData); - } else { - playSysexNow(midiEvent->sysexData, midiEvent->sysexLength); - } - midiQueue->dropMidiEvent(); - } - lastReceivedMIDIEventTimestamp = renderedSampleCount; - } -} - -Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) { - static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value - - if (midiQueue == NULL) return 0; - flushMIDIQueue(); - - // Find a power of 2 that is >= useSize - Bit32u binarySize = 1; - if (useSize < MAX_QUEUE_SIZE) { - // Using simple linear search as this isn't time critical - while (binarySize < useSize) binarySize <<= 1; - } else { - binarySize = MAX_QUEUE_SIZE; - } - delete midiQueue; - midiQueue = new MidiEventQueue(binarySize); - return binarySize; -} - -Bit32u Synth::getShortMessageLength(Bit32u msg) { - if ((msg & 0xF0) == 0xF0) { - switch (msg & 0xFF) { - case 0xF1: - case 0xF3: - return 2; - case 0xF2: - return 3; - default: - return 1; - } - } - // NOTE: This calculation isn't quite correct - // as it doesn't consider the running status byte - return ((msg & 0xE0) == 0xC0) ? 2 : 3; -} - -Bit32u Synth::addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp) { - Bit32u transferTime = Bit32u(double(len) * MIDI_DATA_TRANSFER_RATE); - // Dealing with wrapping - if (Bit32s(timestamp - lastReceivedMIDIEventTimestamp) < 0) { - timestamp = lastReceivedMIDIEventTimestamp; - } - timestamp += transferTime; - lastReceivedMIDIEventTimestamp = timestamp; - return timestamp; -} - -Bit32u Synth::getInternalRenderedSampleCount() const { - return renderedSampleCount; -} - -bool Synth::playMsg(Bit32u msg) { - return playMsg(msg, renderedSampleCount); -} - -bool Synth::playMsg(Bit32u msg, Bit32u timestamp) { - if ((msg & 0xF8) == 0xF8) { - reportHandler->onMIDISystemRealtime(Bit8u(msg & 0xFF)); - return true; - } - if (midiQueue == NULL) return false; - if (midiDelayMode != MIDIDelayMode_IMMEDIATE) { - timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp); - } - if (!activated) activated = true; - do { - if (midiQueue->pushShortMessage(msg, timestamp)) return true; - } while (reportHandler->onMIDIQueueOverflow()); - return false; -} - -bool Synth::playSysex(const Bit8u *sysex, Bit32u len) { - return playSysex(sysex, len, renderedSampleCount); -} - -bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) { - if (midiQueue == NULL) return false; - if (midiDelayMode == MIDIDelayMode_DELAY_ALL) { - timestamp = addMIDIInterfaceDelay(len, timestamp); - } - if (!activated) activated = true; - do { - if (midiQueue->pushSysex(sysex, len, timestamp)) return true; - } while (reportHandler->onMIDIQueueOverflow()); - return false; -} - -void Synth::playMsgNow(Bit32u msg) { - if (!opened) return; - - // NOTE: Active sense IS implemented in real hardware. However, realtime processing is clearly out of the library scope. - // It is assumed that realtime consumers of the library respond to these MIDI events as appropriate. - - Bit8u code = Bit8u((msg & 0x0000F0) >> 4); - Bit8u chan = Bit8u(msg & 0x00000F); - Bit8u note = Bit8u((msg & 0x007F00) >> 8); - Bit8u velocity = Bit8u((msg & 0x7F0000) >> 16); - - //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note); - - Bit8u part = chantable[chan]; - if (part > 8) { -#if MT32EMU_MONITOR_MIDI > 0 - printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity); -#endif - return; - } - playMsgOnPart(part, code, note, velocity); -} - -void Synth::playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity) { - if (!opened) return; - - Bit32u bend; - - if (!activated) activated = true; - //printDebug("Synth::playMsgOnPart(%02x, %02x, %02x, %02x)", part, code, note, velocity); - switch (code) { - case 0x8: - //printDebug("Note OFF - Part %d", part); - // The MT-32 ignores velocity for note off - parts[part]->noteOff(note); - break; - case 0x9: - //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity); - if (velocity == 0) { - // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40 - parts[part]->noteOff(note); - } else { - parts[part]->noteOn(note, velocity); - } - break; - case 0xB: // Control change - switch (note) { - case 0x01: // Modulation - //printDebug("Modulation: %d", velocity); - parts[part]->setModulation(velocity); - break; - case 0x06: - parts[part]->setDataEntryMSB(velocity); - break; - case 0x07: // Set volume - //printDebug("Volume set: %d", velocity); - parts[part]->setVolume(velocity); - break; - case 0x0A: // Pan - //printDebug("Pan set: %d", velocity); - parts[part]->setPan(velocity); - break; - case 0x0B: - //printDebug("Expression set: %d", velocity); - parts[part]->setExpression(velocity); - break; - case 0x40: // Hold (sustain) pedal - //printDebug("Hold pedal set: %d", velocity); - parts[part]->setHoldPedal(velocity >= 64); - break; - - case 0x62: - case 0x63: - parts[part]->setNRPN(); - break; - case 0x64: - parts[part]->setRPNLSB(velocity); - break; - case 0x65: - parts[part]->setRPNMSB(velocity); - break; - - case 0x79: // Reset all controllers - //printDebug("Reset all controllers"); - parts[part]->resetAllControllers(); - break; - - case 0x7B: // All notes off - //printDebug("All notes off"); - parts[part]->allNotesOff(); - break; - - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - // CONFIRMED:Mok: A real LAPC-I responds to these controllers as follows: - parts[part]->setHoldPedal(false); - parts[part]->allNotesOff(); - break; - - default: -#if MT32EMU_MONITOR_MIDI > 0 - printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity); -#endif - return; - } - - break; - case 0xC: // Program change - //printDebug("Program change %01x", note); - parts[part]->setProgram(note); - break; - case 0xE: // Pitch bender - bend = (velocity << 7) | (note); - //printDebug("Pitch bender %02x", bend); - parts[part]->setBend(bend); - break; - default: -#if MT32EMU_MONITOR_MIDI > 0 - printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity); -#endif - return; - } - reportHandler->onMIDIMessagePlayed(); -} - -void Synth::playSysexNow(const Bit8u *sysex, Bit32u len) { - if (len < 2) { - printDebug("playSysex: Message is too short for sysex (%d bytes)", len); - } - if (sysex[0] != 0xF0) { - printDebug("playSysex: Message lacks start-of-sysex (0xF0)"); - return; - } - // Due to some programs (e.g. Java) sending buffers with junk at the end, we have to go through and find the end marker rather than relying on len. - Bit32u endPos; - for (endPos = 1; endPos < len; endPos++) { - if (sysex[endPos] == 0xF7) { - break; - } - } - if (endPos == len) { - printDebug("playSysex: Message lacks end-of-sysex (0xf7)"); - return; - } - playSysexWithoutFraming(sysex + 1, endPos - 1); -} - -void Synth::playSysexWithoutFraming(const Bit8u *sysex, Bit32u len) { - if (len < 4) { - printDebug("playSysexWithoutFraming: Message is too short (%d bytes)!", len); - return; - } - if (sysex[0] != SYSEX_MANUFACTURER_ROLAND) { - printDebug("playSysexWithoutFraming: Header not intended for this device manufacturer: %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); - return; - } - if (sysex[2] == SYSEX_MDL_D50) { - printDebug("playSysexWithoutFraming: Header is intended for model D-50 (not yet supported): %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); - return; - } else if (sysex[2] != SYSEX_MDL_MT32) { - printDebug("playSysexWithoutFraming: Header not intended for model MT-32: %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); - return; - } - playSysexWithoutHeader(sysex[1], sysex[3], sysex + 4, len - 4); -} - -void Synth::playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sysex, Bit32u len) { - if (device > 0x10) { - // We have device ID 0x10 (default, but changeable, on real MT-32), < 0x10 is for channels - printDebug("playSysexWithoutHeader: Message is not intended for this device ID (provided: %02x, expected: 0x10 or channel)", int(device)); - return; - } - // This is checked early in the real devices (before any sysex length checks or further processing) - // FIXME: Response to SYSEX_CMD_DAT reset with partials active (and in general) is untested. - if ((command == SYSEX_CMD_DT1 || command == SYSEX_CMD_DAT) && sysex[0] == 0x7F) { - reset(); - return; - } - - if (command == SYSEX_CMD_EOD) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("playSysexWithoutHeader: Ignored unsupported command %02x", command); -#endif - return; - } - if (len < 4) { - printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len); - return; - } - Bit8u checksum = calcSysexChecksum(sysex, len - 1); - if (checksum != sysex[len - 1]) { - printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum); - return; - } - len -= 1; // Exclude checksum - switch (command) { - case SYSEX_CMD_WSD: -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("playSysexWithoutHeader: Ignored unsupported command %02x", command); -#endif - break; - case SYSEX_CMD_DAT: - /* Outcommented until we (ever) actually implement handshake communication - if (hasActivePartials()) { - printDebug("playSysexWithoutHeader: Got SYSEX_CMD_DAT but partials are active - ignoring"); - // FIXME: We should send SYSEX_CMD_RJC in this case - break; - } - */ - // Deliberate fall-through - case SYSEX_CMD_DT1: - writeSysex(device, sysex, len); - break; - case SYSEX_CMD_RQD: - if (hasActivePartials()) { - printDebug("playSysexWithoutHeader: Got SYSEX_CMD_RQD but partials are active - ignoring"); - // FIXME: We should send SYSEX_CMD_RJC in this case - break; - } - // Deliberate fall-through - case SYSEX_CMD_RQ1: - readSysex(device, sysex, len); - break; - default: - printDebug("playSysexWithoutHeader: Unsupported command %02x", command); - return; - } -} - -void Synth::readSysex(Bit8u /*device*/, const Bit8u * /*sysex*/, Bit32u /*len*/) const { - // NYI -} - -void Synth::writeSysex(Bit8u device, const Bit8u *sysex, Bit32u len) { - if (!opened) return; - reportHandler->onMIDIMessagePlayed(); - Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]); - addr = MT32EMU_MEMADDR(addr); - sysex += 3; - len -= 3; - //printDebug("Sysex addr: 0x%06x", MT32EMU_SYSEXMEMADDR(addr)); - // NOTE: Please keep both lower and upper bounds in each check, for ease of reading - - // Process channel-specific sysex by converting it to device-global - if (device < 0x10) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr)); -#endif - if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) { - int offset; - if (chantable[device] > 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel not mapped to a part... 0 offset)"); -#endif - offset = 0; - } else if (chantable[device] == 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel mapped to rhythm... 0 offset)"); -#endif - offset = 0; - } else { - offset = chantable[device] * sizeof(MemParams::PatchTemp); -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Setting extra offset to %d)", offset); -#endif - } - addr += MT32EMU_MEMADDR(0x030000) + offset; - } else if (/*addr >= MT32EMU_MEMADDR(0x010000) && */ addr < MT32EMU_MEMADDR(0x020000)) { - addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000); - } else if (/*addr >= MT32EMU_MEMADDR(0x020000) && */ addr < MT32EMU_MEMADDR(0x030000)) { - int offset; - if (chantable[device] > 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel not mapped to a part... 0 offset)"); -#endif - offset = 0; - } else if (chantable[device] == 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel mapped to rhythm... 0 offset)"); -#endif - offset = 0; - } else { - offset = chantable[device] * sizeof(TimbreParam); -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Setting extra offset to %d)", offset); -#endif - } - addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset; - } else { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" Invalid channel"); -#endif - return; - } - } - - // Process device-global sysex (possibly converted from channel-specific sysex above) - for (;;) { - // Find the appropriate memory region - const MemoryRegion *region = findMemoryRegion(addr); - - if (region == NULL) { - printDebug("Sysex write to unrecognised address %06x, len %d", MT32EMU_SYSEXMEMADDR(addr), len); - break; - } - writeMemoryRegion(region, addr, region->getClampedLen(addr, len), sysex); - - Bit32u next = region->next(addr, len); - if (next == 0) { - break; - } - addr += next; - sysex += next; - len -= next; - } -} - -void Synth::readMemory(Bit32u addr, Bit32u len, Bit8u *data) { - if (!opened) return; - const MemoryRegion *region = findMemoryRegion(addr); - if (region != NULL) { - readMemoryRegion(region, addr, len, data); - } -} - -void Synth::initMemoryRegions() { - // Timbre max tables are slightly more complicated than the others, which are used directly from the ROM. - // The ROM (sensibly) just has maximums for TimbreParam.commonParam followed by just one TimbreParam.partialParam, - // so we produce a table with all partialParams filled out, as well as padding for PaddedTimbre, for quick lookup. - paddedTimbreMaxTable = new Bit8u[sizeof(MemParams::PaddedTimbre)]; - memcpy(&paddedTimbreMaxTable[0], &controlROMData[controlROMMap->timbreMaxTable], sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam)); // commonParam and one partialParam - int pos = sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam); - for (int i = 0; i < 3; i++) { - memcpy(&paddedTimbreMaxTable[pos], &controlROMData[controlROMMap->timbreMaxTable + sizeof(TimbreParam::CommonParam)], sizeof(TimbreParam::PartialParam)); - pos += sizeof(TimbreParam::PartialParam); - } - memset(&paddedTimbreMaxTable[pos], 0, 10); // Padding - patchTempMemoryRegion = new PatchTempMemoryRegion(this, reinterpret_cast(&mt32ram.patchTemp[0]), &controlROMData[controlROMMap->patchMaxTable]); - rhythmTempMemoryRegion = new RhythmTempMemoryRegion(this, reinterpret_cast(&mt32ram.rhythmTemp[0]), &controlROMData[controlROMMap->rhythmMaxTable]); - timbreTempMemoryRegion = new TimbreTempMemoryRegion(this, reinterpret_cast(&mt32ram.timbreTemp[0]), paddedTimbreMaxTable); - patchesMemoryRegion = new PatchesMemoryRegion(this, reinterpret_cast(&mt32ram.patches[0]), &controlROMData[controlROMMap->patchMaxTable]); - timbresMemoryRegion = new TimbresMemoryRegion(this, reinterpret_cast(&mt32ram.timbres[0]), paddedTimbreMaxTable); - systemMemoryRegion = new SystemMemoryRegion(this, reinterpret_cast(&mt32ram.system), &controlROMData[controlROMMap->systemMaxTable]); - displayMemoryRegion = new DisplayMemoryRegion(this); - resetMemoryRegion = new ResetMemoryRegion(this); -} - -void Synth::deleteMemoryRegions() { - delete patchTempMemoryRegion; - patchTempMemoryRegion = NULL; - delete rhythmTempMemoryRegion; - rhythmTempMemoryRegion = NULL; - delete timbreTempMemoryRegion; - timbreTempMemoryRegion = NULL; - delete patchesMemoryRegion; - patchesMemoryRegion = NULL; - delete timbresMemoryRegion; - timbresMemoryRegion = NULL; - delete systemMemoryRegion; - systemMemoryRegion = NULL; - delete displayMemoryRegion; - displayMemoryRegion = NULL; - delete resetMemoryRegion; - resetMemoryRegion = NULL; - - delete[] paddedTimbreMaxTable; - paddedTimbreMaxTable = NULL; -} - -MemoryRegion *Synth::findMemoryRegion(Bit32u addr) { - MemoryRegion *regions[] = { - patchTempMemoryRegion, - rhythmTempMemoryRegion, - timbreTempMemoryRegion, - patchesMemoryRegion, - timbresMemoryRegion, - systemMemoryRegion, - displayMemoryRegion, - resetMemoryRegion, - NULL - }; - for (int pos = 0; regions[pos] != NULL; pos++) { - if (regions[pos]->contains(addr)) { - return regions[pos]; - } - } - return NULL; -} - -void Synth::readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data) { - unsigned int first = region->firstTouched(addr); - //unsigned int last = region->lastTouched(addr, len); - unsigned int off = region->firstTouchedOffset(addr); - len = region->getClampedLen(addr, len); - - unsigned int m; - - if (region->isReadable()) { - region->read(first, off, data, len); - } else { - // FIXME: We might want to do these properly in future - for (m = 0; m < len; m += 2) { - data[m] = 0xff; - if (m + 1 < len) { - data[m+1] = Bit8u(region->type); - } - } - } -} - -void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data) { - unsigned int first = region->firstTouched(addr); - unsigned int last = region->lastTouched(addr, len); - unsigned int off = region->firstTouchedOffset(addr); - switch (region->type) { - case MR_PatchTemp: - region->write(first, off, data, len); - //printDebug("Patch temp: Patch %d, offset %x, len %d", off/16, off % 16, len); - - for (unsigned int i = first; i <= last; i++) { - int absTimbreNum = mt32ram.patchTemp[i].patch.timbreGroup * 64 + mt32ram.patchTemp[i].patch.timbreNum; - char timbreName[11]; - memcpy(timbreName, mt32ram.timbres[absTimbreNum].timbre.common.name, 10); - timbreName[10] = 0; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s), outlevel=%d", first, last, off, off + len, i, absTimbreNum, timbreName, mt32ram.patchTemp[i].outputLevel); -#endif - if (parts[i] != NULL) { - if (i != 8) { - // Note: Confirmed on CM-64 that we definitely *should* update the timbre here, - // but only in the case that the sysex actually writes to those values - if (i == first && off > 2) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Not updating timbre, since those values weren't touched)"); -#endif - } else { - parts[i]->setTimbre(&mt32ram.timbres[parts[i]->getAbsTimbreNum()].timbre); - } - } - parts[i]->refresh(); - } - } - break; - case MR_RhythmTemp: - region->write(first, off, data, len); - for (unsigned int i = first; i <= last; i++) { - int timbreNum = mt32ram.rhythmTemp[i].timbre; - char timbreName[11]; - if (timbreNum < 94) { - memcpy(timbreName, mt32ram.timbres[128 + timbreNum].timbre.common.name, 10); - timbreName[10] = 0; - } else { - strcpy(timbreName, "[None]"); - } -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", first, last, off, off + len, i, mt32ram.rhythmTemp[i].outputLevel, mt32ram.rhythmTemp[i].panpot, mt32ram.rhythmTemp[i].reverbSwitch, mt32ram.rhythmTemp[i].timbre, timbreName); -#endif - } - if (parts[8] != NULL) { - parts[8]->refresh(); - } - break; - case MR_TimbreTemp: - region->write(first, off, data, len); - for (unsigned int i = first; i <= last; i++) { - char instrumentName[11]; - memcpy(instrumentName, mt32ram.timbreTemp[i].common.name, 10); - instrumentName[10] = 0; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", first, last, off, off + len, i, instrumentName); -#endif - if (parts[i] != NULL) { - parts[i]->refresh(); - } - } - break; - case MR_Patches: - region->write(first, off, data, len); -#if MT32EMU_MONITOR_SYSEX > 0 - for (unsigned int i = first; i <= last; i++) { - PatchParam *patch = &mt32ram.patches[i]; - int patchAbsTimbreNum = patch->timbreGroup * 64 + patch->timbreNum; - char instrumentName[11]; - memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10); - instrumentName[10] = 0; - Bit8u *n = (Bit8u *)patch; - printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]); - } -#endif - break; - case MR_Timbres: - // Timbres - first += 128; - last += 128; - region->write(first, off, data, len); - for (unsigned int i = first; i <= last; i++) { -#if MT32EMU_MONITOR_TIMBRES >= 1 - TimbreParam *timbre = &mt32ram.timbres[i].timbre; - char instrumentName[11]; - memcpy(instrumentName, timbre->common.name, 10); - instrumentName[10] = 0; - printDebug("WRITE-TIMBRE (%d-%d@%d..%d): %d; name=\"%s\"", first, last, off, off + len, i, instrumentName); -#if MT32EMU_MONITOR_TIMBRES >= 2 -#define DT(x) printDebug(" " #x ": %d", timbre->x) - DT(common.partialStructure12); - DT(common.partialStructure34); - DT(common.partialMute); - DT(common.noSustain); - -#define DTP(x) \ - DT(partial[x].wg.pitchCoarse); \ - DT(partial[x].wg.pitchFine); \ - DT(partial[x].wg.pitchKeyfollow); \ - DT(partial[x].wg.pitchBenderEnabled); \ - DT(partial[x].wg.waveform); \ - DT(partial[x].wg.pcmWave); \ - DT(partial[x].wg.pulseWidth); \ - DT(partial[x].wg.pulseWidthVeloSensitivity); \ - DT(partial[x].pitchEnv.depth); \ - DT(partial[x].pitchEnv.veloSensitivity); \ - DT(partial[x].pitchEnv.timeKeyfollow); \ - DT(partial[x].pitchEnv.time[0]); \ - DT(partial[x].pitchEnv.time[1]); \ - DT(partial[x].pitchEnv.time[2]); \ - DT(partial[x].pitchEnv.time[3]); \ - DT(partial[x].pitchEnv.level[0]); \ - DT(partial[x].pitchEnv.level[1]); \ - DT(partial[x].pitchEnv.level[2]); \ - DT(partial[x].pitchEnv.level[3]); \ - DT(partial[x].pitchEnv.level[4]); \ - DT(partial[x].pitchLFO.rate); \ - DT(partial[x].pitchLFO.depth); \ - DT(partial[x].pitchLFO.modSensitivity); \ - DT(partial[x].tvf.cutoff); \ - DT(partial[x].tvf.resonance); \ - DT(partial[x].tvf.keyfollow); \ - DT(partial[x].tvf.biasPoint); \ - DT(partial[x].tvf.biasLevel); \ - DT(partial[x].tvf.envDepth); \ - DT(partial[x].tvf.envVeloSensitivity); \ - DT(partial[x].tvf.envDepthKeyfollow); \ - DT(partial[x].tvf.envTimeKeyfollow); \ - DT(partial[x].tvf.envTime[0]); \ - DT(partial[x].tvf.envTime[1]); \ - DT(partial[x].tvf.envTime[2]); \ - DT(partial[x].tvf.envTime[3]); \ - DT(partial[x].tvf.envTime[4]); \ - DT(partial[x].tvf.envLevel[0]); \ - DT(partial[x].tvf.envLevel[1]); \ - DT(partial[x].tvf.envLevel[2]); \ - DT(partial[x].tvf.envLevel[3]); \ - DT(partial[x].tva.level); \ - DT(partial[x].tva.veloSensitivity); \ - DT(partial[x].tva.biasPoint1); \ - DT(partial[x].tva.biasLevel1); \ - DT(partial[x].tva.biasPoint2); \ - DT(partial[x].tva.biasLevel2); \ - DT(partial[x].tva.envTimeKeyfollow); \ - DT(partial[x].tva.envTimeVeloSensitivity); \ - DT(partial[x].tva.envTime[0]); \ - DT(partial[x].tva.envTime[1]); \ - DT(partial[x].tva.envTime[2]); \ - DT(partial[x].tva.envTime[3]); \ - DT(partial[x].tva.envTime[4]); \ - DT(partial[x].tva.envLevel[0]); \ - DT(partial[x].tva.envLevel[1]); \ - DT(partial[x].tva.envLevel[2]); \ - DT(partial[x].tva.envLevel[3]); - - DTP(0); - DTP(1); - DTP(2); - DTP(3); -#undef DTP -#undef DT -#endif -#endif - // FIXME:KG: Not sure if the stuff below should be done (for rhythm and/or parts)... - // Does the real MT-32 automatically do this? - for (unsigned int part = 0; part < 9; part++) { - if (parts[part] != NULL) { - parts[part]->refreshTimbre(i); - } - } - } - break; - case MR_System: - region->write(0, off, data, len); - - reportHandler->onDeviceReconfig(); - // FIXME: We haven't properly confirmed any of this behaviour - // In particular, we tend to reset things such as reverb even if the write contained - // the same parameters as were already set, which may be wrong. - // On the other hand, the real thing could be resetting things even when they aren't touched - // by the write at all. -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-SYSTEM:"); -#endif - if (off <= SYSTEM_MASTER_TUNE_OFF && off + len > SYSTEM_MASTER_TUNE_OFF) { - refreshSystemMasterTune(); - } - if (off <= SYSTEM_REVERB_LEVEL_OFF && off + len > SYSTEM_REVERB_MODE_OFF) { - refreshSystemReverbParameters(); - } - if (off <= SYSTEM_RESERVE_SETTINGS_END_OFF && off + len > SYSTEM_RESERVE_SETTINGS_START_OFF) { - refreshSystemReserveSettings(); - } - if (off <= SYSTEM_CHAN_ASSIGN_END_OFF && off + len > SYSTEM_CHAN_ASSIGN_START_OFF) { - int firstPart = off - SYSTEM_CHAN_ASSIGN_START_OFF; - if(firstPart < 0) - firstPart = 0; - int lastPart = off + len - SYSTEM_CHAN_ASSIGN_START_OFF; - if(lastPart > 8) - lastPart = 8; - refreshSystemChanAssign(Bit8u(firstPart), Bit8u(lastPart)); - } - if (off <= SYSTEM_MASTER_VOL_OFF && off + len > SYSTEM_MASTER_VOL_OFF) { - refreshSystemMasterVol(); - } - break; - case MR_Display: - char buf[SYSEX_BUFFER_SIZE]; - memcpy(&buf, &data[0], len); - buf[len] = 0; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("WRITE-LCD: %s", buf); -#endif - reportHandler->showLCDMessage(buf); - break; - case MR_Reset: - reset(); - break; - } -} - -void Synth::refreshSystemMasterTune() { - // 171 is ~half a semitone. - extensions.masterTunePitchDelta = ((mt32ram.system.masterTune - 64) * 171) >> 6; // PORTABILITY NOTE: Assumes arithmetic shift. -#if MT32EMU_MONITOR_SYSEX > 0 - //FIXME:KG: This is just an educated guess. - // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here) - // The MT-32 documentation claims a range of 432.1Hz-457.6Hz - float masterTune = 440.0f * EXP2F((mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f)); - printDebug(" Master Tune: %f", masterTune); -#endif -} - -void Synth::refreshSystemReverbParameters() { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel); -#endif - if (reverbOverridden) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Reverb overridden - ignoring)"); -#endif - return; - } - reportHandler->onNewReverbMode(mt32ram.system.reverbMode); - reportHandler->onNewReverbTime(mt32ram.system.reverbTime); - reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel); - - BReverbModel *oldReverbModel = reverbModel; - if (mt32ram.system.reverbTime == 0 && mt32ram.system.reverbLevel == 0) { - // Setting both time and level to 0 effectively disables wet reverb output on real devices. - // Take a shortcut in this case to reduce CPU load. - reverbModel = NULL; - } else { - reverbModel = reverbModels[mt32ram.system.reverbMode]; - } - if (reverbModel != oldReverbModel) { -#if MT32EMU_REDUCE_REVERB_MEMORY - if (oldReverbModel != NULL) { - oldReverbModel->close(); - } - if (isReverbEnabled()) { - reverbModel->open(); - } -#else - if (isReverbEnabled()) { - reverbModel->mute(); - } -#endif - } - if (isReverbEnabled()) { - reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel); - } -} - -void Synth::refreshSystemReserveSettings() { - Bit8u *rset = mt32ram.system.reserveSettings; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" Partial reserve: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]); -#endif - partialManager->setReserve(rset); -} - -void Synth::refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart) { - memset(chantable, 0xFF, sizeof(chantable)); - - // CONFIRMED: In the case of assigning a channel to multiple parts, the lower part wins. - for (Bit32u i = 0; i <= 8; i++) { - if (parts[i] != NULL && i >= firstPart && i <= lastPart) { - // CONFIRMED: Decay is started for all polys, and all controllers are reset, for every part whose assignment was touched by the sysex write. - parts[i]->allSoundOff(); - parts[i]->resetAllControllers(); - } - Bit8u chan = mt32ram.system.chanAssign[i]; - if (chan < 16 && chantable[chan] > 8) { - chantable[chan] = Bit8u(i); - } - } - -#if MT32EMU_MONITOR_SYSEX > 0 - Bit8u *rset = mt32ram.system.chanAssign; - printDebug(" Part assign: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]); -#endif -} - -void Synth::refreshSystemMasterVol() { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" Master volume: %d", mt32ram.system.masterVol); -#endif -} - -void Synth::refreshSystem() { - refreshSystemMasterTune(); - refreshSystemReverbParameters(); - refreshSystemReserveSettings(); - refreshSystemChanAssign(0, 8); - refreshSystemMasterVol(); -} - -void Synth::reset() { - if (!opened) return; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug("RESET"); -#endif - reportHandler->onDeviceReset(); - partialManager->deactivateAll(); - mt32ram = mt32default; - for (int i = 0; i < 9; i++) { - parts[i]->reset(); - if (i != 8) { - parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]); - } else { - parts[8]->refresh(); - } - } - refreshSystem(); - resetMasterTunePitchDelta(); - isActive(); -} - -void Synth::resetMasterTunePitchDelta() { - // This effectively resets master tune to 440.0Hz. - // Despite that the manual claims 442.0Hz is the default setting for master tune, - // it doesn't actually take effect upon a reset due to a bug in the reset routine. - // CONFIRMED: This bug is present in all supported Control ROMs. - extensions.masterTunePitchDelta = 0; -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" Actual Master Tune reset to 440.0"); -#endif -} - -Bit32s Synth::getMasterTunePitchDelta() const { - return extensions.masterTunePitchDelta; -} - -MidiEvent::~MidiEvent() { - if (sysexData != NULL) { - delete[] sysexData; - } -} - -void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) { - if (sysexData != NULL) { - delete[] sysexData; - } - shortMessageData = useShortMessageData; - timestamp = useTimestamp; - sysexData = NULL; - sysexLength = 0; -} - -void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) { - if (sysexData != NULL) { - delete[] sysexData; - } - shortMessageData = 0; - timestamp = useTimestamp; - sysexLength = useSysexLength; - Bit8u *dstSysexData = new Bit8u[sysexLength]; - sysexData = dstSysexData; - memcpy(dstSysexData, useSysexData, sysexLength); -} - -MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) { - memset(ringBuffer, 0, useRingBufferSize * sizeof(MidiEvent)); - reset(); -} - -MidiEventQueue::~MidiEventQueue() { - delete[] ringBuffer; -} - -void MidiEventQueue::reset() { - startPosition = 0; - endPosition = 0; -} - -bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) { - Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; - // Is ring buffer full? - if (startPosition == newEndPosition) return false; - ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp); - endPosition = newEndPosition; - return true; -} - -bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) { - Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; - // Is ring buffer full? - if (startPosition == newEndPosition) return false; - ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp); - endPosition = newEndPosition; - return true; -} - -const MidiEvent *MidiEventQueue::peekMidiEvent() { - return isEmpty() ? NULL : &ringBuffer[startPosition]; -} - -void MidiEventQueue::dropMidiEvent() { - // Is ring buffer empty? - if (startPosition != endPosition) { - startPosition = (startPosition + 1) & ringBufferMask; - } -} - -bool MidiEventQueue::isFull() const { - return startPosition == ((endPosition + 1) & ringBufferMask); -} - -bool MidiEventQueue::isEmpty() const { - return startPosition == endPosition; -} - -void Synth::selectRendererType(RendererType newRendererType) { - extensions.selectedRendererType = newRendererType; -} - -RendererType Synth::getSelectedRendererType() const { - return extensions.selectedRendererType; -} - -Bit32u Synth::getStereoOutputSampleRate() const { - return (analog == NULL) ? SAMPLE_RATE : analog->getOutputSampleRate(); -} - -template -void RendererImpl::doRender(Sample *stereoStream, Bit32u len) { - if (!isActivated()) { - incRenderedSampleCount(getAnalog().getDACStreamsLength(len)); - if (!getAnalog().process(NULL, NULL, NULL, NULL, NULL, NULL, stereoStream, len)) { - printDebug("RendererImpl: Invalid call to Analog::process()!\n"); - } - Synth::muteSampleBuffer(stereoStream, len << 1); - return; - } - - while (len > 0) { - // As in AnalogOutputMode_ACCURATE mode output is upsampled, MAX_SAMPLES_PER_RUN is more than enough for the temp buffers. - Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; - doRenderStreams(tmpBuffers, getAnalog().getDACStreamsLength(thisPassLen)); - if (!getAnalog().process(stereoStream, tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisPassLen)) { - printDebug("RendererImpl: Invalid call to Analog::process()!\n"); - Synth::muteSampleBuffer(stereoStream, len << 1); - return; - } - stereoStream += thisPassLen << 1; - len -= thisPassLen; - } -} - -template -template -void RendererImpl::doRenderAndConvert(O *stereoStream, Bit32u len) { - Sample renderingBuffer[MAX_SAMPLES_PER_RUN << 1]; - while (len > 0) { - Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; - doRender(renderingBuffer, thisPassLen); - convertSampleFormat(renderingBuffer, stereoStream, thisPassLen << 1); - stereoStream += thisPassLen << 1; - len -= thisPassLen; - } -} - -template<> -void RendererImpl::render(IntSample *stereoStream, Bit32u len) { - doRender(stereoStream, len); -} - -template<> -void RendererImpl::render(FloatSample *stereoStream, Bit32u len) { - doRenderAndConvert(stereoStream, len); -} - -template<> -void RendererImpl::render(IntSample *stereoStream, Bit32u len) { - doRenderAndConvert(stereoStream, len); -} - -template<> -void RendererImpl::render(FloatSample *stereoStream, Bit32u len) { - doRender(stereoStream, len); -} - -template -static inline void renderStereo(bool opened, Renderer *renderer, S *stream, Bit32u len) { - if (opened) { - renderer->render(stream, len); - } else { - Synth::muteSampleBuffer(stream, len << 1); - } -} - -void Synth::render(Bit16s *stream, Bit32u len) { - renderStereo(opened, renderer, stream, len); -} - -void Synth::render(float *stream, Bit32u len) { - renderStereo(opened, renderer, stream, len); -} - -template -static inline void advanceStream(Sample *&stream, Bit32u len) { - if (stream != NULL) { - stream += len; - } -} - -template -static inline void advanceStreams(DACOutputStreams &streams, Bit32u len) { - advanceStream(streams.nonReverbLeft, len); - advanceStream(streams.nonReverbRight, len); - advanceStream(streams.reverbDryLeft, len); - advanceStream(streams.reverbDryRight, len); - advanceStream(streams.reverbWetLeft, len); - advanceStream(streams.reverbWetRight, len); -} - -template -static inline void muteStreams(const DACOutputStreams &streams, Bit32u len) { - Synth::muteSampleBuffer(streams.nonReverbLeft, len); - Synth::muteSampleBuffer(streams.nonReverbRight, len); - Synth::muteSampleBuffer(streams.reverbDryLeft, len); - Synth::muteSampleBuffer(streams.reverbDryRight, len); - Synth::muteSampleBuffer(streams.reverbWetLeft, len); - Synth::muteSampleBuffer(streams.reverbWetRight, len); -} - -template -static inline void convertStreamsFormat(const DACOutputStreams &inStreams, const DACOutputStreams &outStreams, Bit32u len) { - convertSampleFormat(inStreams.nonReverbLeft, outStreams.nonReverbLeft, len); - convertSampleFormat(inStreams.nonReverbRight, outStreams.nonReverbRight, len); - convertSampleFormat(inStreams.reverbDryLeft, outStreams.reverbDryLeft, len); - convertSampleFormat(inStreams.reverbDryRight, outStreams.reverbDryRight, len); - convertSampleFormat(inStreams.reverbWetLeft, outStreams.reverbWetLeft, len); - convertSampleFormat(inStreams.reverbWetRight, outStreams.reverbWetRight, len); -} - -template -void RendererImpl::doRenderStreams(const DACOutputStreams &streams, Bit32u len) -{ - DACOutputStreams tmpStreams = streams; - while (len > 0) { - // We need to ensure zero-duration notes will play so add minimum 1-sample delay. - Bit32u thisLen = 1; - if (!isAbortingPoly()) { - const MidiEvent *nextEvent = getMidiQueue().peekMidiEvent(); - Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - getRenderedSampleCount()) : MAX_SAMPLES_PER_RUN; - if (samplesToNextEvent > 0) { - thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; - if (thisLen > Bit32u(samplesToNextEvent)) { - thisLen = samplesToNextEvent; - } - } else { - if (nextEvent->sysexData == NULL) { - synth.playMsgNow(nextEvent->shortMessageData); - // If a poly is aborting we don't drop the event from the queue. - // Instead, we'll return to it again when the abortion is done. - if (!isAbortingPoly()) { - getMidiQueue().dropMidiEvent(); - } - } else { - synth.playSysexNow(nextEvent->sysexData, nextEvent->sysexLength); - getMidiQueue().dropMidiEvent(); - } - } - } - produceStreams(tmpStreams, thisLen); - advanceStreams(tmpStreams, thisLen); - len -= thisLen; - } -} - -template -template -void RendererImpl::doRenderAndConvertStreams(const DACOutputStreams &streams, Bit32u len) { - Sample cnvNonReverbLeft[MAX_SAMPLES_PER_RUN], cnvNonReverbRight[MAX_SAMPLES_PER_RUN]; - Sample cnvReverbDryLeft[MAX_SAMPLES_PER_RUN], cnvReverbDryRight[MAX_SAMPLES_PER_RUN]; - Sample cnvReverbWetLeft[MAX_SAMPLES_PER_RUN], cnvReverbWetRight[MAX_SAMPLES_PER_RUN]; - - const DACOutputStreams cnvStreams = { - cnvNonReverbLeft, cnvNonReverbRight, - cnvReverbDryLeft, cnvReverbDryRight, - cnvReverbWetLeft, cnvReverbWetRight - }; - - DACOutputStreams tmpStreams = streams; - - while (len > 0) { - Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; - doRenderStreams(cnvStreams, thisPassLen); - convertStreamsFormat(cnvStreams, tmpStreams, thisPassLen); - advanceStreams(tmpStreams, thisPassLen); - len -= thisPassLen; - } -} - -template<> -void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { - doRenderStreams(streams, len); -} - -template<> -void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { - doRenderAndConvertStreams(streams, len); -} - -template<> -void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { - doRenderAndConvertStreams(streams, len); -} - -template<> -void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { - doRenderStreams(streams, len); -} - -template -static inline void renderStreams(bool opened, Renderer *renderer, const DACOutputStreams &streams, Bit32u len) { - if (opened) { - renderer->renderStreams(streams, len); - } else { - muteStreams(streams, len); - } -} - -void Synth::renderStreams(const DACOutputStreams &streams, Bit32u len) { - MT32Emu::renderStreams(opened, renderer, streams, len); -} - -void Synth::renderStreams(const DACOutputStreams &streams, Bit32u len) { - MT32Emu::renderStreams(opened, renderer, streams, len); -} - -void Synth::renderStreams( - Bit16s *nonReverbLeft, Bit16s *nonReverbRight, - Bit16s *reverbDryLeft, Bit16s *reverbDryRight, - Bit16s *reverbWetLeft, Bit16s *reverbWetRight, - Bit32u len) -{ - DACOutputStreams streams = { - nonReverbLeft, nonReverbRight, - reverbDryLeft, reverbDryRight, - reverbWetLeft, reverbWetRight - }; - renderStreams(streams, len); -} - -void Synth::renderStreams( - float *nonReverbLeft, float *nonReverbRight, - float *reverbDryLeft, float *reverbDryRight, - float *reverbWetLeft, float *reverbWetRight, - Bit32u len) -{ - DACOutputStreams streams = { - nonReverbLeft, nonReverbRight, - reverbDryLeft, reverbDryRight, - reverbWetLeft, reverbWetRight - }; - renderStreams(streams, len); -} - -// In GENERATION2 units, the output from LA32 goes to the Boss chip already bit-shifted. -// In NICE mode, it's also better to increase volume before the reverb processing to preserve accuracy. -template <> -void RendererImpl::produceLA32Output(IntSample *buffer, Bit32u len) { - switch (synth.getDACInputMode()) { - case DACInputMode_GENERATION2: - while (len--) { - *buffer = (*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE) | ((*buffer >> 14) & 0x0001); - ++buffer; - } - break; - case DACInputMode_NICE: - while (len--) { - *buffer = Synth::clipSampleEx(IntSampleEx(*buffer) << 1); - ++buffer; - } - break; - default: - break; - } -} - -template <> -void RendererImpl::convertSamplesToOutput(IntSample *buffer, Bit32u len) { - if (synth.getDACInputMode() == DACInputMode_GENERATION1) { - while (len--) { - *buffer = IntSample((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE)); - ++buffer; - } - } -} - -static inline float produceDistortedSample(float sample) { - // Here we roughly simulate the distortion caused by the DAC bit shift. - if (sample < -1.0f) { - return sample + 2.0f; - } else if (1.0f < sample) { - return sample - 2.0f; - } - return sample; -} - -template <> -void RendererImpl::produceLA32Output(FloatSample *buffer, Bit32u len) { - switch (synth.getDACInputMode()) { - case DACInputMode_NICE: - // Note, we do not do any clamping for floats here to avoid introducing distortions. - // This means that the output signal may actually overshoot the unity when the volume is set too high. - // We leave it up to the consumer whether the output is to be clamped or properly normalised further on. - while (len--) { - *buffer *= 2.0f; - buffer++; - } - break; - case DACInputMode_GENERATION2: - while (len--) { - *buffer = produceDistortedSample(2.0f * *buffer); - buffer++; - } - break; - default: - break; - } -} - -template <> -void RendererImpl::convertSamplesToOutput(FloatSample *buffer, Bit32u len) { - if (synth.getDACInputMode() == DACInputMode_GENERATION1) { - while (len--) { - *buffer = produceDistortedSample(2.0f * *buffer); - buffer++; - } - } -} - -template -void RendererImpl::produceStreams(const DACOutputStreams &streams, Bit32u len) { - if (isActivated()) { - // Even if LA32 output isn't desired, we proceed anyway with temp buffers - Sample *nonReverbLeft = streams.nonReverbLeft == NULL ? tmpNonReverbLeft : streams.nonReverbLeft; - Sample *nonReverbRight = streams.nonReverbRight == NULL ? tmpNonReverbRight : streams.nonReverbRight; - Sample *reverbDryLeft = streams.reverbDryLeft == NULL ? tmpReverbDryLeft : streams.reverbDryLeft; - Sample *reverbDryRight = streams.reverbDryRight == NULL ? tmpReverbDryRight : streams.reverbDryRight; - - Synth::muteSampleBuffer(nonReverbLeft, len); - Synth::muteSampleBuffer(nonReverbRight, len); - Synth::muteSampleBuffer(reverbDryLeft, len); - Synth::muteSampleBuffer(reverbDryRight, len); - - for (unsigned int i = 0; i < synth.getPartialCount(); i++) { - if (getPartialManager().shouldReverb(i)) { - getPartialManager().produceOutput(i, reverbDryLeft, reverbDryRight, len); - } else { - getPartialManager().produceOutput(i, nonReverbLeft, nonReverbRight, len); - } - } - - produceLA32Output(reverbDryLeft, len); - produceLA32Output(reverbDryRight, len); - - if (synth.isReverbEnabled()) { - if (!getReverbModel().process(reverbDryLeft, reverbDryRight, streams.reverbWetLeft, streams.reverbWetRight, len)) { - printDebug("RendererImpl: Invalid call to BReverbModel::process()!\n"); - } - if (streams.reverbWetLeft != NULL) convertSamplesToOutput(streams.reverbWetLeft, len); - if (streams.reverbWetRight != NULL) convertSamplesToOutput(streams.reverbWetRight, len); - } else { - Synth::muteSampleBuffer(streams.reverbWetLeft, len); - Synth::muteSampleBuffer(streams.reverbWetRight, len); - } - - // Don't bother with conversion if the output is going to be unused - if (streams.nonReverbLeft != NULL) { - produceLA32Output(nonReverbLeft, len); - convertSamplesToOutput(nonReverbLeft, len); - } - if (streams.nonReverbRight != NULL) { - produceLA32Output(nonReverbRight, len); - convertSamplesToOutput(nonReverbRight, len); - } - if (streams.reverbDryLeft != NULL) convertSamplesToOutput(reverbDryLeft, len); - if (streams.reverbDryRight != NULL) convertSamplesToOutput(reverbDryRight, len); - } else { - muteStreams(streams, len); - } - - getPartialManager().clearAlreadyOutputed(); - incRenderedSampleCount(len); -} - -void Synth::printPartialUsage(Bit32u sampleOffset) { - unsigned int partialUsage[9]; - partialManager->getPerPartPartialUsage(partialUsage); - if (sampleOffset > 0) { - printDebug("[+%u] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount()); - } else { - printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount()); - } -} - -bool Synth::hasActivePartials() const { - if (!opened) { - return false; - } - for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) { - if (partialManager->getPartial(partialNum)->isActive()) { - return true; - } - } - return false; -} - -bool Synth::isActive() { - if (!opened) { - return false; - } - if (!midiQueue->isEmpty() || hasActivePartials()) { - return true; - } - if (isReverbEnabled() && reverbModel->isActive()) { - return true; - } - activated = false; - return false; -} - -Bit32u Synth::getPartialCount() const { - return partialCount; -} - -void Synth::getPartStates(bool *partStates) const { - if (!opened) { - memset(partStates, 0, 9 * sizeof(bool)); - return; - } - for (int partNumber = 0; partNumber < 9; partNumber++) { - const Part *part = parts[partNumber]; - partStates[partNumber] = part->getActiveNonReleasingPartialCount() > 0; - } -} - -Bit32u Synth::getPartStates() const { - if (!opened) return 0; - bool partStates[9]; - getPartStates(partStates); - Bit32u bitSet = 0; - for (int partNumber = 8; partNumber >= 0; partNumber--) { - bitSet = (bitSet << 1) | (partStates[partNumber] ? 1 : 0); - } - return bitSet; -} - -void Synth::getPartialStates(PartialState *partialStates) const { - if (!opened) { - memset(partialStates, 0, partialCount * sizeof(PartialState)); - return; - } - for (unsigned int partialNum = 0; partialNum < partialCount; partialNum++) { - partialStates[partialNum] = getPartialState(partialManager, partialNum); - } -} - -void Synth::getPartialStates(Bit8u *partialStates) const { - if (!opened) { - memset(partialStates, 0, ((partialCount + 3) >> 2)); - return; - } - for (unsigned int quartNum = 0; (4 * quartNum) < partialCount; quartNum++) { - Bit8u packedStates = 0; - for (unsigned int i = 0; i < 4; i++) { - unsigned int partialNum = (4 * quartNum) + i; - if (partialCount <= partialNum) break; - PartialState partialState = getPartialState(partialManager, partialNum); - packedStates |= (partialState & 3) << (2 * i); - } - partialStates[quartNum] = packedStates; - } -} - -Bit32u Synth::getPlayingNotes(Bit8u partNumber, Bit8u *keys, Bit8u *velocities) const { - Bit32u playingNotes = 0; - if (opened && (partNumber < 9)) { - const Part *part = parts[partNumber]; - const Poly *poly = part->getFirstActivePoly(); - while (poly != NULL) { - keys[playingNotes] = Bit8u(poly->getKey()); - velocities[playingNotes] = Bit8u(poly->getVelocity()); - playingNotes++; - poly = poly->getNext(); - } - } - return playingNotes; -} - -const char *Synth::getPatchName(Bit8u partNumber) const { - return (!opened || partNumber > 8) ? NULL : parts[partNumber]->getCurrentInstr(); -} - -const Part *Synth::getPart(Bit8u partNum) const { - if (partNum > 8) { - return NULL; - } - return parts[partNum]; -} - -void MemoryRegion::read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const { - off += entry * entrySize; - // This method should never be called with out-of-bounds parameters, - // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator - if (off > entrySize * entries - 1) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("read[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - return; - } - if (off + len > entrySize * entries) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("read[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - len = entrySize * entries - off; - } - Bit8u *src = getRealMemory(); - if (src == NULL) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("read[%d]: unreadable region: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - return; - } - memcpy(dst, src + off, len); -} - -void MemoryRegion::write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init) const { - unsigned int memOff = entry * entrySize + off; - // This method should never be called with out-of-bounds parameters, - // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator - if (off > entrySize * entries - 1) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("write[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - return; - } - if (off + len > entrySize * entries) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("write[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - len = entrySize * entries - off; - } - Bit8u *dest = getRealMemory(); - if (dest == NULL) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("write[%d]: unwritable region: entry=%d, off=%d, len=%d", type, entry, off, len); -#endif - return; - } - - for (unsigned int i = 0; i < len; i++) { - Bit8u desiredValue = src[i]; - Bit8u maxValue = getMaxValue(memOff); - // maxValue == 0 means write-protected unless called from initialisation code, in which case it really means the maximum value is 0. - if (maxValue != 0 || init) { - if (desiredValue > maxValue) { -#if MT32EMU_MONITOR_SYSEX > 0 - synth->printDebug("write[%d]: Wanted 0x%02x at %d, but max 0x%02x", type, desiredValue, memOff, maxValue); -#endif - desiredValue = maxValue; - } - dest[memOff] = desiredValue; - } else if (desiredValue != 0) { -#if MT32EMU_MONITOR_SYSEX > 0 - // Only output debug info if they wanted to write non-zero, since a lot of things cause this to spit out a lot of debug info otherwise. - synth->printDebug("write[%d]: Wanted 0x%02x at %d, but write-protected", type, desiredValue, memOff); -#endif - } - memOff++; - } -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Synth.h b/src - Cópia/sound/munt/Synth.h deleted file mode 100644 index cde080c9d..000000000 --- a/src - Cópia/sound/munt/Synth.h +++ /dev/null @@ -1,500 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_SYNTH_H -#define MT32EMU_SYNTH_H - -#include -#include -#include - -#include "globals.h" -#include "Types.h" -#include "Enumerations.h" - -namespace MT32Emu { - -class Analog; -class BReverbModel; -class Extensions; -class MemoryRegion; -class MidiEventQueue; -class Part; -class Poly; -class Partial; -class PartialManager; -class Renderer; -class ROMImage; - -class PatchTempMemoryRegion; -class RhythmTempMemoryRegion; -class TimbreTempMemoryRegion; -class PatchesMemoryRegion; -class TimbresMemoryRegion; -class SystemMemoryRegion; -class DisplayMemoryRegion; -class ResetMemoryRegion; - -struct ControlROMFeatureSet; -struct ControlROMMap; -struct PCMWaveEntry; -struct MemParams; - -const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41; - -const Bit8u SYSEX_MDL_MT32 = 0x16; -const Bit8u SYSEX_MDL_D50 = 0x14; - -const Bit8u SYSEX_CMD_RQ1 = 0x11; // Request data #1 -const Bit8u SYSEX_CMD_DT1 = 0x12; // Data set 1 -const Bit8u SYSEX_CMD_WSD = 0x40; // Want to send data -const Bit8u SYSEX_CMD_RQD = 0x41; // Request data -const Bit8u SYSEX_CMD_DAT = 0x42; // Data set -const Bit8u SYSEX_CMD_ACK = 0x43; // Acknowledge -const Bit8u SYSEX_CMD_EOD = 0x45; // End of data -const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error -const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection - -const Bit32u CONTROL_ROM_SIZE = 64 * 1024; - -// Set of multiplexed output streams appeared at the DAC entrance. -template -struct DACOutputStreams { - T *nonReverbLeft; - T *nonReverbRight; - T *reverbDryLeft; - T *reverbDryRight; - T *reverbWetLeft; - T *reverbWetRight; -}; - -// Class for the client to supply callbacks for reporting various errors and information -class MT32EMU_EXPORT ReportHandler { -public: - virtual ~ReportHandler() {} - - // Callback for debug messages, in vprintf() format - virtual void printDebug(const char *fmt, va_list list); - // Callbacks for reporting errors - virtual void onErrorControlROM() {} - virtual void onErrorPCMROM() {} - // Callback for reporting about displaying a new custom message on LCD - virtual void showLCDMessage(const char *message); - // Callback for reporting actual processing of a MIDI message - virtual void onMIDIMessagePlayed() {} - // Callback for reporting an overflow of the input MIDI queue. - // Returns true if a recovery action was taken and yet another attempt to enqueue the MIDI event is desired. - virtual bool onMIDIQueueOverflow() { return false; } - // Callback invoked when a System Realtime MIDI message is detected at the input. - virtual void onMIDISystemRealtime(Bit8u /* systemRealtime */) {} - // Callbacks for reporting system events - virtual void onDeviceReset() {} - virtual void onDeviceReconfig() {} - // Callbacks for reporting changes of reverb settings - virtual void onNewReverbMode(Bit8u /* mode */) {} - virtual void onNewReverbTime(Bit8u /* time */) {} - virtual void onNewReverbLevel(Bit8u /* level */) {} - // Callbacks for reporting various information - virtual void onPolyStateChanged(Bit8u /* partNum */) {} - virtual void onProgramChanged(Bit8u /* partNum */, const char * /* soundGroupName */, const char * /* patchName */) {} -}; - -class Synth { -friend class DefaultMidiStreamParser; -friend class Part; -friend class Partial; -friend class PartialManager; -friend class Poly; -friend class Renderer; -friend class RhythmPart; -friend class SamplerateAdapter; -friend class SoxrAdapter; -friend class TVA; -friend class TVF; -friend class TVP; - -private: - // **************************** Implementation fields ************************** - - PatchTempMemoryRegion *patchTempMemoryRegion; - RhythmTempMemoryRegion *rhythmTempMemoryRegion; - TimbreTempMemoryRegion *timbreTempMemoryRegion; - PatchesMemoryRegion *patchesMemoryRegion; - TimbresMemoryRegion *timbresMemoryRegion; - SystemMemoryRegion *systemMemoryRegion; - DisplayMemoryRegion *displayMemoryRegion; - ResetMemoryRegion *resetMemoryRegion; - - Bit8u *paddedTimbreMaxTable; - - PCMWaveEntry *pcmWaves; // Array - - const ControlROMFeatureSet *controlROMFeatures; - const ControlROMMap *controlROMMap; - Bit8u controlROMData[CONTROL_ROM_SIZE]; - Bit16s *pcmROMData; - size_t pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM - - Bit8u soundGroupIx[128]; // For each standard timbre - const char (*soundGroupNames)[9]; // Array - - Bit32u partialCount; - Bit8u chantable[16]; // NOTE: value above 8 means that the channel is not assigned - - MidiEventQueue *midiQueue; - volatile Bit32u lastReceivedMIDIEventTimestamp; - volatile Bit32u renderedSampleCount; - - MemParams &mt32ram, &mt32default; - - BReverbModel *reverbModels[4]; - BReverbModel *reverbModel; - bool reverbOverridden; - - MIDIDelayMode midiDelayMode; - DACInputMode dacInputMode; - - float outputGain; - float reverbOutputGain; - - bool reversedStereoEnabled; - - bool opened; - bool activated; - - bool isDefaultReportHandler; - ReportHandler *reportHandler; - - PartialManager *partialManager; - Part *parts[9]; - - // When a partial needs to be aborted to free it up for use by a new Poly, - // the controller will busy-loop waiting for the sound to finish. - // We emulate this by delaying new MIDI events processing until abortion finishes. - Poly *abortingPoly; - - Analog *analog; - Renderer *renderer; - - // Binary compatibility helper. - Extensions &extensions; - - // **************************** Implementation methods ************************** - - Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp); - bool isAbortingPoly() const { return abortingPoly != NULL; } - - void readSysex(Bit8u channel, const Bit8u *sysex, Bit32u len) const; - void initMemoryRegions(); - void deleteMemoryRegions(); - MemoryRegion *findMemoryRegion(Bit32u addr); - void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data); - void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data); - - bool loadControlROM(const ROMImage &controlROMImage); - bool loadPCMROM(const ROMImage &pcmROMImage); - - bool initPCMList(Bit16u mapAddress, Bit16u count); - bool initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u timbreCount, Bit16u startTimbre, bool compressed); - bool initCompressedTimbre(Bit16u drumNum, const Bit8u *mem, Bit32u memLen); - void initReverbModels(bool mt32CompatibleMode); - void initSoundGroups(char newSoundGroupNames[][9]); - - void refreshSystemMasterTune(); - void refreshSystemReverbParameters(); - void refreshSystemReserveSettings(); - void refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart); - void refreshSystemMasterVol(); - void refreshSystem(); - void reset(); - void dispose(); - - void printPartialUsage(Bit32u sampleOffset = 0); - - void newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, const char patchName[]); - void printDebug(const char *fmt, ...); - - // partNum should be 0..7 for Part 1..8, or 8 for Rhythm - const Part *getPart(Bit8u partNum) const; - - void resetMasterTunePitchDelta(); - Bit32s getMasterTunePitchDelta() const; - -public: - static inline Bit16s clipSampleEx(Bit32s sampleEx) { - // Clamp values above 32767 to 32767, and values below -32768 to -32768 - // FIXME: Do we really need this stuff? I think these branches are very well predicted. Instead, this introduces a chain. - // The version below is actually a bit faster on my system... - //return ((sampleEx + 0x8000) & ~0xFFFF) ? Bit16s((sampleEx >> 31) ^ 0x7FFF) : (Bit16s)sampleEx; - return ((-0x8000 <= sampleEx) && (sampleEx <= 0x7FFF)) ? Bit16s(sampleEx) : Bit16s((sampleEx >> 31) ^ 0x7FFF); - } - - static inline float clipSampleEx(float sampleEx) { - return sampleEx; - } - - template - static inline void muteSampleBuffer(S *buffer, Bit32u len) { - if (buffer == NULL) return; - memset(buffer, 0, len * sizeof(S)); - } - - static inline void muteSampleBuffer(float *buffer, Bit32u len) { - if (buffer == NULL) return; - // FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win) - while (len--) { - *(buffer++) = 0.0f; - } - } - - static inline Bit16s convertSample(float sample) { - return Synth::clipSampleEx(Bit32s(sample * 32768.0f)); // This multiplier corresponds to normalised floats - } - - static inline float convertSample(Bit16s sample) { - return float(sample) / 32768.0f; // This multiplier corresponds to normalised floats - } - - // Returns library version as an integer in format: 0x00MMmmpp, where: - // MM - major version number - // mm - minor version number - // pp - patch number - MT32EMU_EXPORT static Bit32u getLibraryVersionInt(); - // Returns library version as a C-string in format: "MAJOR.MINOR.PATCH" - MT32EMU_EXPORT static const char *getLibraryVersionString(); - - MT32EMU_EXPORT static Bit32u getShortMessageLength(Bit32u msg); - MT32EMU_EXPORT static Bit8u calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum = 0); - - // Returns output sample rate used in emulation of stereo analog circuitry of hardware units. - // See comment for AnalogOutputMode. - MT32EMU_EXPORT static Bit32u getStereoOutputSampleRate(AnalogOutputMode analogOutputMode); - - // Optionally sets callbacks for reporting various errors, information and debug messages - MT32EMU_EXPORT explicit Synth(ReportHandler *useReportHandler = NULL); - MT32EMU_EXPORT ~Synth(); - - // Used to initialise the MT-32. Must be called before any other function. - // Returns true if initialization was sucessful, otherwise returns false. - // controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth. - // usePartialCount sets the maximum number of partials playing simultaneously for this session (optional). - // analogOutputMode sets the mode for emulation of analogue circuitry of the hardware units (optional). - MT32EMU_EXPORT bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, Bit32u usePartialCount = DEFAULT_MAX_PARTIALS, AnalogOutputMode analogOutputMode = AnalogOutputMode_COARSE); - - // Overloaded method which opens the synth with default partial count. - MT32EMU_EXPORT bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode); - - // Closes the MT-32 and deallocates any memory used by the synthesizer - MT32EMU_EXPORT void close(); - - // Returns true if the synth is in completely initialized state, otherwise returns false. - MT32EMU_EXPORT bool isOpen() const; - - // All the enqueued events are processed by the synth immediately. - MT32EMU_EXPORT void flushMIDIQueue(); - - // Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified. - // The queue is flushed before reallocation. - // Returns the actual queue size being used. - MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u); - - // Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz). - // This method helps to compute accurate timestamp of a MIDI message to use with the methods below. - MT32EMU_EXPORT Bit32u getInternalRenderedSampleCount() const; - - // Enqueues a MIDI event for subsequent playback. - // The MIDI event will be processed not before the specified timestamp. - // The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz). - // The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface - // and emulation of the MCU busy-loop while it frees partials for use by a new Poly. - // Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread. - // The methods return false if the MIDI event queue is full and the message cannot be enqueued. - - // Enqueues a single short MIDI message to play at specified time. The message must contain a status byte. - MT32EMU_EXPORT bool playMsg(Bit32u msg, Bit32u timestamp); - // Enqueues a single well formed System Exclusive MIDI message to play at specified time. - MT32EMU_EXPORT bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp); - - // Enqueues a single short MIDI message to be processed ASAP. The message must contain a status byte. - MT32EMU_EXPORT bool playMsg(Bit32u msg); - // Enqueues a single well formed System Exclusive MIDI message to be processed ASAP. - MT32EMU_EXPORT bool playSysex(const Bit8u *sysex, Bit32u len); - - // WARNING: - // The methods below don't ensure minimum 1-sample delay between sequential MIDI events, - // and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent. - // A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering. - - // Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte. - // See the WARNING above. - MT32EMU_EXPORT void playMsgNow(Bit32u msg); - // Sends unpacked short MIDI message to the synth for immediate playback. The message must contain a status byte. - // See the WARNING above. - MT32EMU_EXPORT void playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity); - - // Sends a single well formed System Exclusive MIDI message for immediate processing. The length is in bytes. - // See the WARNING above. - MT32EMU_EXPORT void playSysexNow(const Bit8u *sysex, Bit32u len); - // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. - // See the WARNING above. - MT32EMU_EXPORT void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len); - // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. - // See the WARNING above. - MT32EMU_EXPORT void playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sysex, Bit32u len); - // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. - // See the WARNING above. - MT32EMU_EXPORT void writeSysex(Bit8u channel, const Bit8u *sysex, Bit32u len); - - // Allows to disable wet reverb output altogether. - MT32EMU_EXPORT void setReverbEnabled(bool reverbEnabled); - // Returns whether wet reverb output is enabled. - MT32EMU_EXPORT bool isReverbEnabled() const; - // Sets override reverb mode. In this mode, emulation ignores sysexes (or the related part of them) which control the reverb parameters. - // This mode is in effect until it is turned off. When the synth is re-opened, the override mode is unchanged but the state - // of the reverb model is reset to default. - MT32EMU_EXPORT void setReverbOverridden(bool reverbOverridden); - // Returns whether reverb settings are overridden. - MT32EMU_EXPORT bool isReverbOverridden() const; - // Forces reverb model compatibility mode. By default, the compatibility mode corresponds to the used control ROM version. - // Invoking this method with the argument set to true forces emulation of old MT-32 reverb circuit. - // When the argument is false, emulation of the reverb circuit used in new generation of MT-32 compatible modules is enforced - // (these include CM-32L and LAPC-I). - MT32EMU_EXPORT void setReverbCompatibilityMode(bool mt32CompatibleMode); - // Returns whether reverb is in old MT-32 compatibility mode. - MT32EMU_EXPORT bool isMT32ReverbCompatibilityMode() const; - // Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. - MT32EMU_EXPORT bool isDefaultReverbMT32Compatible() const; - // Sets new DAC input mode. See DACInputMode for details. - MT32EMU_EXPORT void setDACInputMode(DACInputMode mode); - // Returns current DAC input mode. See DACInputMode for details. - MT32EMU_EXPORT DACInputMode getDACInputMode() const; - // Sets new MIDI delay mode. See MIDIDelayMode for details. - MT32EMU_EXPORT void setMIDIDelayMode(MIDIDelayMode mode); - // Returns current MIDI delay mode. See MIDIDelayMode for details. - MT32EMU_EXPORT MIDIDelayMode getMIDIDelayMode() const; - - // Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume, - // it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with setReverbOutputGain() - // it offers to the user a capability to control the gain of reverb and non-reverb output channels independently. - MT32EMU_EXPORT void setOutputGain(float gain); - // Returns current output gain factor for synth output channels. - MT32EMU_EXPORT float getOutputGain() const; - - // Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output - // analog circuitry of the hardware units. However, together with setOutputGain() it offers to the user a capability - // to control the gain of reverb and non-reverb output channels independently. - // - // Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely - // corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic, - // there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68 - // of that for LA32 analogue output. This factor is applied to the reverb output gain. - MT32EMU_EXPORT void setReverbOutputGain(float gain); - // Returns current output gain factor for reverb wet output channels. - MT32EMU_EXPORT float getReverbOutputGain() const; - - // Swaps left and right output channels. - MT32EMU_EXPORT void setReversedStereoEnabled(bool enabled); - // Returns whether left and right output channels are swapped. - MT32EMU_EXPORT bool isReversedStereoEnabled() const; - - // Allows to toggle the NiceAmpRamp mode. - // In this mode, we want to ensure that amp ramp never jumps to the target - // value and always gradually increases or decreases. It seems that real units - // do not bother to always check if a newly started ramp leads to a jump. - // We also prefer the quality improvement over the emulation accuracy, - // so this mode is enabled by default. - MT32EMU_EXPORT void setNiceAmpRampEnabled(bool enabled); - // Returns whether NiceAmpRamp mode is enabled. - MT32EMU_EXPORT bool isNiceAmpRampEnabled() const; - - // Selects new type of the wave generator and renderer to be used during subsequent calls to open(). - // By default, RendererType_BIT16S is selected. - // See RendererType for details. - MT32EMU_EXPORT void selectRendererType(RendererType); - // Returns previously selected type of the wave generator and renderer. - // See RendererType for details. - MT32EMU_EXPORT RendererType getSelectedRendererType() const; - - // Returns actual sample rate used in emulation of stereo analog circuitry of hardware units. - // See comment for render() below. - MT32EMU_EXPORT Bit32u getStereoOutputSampleRate() const; - - // Renders samples to the specified output stream as if they were sampled at the analog stereo output. - // When AnalogOutputMode is set to ACCURATE (OVERSAMPLED), the output signal is upsampled to 48 (96) kHz in order - // to retain emulation accuracy in whole audible frequency spectra. Otherwise, native digital signal sample rate is retained. - // getStereoOutputSampleRate() can be used to query actual sample rate of the output signal. - // The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes). Uses NATIVE byte ordering. - MT32EMU_EXPORT void render(Bit16s *stream, Bit32u len); - // Same as above but outputs to a float stereo stream. - MT32EMU_EXPORT void render(float *stream, Bit32u len); - - // Renders samples to the specified output streams as if they appeared at the DAC entrance. - // No further processing performed in analog circuitry emulation is applied to the signal. - // NULL may be specified in place of any or all of the stream buffers to skip it. - // The length is in samples, not bytes. Uses NATIVE byte ordering. - MT32EMU_EXPORT void renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len); - MT32EMU_EXPORT void renderStreams(const DACOutputStreams &streams, Bit32u len); - // Same as above but outputs to float streams. - MT32EMU_EXPORT void renderStreams(float *nonReverbLeft, float *nonReverbRight, float *reverbDryLeft, float *reverbDryRight, float *reverbWetLeft, float *reverbWetRight, Bit32u len); - MT32EMU_EXPORT void renderStreams(const DACOutputStreams &streams, Bit32u len); - - // Returns true when there is at least one active partial, otherwise false. - MT32EMU_EXPORT bool hasActivePartials() const; - - // Returns true if the synth is active and subsequent calls to render() may result in non-trivial output (i.e. silence). - // The synth is considered active when either there are pending MIDI events in the queue, there is at least one active partial, - // or the reverb is (somewhat unreliably) detected as being active. - MT32EMU_EXPORT bool isActive(); - - // Returns the maximum number of partials playing simultaneously. - MT32EMU_EXPORT Bit32u getPartialCount() const; - - // Fills in current states of all the parts into the array provided. The array must have at least 9 entries to fit values for all the parts. - // If the value returned for a part is true, there is at least one active non-releasing partial playing on this part. - // This info is useful in emulating behaviour of LCD display of the hardware units. - MT32EMU_EXPORT void getPartStates(bool *partStates) const; - - // Returns current states of all the parts as a bit set. The least significant bit corresponds to the state of part 1, - // total of 9 bits hold the states of all the parts. If the returned bit for a part is set, there is at least one active - // non-releasing partial playing on this part. This info is useful in emulating behaviour of LCD display of the hardware units. - MT32EMU_EXPORT Bit32u getPartStates() const; - - // Fills in current states of all the partials into the array provided. The array must be large enough to accommodate states of all the partials. - MT32EMU_EXPORT void getPartialStates(PartialState *partialStates) const; - - // Fills in current states of all the partials into the array provided. Each byte in the array holds states of 4 partials - // starting from the least significant bits. The state of each partial is packed in a pair of bits. - // The array must be large enough to accommodate states of all the partials (see getPartialCount()). - MT32EMU_EXPORT void getPartialStates(Bit8u *partialStates) const; - - // Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough - // to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials. - // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. - // Returns the number of currently playing notes on the specified part. - MT32EMU_EXPORT Bit32u getPlayingNotes(Bit8u partNumber, Bit8u *keys, Bit8u *velocities) const; - - // Returns name of the patch set on the specified part. - // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. - MT32EMU_EXPORT const char *getPatchName(Bit8u partNumber) const; - - // Stores internal state of emulated synth into an array provided (as it would be acquired from hardware). - MT32EMU_EXPORT void readMemory(Bit32u addr, Bit32u len, Bit8u *data); -}; // class Synth - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_SYNTH_H diff --git a/src - Cópia/sound/munt/TVA.cpp b/src - Cópia/sound/munt/TVA.cpp deleted file mode 100644 index 3f7064f9a..000000000 --- a/src - Cópia/sound/munt/TVA.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/* - * This class emulates the calculations performed by the 8095 microcontroller in order to configure the LA-32's amplitude ramp for a single partial at each stage of its TVA envelope. - * Unless we introduced bugs, it should be pretty much 100% accurate according to Mok's specifications. -*/ - -#include "internals.h" - -#include "TVA.h" -#include "Part.h" -#include "Partial.h" -#include "Poly.h" -#include "Synth.h" -#include "Tables.h" - -namespace MT32Emu { - -// CONFIRMED: Matches a table in ROM - haven't got around to coming up with a formula for it yet. -static Bit8u biasLevelToAmpSubtractionCoeff[13] = {255, 187, 137, 100, 74, 54, 40, 29, 21, 15, 10, 5, 0}; - -TVA::TVA(const Partial *usePartial, LA32Ramp *useAmpRamp) : - partial(usePartial), ampRamp(useAmpRamp), system(&usePartial->getSynth()->mt32ram.system), phase(TVA_PHASE_DEAD) { -} - -void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { - target = newTarget; - phase = newPhase; - ampRamp->startRamp(newTarget, newIncrement); -#if MT32EMU_MONITOR_TVA >= 1 - partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,ramp,%x,%s%x,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? "-" : "+", (newIncrement & 0x7F), newPhase); -#endif -} - -void TVA::end(int newPhase) { - phase = newPhase; - playing = false; -#if MT32EMU_MONITOR_TVA >= 1 - partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,end,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newPhase); -#endif -} - -static int multBias(Bit8u biasLevel, int bias) { - return (bias * biasLevelToAmpSubtractionCoeff[biasLevel]) >> 5; -} - -static int calcBiasAmpSubtraction(Bit8u biasPoint, Bit8u biasLevel, int key) { - if ((biasPoint & 0x40) == 0) { - int bias = biasPoint + 33 - key; - if (bias > 0) { - return multBias(biasLevel, bias); - } - } else { - int bias = biasPoint - 31 - key; - if (bias < 0) { - bias = -bias; - return multBias(biasLevel, bias); - } - } - return 0; -} - -static int calcBiasAmpSubtractions(const TimbreParam::PartialParam *partialParam, int key) { - int biasAmpSubtraction1 = calcBiasAmpSubtraction(partialParam->tva.biasPoint1, partialParam->tva.biasLevel1, key); - if (biasAmpSubtraction1 > 255) { - return 255; - } - int biasAmpSubtraction2 = calcBiasAmpSubtraction(partialParam->tva.biasPoint2, partialParam->tva.biasLevel2, key); - if (biasAmpSubtraction2 > 255) { - return 255; - } - int biasAmpSubtraction = biasAmpSubtraction1 + biasAmpSubtraction2; - if (biasAmpSubtraction > 255) { - return 255; - } - return biasAmpSubtraction; -} - -static int calcVeloAmpSubtraction(Bit8u veloSensitivity, unsigned int velocity) { - // FIXME:KG: Better variable names - int velocityMult = veloSensitivity - 50; - int absVelocityMult = velocityMult < 0 ? -velocityMult : velocityMult; - velocityMult = signed(unsigned(velocityMult * (signed(velocity) - 64)) << 2); - return absVelocityMult - (velocityMult >> 8); // PORTABILITY NOTE: Assumes arithmetic shift -} - -static int calcBasicAmp(const Tables *tables, const Partial *partial, const MemParams::System *system, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, const MemParams::RhythmTemp *rhythmTemp, int biasAmpSubtraction, int veloAmpSubtraction, Bit8u expression, bool hasRingModQuirk) { - int amp = 155; - - if (!(hasRingModQuirk ? partial->isRingModulatingNoMix() : partial->isRingModulatingSlave())) { - amp -= tables->masterVolToAmpSubtraction[system->masterVol]; - if (amp < 0) { - return 0; - } - amp -= tables->levelToAmpSubtraction[patchTemp->outputLevel]; - if (amp < 0) { - return 0; - } - amp -= tables->levelToAmpSubtraction[expression]; - if (amp < 0) { - return 0; - } - if (rhythmTemp != NULL) { - amp -= tables->levelToAmpSubtraction[rhythmTemp->outputLevel]; - if (amp < 0) { - return 0; - } - } - } - amp -= biasAmpSubtraction; - if (amp < 0) { - return 0; - } - amp -= tables->levelToAmpSubtraction[partialParam->tva.level]; - if (amp < 0) { - return 0; - } - amp -= veloAmpSubtraction; - if (amp < 0) { - return 0; - } - if (amp > 155) { - amp = 155; - } - amp -= partialParam->tvf.resonance >> 1; - if (amp < 0) { - return 0; - } - return amp; -} - -static int calcKeyTimeSubtraction(Bit8u envTimeKeyfollow, int key) { - if (envTimeKeyfollow == 0) { - return 0; - } - return (key - 60) >> (5 - envTimeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift -} - -void TVA::reset(const Part *newPart, const TimbreParam::PartialParam *newPartialParam, const MemParams::RhythmTemp *newRhythmTemp) { - part = newPart; - partialParam = newPartialParam; - patchTemp = newPart->getPatchTemp(); - rhythmTemp = newRhythmTemp; - - playing = true; - - const Tables *tables = &Tables::getInstance(); - - int key = partial->getPoly()->getKey(); - int velocity = partial->getPoly()->getVelocity(); - - keyTimeSubtraction = calcKeyTimeSubtraction(partialParam->tva.envTimeKeyfollow, key); - - biasAmpSubtraction = calcBiasAmpSubtractions(partialParam, key); - veloAmpSubtraction = calcVeloAmpSubtraction(partialParam->tva.veloSensitivity, velocity); - - int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, newRhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix); - int newPhase; - if (partialParam->tva.envTime[0] == 0) { - // Initially go to the TVA_PHASE_ATTACK target amp, and spend the next phase going from there to the TVA_PHASE_2 target amp - // Note that this means that velocity never affects time for this partial. - newTarget += partialParam->tva.envLevel[0]; - newPhase = TVA_PHASE_ATTACK; // The first target used in nextPhase() will be TVA_PHASE_2 - } else { - // Initially go to the base amp determined by TVA level, part volume, etc., and spend the next phase going from there to the full TVA_PHASE_ATTACK target amp. - newPhase = TVA_PHASE_BASIC; // The first target used in nextPhase() will be TVA_PHASE_ATTACK - } - - ampRamp->reset();//currentAmp = 0; - - // "Go downward as quickly as possible". - // Since the current value is 0, the LA32Ramp will notice that we're already at or below the target and trying to go downward, - // and therefore jump to the target immediately and raise an interrupt. - startRamp(Bit8u(newTarget), 0x80 | 127, newPhase); -} - -void TVA::startAbort() { - startRamp(64, 0x80 | 127, TVA_PHASE_RELEASE); -} - -void TVA::startDecay() { - if (phase >= TVA_PHASE_RELEASE) { - return; - } - Bit8u newIncrement; - if (partialParam->tva.envTime[4] == 0) { - newIncrement = 1; - } else { - newIncrement = -partialParam->tva.envTime[4]; - } - // The next time nextPhase() is called, it will think TVA_PHASE_RELEASE has finished and the partial will be aborted - startRamp(0, newIncrement, TVA_PHASE_RELEASE); -} - -void TVA::handleInterrupt() { - nextPhase(); -} - -void TVA::recalcSustain() { - // We get pinged periodically by the pitch code to recalculate our values when in sustain. - // This is done so that the TVA will respond to things like MIDI expression and volume changes while it's sustaining, which it otherwise wouldn't do. - - // The check for envLevel[3] == 0 strikes me as slightly dumb. FIXME: Explain why - if (phase != TVA_PHASE_SUSTAIN || partialParam->tva.envLevel[3] == 0) { - return; - } - // We're sustaining. Recalculate all the values - const Tables *tables = &Tables::getInstance(); - int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix); - newTarget += partialParam->tva.envLevel[3]; - - // Although we're in TVA_PHASE_SUSTAIN at this point, we cannot be sure that there is no active ramp at the moment. - // In case the channel volume or the expression changes frequently, the previously started ramp may still be in progress. - // Real hardware units ignore this possibility and rely on the assumption that the target is the current amp. - // This is OK in most situations but when the ramp that is currently in progress needs to change direction - // due to a volume/expression update, this leads to a jump in the amp that is audible as an unpleasant click. - // To avoid that, we compare the newTarget with the the actual current ramp value and correct the direction if necessary. - int targetDelta = newTarget - target; - - // Calculate an increment to get to the new amp value in a short, more or less consistent amount of time - Bit8u newIncrement; - bool descending = targetDelta < 0; - if (!descending) { - newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - 2; - } else { - newIncrement = (tables->envLogarithmicTime[Bit8u(-targetDelta)] - 2) | 0x80; - } - if (part->getSynth()->isNiceAmpRampEnabled() && (descending != ampRamp->isBelowCurrent(newTarget))) { - newIncrement ^= 0x80; - } - - // Configure so that once the transition's complete and nextPhase() is called, we'll just re-enter sustain phase (or decay phase, depending on parameters at the time). - startRamp(newTarget, newIncrement, TVA_PHASE_SUSTAIN - 1); -} - -bool TVA::isPlaying() const { - return playing; -} - -int TVA::getPhase() const { - return phase; -} - -void TVA::nextPhase() { - const Tables *tables = &Tables::getInstance(); - - if (phase >= TVA_PHASE_DEAD || !playing) { - partial->getSynth()->printDebug("TVA::nextPhase(): Shouldn't have got here with phase %d, playing=%s", phase, playing ? "true" : "false"); - return; - } - int newPhase = phase + 1; - - if (newPhase == TVA_PHASE_DEAD) { - end(newPhase); - return; - } - - bool allLevelsZeroFromNowOn = false; - if (!partial->getSynth()->controlROMFeatures->quirkTVAZeroEnvLevels && partialParam->tva.envLevel[3] == 0) { - if (newPhase == TVA_PHASE_4) { - allLevelsZeroFromNowOn = true; - } else if (partialParam->tva.envLevel[2] == 0) { - if (newPhase == TVA_PHASE_3) { - allLevelsZeroFromNowOn = true; - } else if (partialParam->tva.envLevel[1] == 0) { - if (newPhase == TVA_PHASE_2) { - allLevelsZeroFromNowOn = true; - } else if (partialParam->tva.envLevel[0] == 0) { - if (newPhase == TVA_PHASE_ATTACK) { // this line added, missing in ROM - FIXME: Add description of repercussions - allLevelsZeroFromNowOn = true; - } - } - } - } - } - - int newTarget; - int newIncrement = 0; // Initialised to please compilers - int envPointIndex = phase; - - if (!allLevelsZeroFromNowOn) { - newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix); - - if (newPhase == TVA_PHASE_SUSTAIN || newPhase == TVA_PHASE_RELEASE) { - if (partialParam->tva.envLevel[3] == 0) { - end(newPhase); - return; - } - if (!partial->getPoly()->canSustain()) { - newPhase = TVA_PHASE_RELEASE; - newTarget = 0; - newIncrement = -partialParam->tva.envTime[4]; - if (newIncrement == 0) { - // We can't let the increment be 0, or there would be no emulated interrupt. - // So we do an "upward" increment, which should set the amp to 0 extremely quickly - // and cause an "interrupt" to bring us back to nextPhase(). - newIncrement = 1; - } - } else { - newTarget += partialParam->tva.envLevel[3]; - newIncrement = 0; - } - } else { - newTarget += partialParam->tva.envLevel[envPointIndex]; - } - } else { - newTarget = 0; - } - - if ((newPhase != TVA_PHASE_SUSTAIN && newPhase != TVA_PHASE_RELEASE) || allLevelsZeroFromNowOn) { - int envTimeSetting = partialParam->tva.envTime[envPointIndex]; - - if (newPhase == TVA_PHASE_ATTACK) { - envTimeSetting -= (signed(partial->getPoly()->getVelocity()) - 64) >> (6 - partialParam->tva.envTimeVeloSensitivity); // PORTABILITY NOTE: Assumes arithmetic shift - - if (envTimeSetting <= 0 && partialParam->tva.envTime[envPointIndex] != 0) { - envTimeSetting = 1; - } - } else { - envTimeSetting -= keyTimeSubtraction; - } - if (envTimeSetting > 0) { - int targetDelta = newTarget - target; - if (targetDelta <= 0) { - if (targetDelta == 0) { - // target and newTarget are the same. - // We can't have an increment of 0 or we wouldn't get an emulated interrupt. - // So instead make the target one less than it really should be and set targetDelta accordingly. - targetDelta = -1; - newTarget--; - if (newTarget < 0) { - // Oops, newTarget is less than zero now, so let's do it the other way: - // Make newTarget one more than it really should've been and set targetDelta accordingly. - // FIXME (apparent bug in real firmware): - // This means targetDelta will be positive just below here where it's inverted, and we'll end up using envLogarithmicTime[-1], and we'll be setting newIncrement to be descending later on, etc.. - targetDelta = 1; - newTarget = -newTarget; - } - } - targetDelta = -targetDelta; - newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - envTimeSetting; - if (newIncrement <= 0) { - newIncrement = 1; - } - newIncrement = newIncrement | 0x80; - } else { - // FIXME: The last 22 or so entries in this table are 128 - surely that fucks things up, since that ends up being -128 signed? - newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - envTimeSetting; - if (newIncrement <= 0) { - newIncrement = 1; - } - } - } else { - newIncrement = newTarget >= target ? (0x80 | 127) : 127; - } - - // FIXME: What's the point of this? It's checked or set to non-zero everywhere above - if (newIncrement == 0) { - newIncrement = 1; - } - } - - startRamp(Bit8u(newTarget), Bit8u(newIncrement), newPhase); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/TVA.h b/src - Cópia/sound/munt/TVA.h deleted file mode 100644 index cf9296d48..000000000 --- a/src - Cópia/sound/munt/TVA.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_TVA_H -#define MT32EMU_TVA_H - -#include "globals.h" -#include "Types.h" -#include "Structures.h" - -namespace MT32Emu { - -class LA32Ramp; -class Part; -class Partial; - -// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to -// newPhase's value. -enum { - // In this phase, the base amp (as calculated in calcBasicAmp()) is targeted with an instant time. - // This phase is entered by reset() only if time[0] != 0. - TVA_PHASE_BASIC = 0, - - // In this phase, level[0] is targeted within time[0], and velocity potentially affects time - TVA_PHASE_ATTACK = 1, - - // In this phase, level[1] is targeted within time[1] - TVA_PHASE_2 = 2, - - // In this phase, level[2] is targeted within time[2] - TVA_PHASE_3 = 3, - - // In this phase, level[3] is targeted within time[3] - TVA_PHASE_4 = 4, - - // In this phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain. - // Aborts the partial if level[3] is 0. - // Otherwise level[3] is continued, no phase change will occur until some external influence (like pedal release) - TVA_PHASE_SUSTAIN = 5, - - // In this phase, 0 is targeted within time[4] (the time calculation is quite different from the other phases) - TVA_PHASE_RELEASE = 6, - - // It's PHASE_DEAD, Jim. - TVA_PHASE_DEAD = 7 -}; - -class TVA { -private: - const Partial * const partial; - LA32Ramp *ampRamp; - const MemParams::System * const system; - - const Part *part; - const TimbreParam::PartialParam *partialParam; - const MemParams::PatchTemp *patchTemp; - const MemParams::RhythmTemp *rhythmTemp; - - bool playing; - - int biasAmpSubtraction; - int veloAmpSubtraction; - int keyTimeSubtraction; - - Bit8u target; - int phase; - - void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase); - void end(int newPhase); - void nextPhase(); - -public: - TVA(const Partial *partial, LA32Ramp *ampRamp); - void reset(const Part *part, const TimbreParam::PartialParam *partialParam, const MemParams::RhythmTemp *rhythmTemp); - void handleInterrupt(); - void recalcSustain(); - void startDecay(); - void startAbort(); - - bool isPlaying() const; - int getPhase() const; -}; // class TVA - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_TVA_H diff --git a/src - Cópia/sound/munt/TVF.cpp b/src - Cópia/sound/munt/TVF.cpp deleted file mode 100644 index 7ba9c7f2e..000000000 --- a/src - Cópia/sound/munt/TVF.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "internals.h" - -#include "TVF.h" -#include "LA32Ramp.h" -#include "Partial.h" -#include "Poly.h" -#include "Synth.h" -#include "Tables.h" - -namespace MT32Emu { - -// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to -// newPhase's value. -enum { - // When this is the target phase, level[0] is targeted within time[0] - // Note that this phase is always set up in reset(), not nextPhase() - PHASE_ATTACK = 1, - - // When this is the target phase, level[1] is targeted within time[1] - PHASE_2 = 2, - - // When this is the target phase, level[2] is targeted within time[2] - PHASE_3 = 3, - - // When this is the target phase, level[3] is targeted within time[3] - PHASE_4 = 4, - - // When this is the target phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain. - // Otherwise level[3] is continued with increment 0 - no phase change will occur until some external influence (like pedal release) - PHASE_SUSTAIN = 5, - - // 0 is targeted within time[4] (the time calculation is quite different from the other phases) - PHASE_RELEASE = 6, - - // 0 is targeted with increment 0 (thus theoretically staying that way forever) - PHASE_DONE = 7 -}; - -static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u basePitch, unsigned int key, bool quirkTVFBaseCutoffLimit) { - // This table matches the values used by a real LAPC-I. - static const Bit8s biasLevelToBiasMult[] = {85, 42, 21, 16, 10, 5, 2, 0, -2, -5, -10, -16, -21, -74, -85}; - // These values represent unique options with no consistent pattern, so we have to use something like a table in any case. - // The table entries, when divided by 21, match approximately what the manual claims: - // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2 - // Note that the entry for 1/8 is rounded to 2 (from 1/8 * 21 = 2.625), which seems strangely inaccurate compared to the others. - static const Bit8s keyfollowMult21[] = {-21, -10, -5, 0, 2, 5, 8, 10, 13, 16, 18, 21, 26, 32, 42, 21, 21}; - int baseCutoff = keyfollowMult21[partialParam->tvf.keyfollow] - keyfollowMult21[partialParam->wg.pitchKeyfollow]; - // baseCutoff range now: -63 to 63 - baseCutoff *= int(key) - 60; - // baseCutoff range now: -3024 to 3024 - int biasPoint = partialParam->tvf.biasPoint; - if ((biasPoint & 0x40) == 0) { - // biasPoint range here: 0 to 63 - int bias = biasPoint + 33 - key; // bias range here: -75 to 84 - if (bias > 0) { - bias = -bias; // bias range here: -1 to -84 - baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: -7140 to 7140 - // baseCutoff range now: -10164 to 10164 - } - } else { - // biasPoint range here: 64 to 127 - int bias = biasPoint - 31 - key; // bias range here: -75 to 84 - if (bias < 0) { - baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: -6375 to 6375 - // baseCutoff range now: -9399 to 9399 - } - } - // baseCutoff range now: -10164 to 10164 - baseCutoff += ((partialParam->tvf.cutoff << 4) - 800); - // baseCutoff range now: -10964 to 10964 - if (baseCutoff >= 0) { - // FIXME: Potentially bad if baseCutoff ends up below -2056? - int pitchDeltaThing = (basePitch >> 4) + baseCutoff - 3584; - if (pitchDeltaThing > 0) { - baseCutoff -= pitchDeltaThing; - } - } else if (quirkTVFBaseCutoffLimit) { - if (baseCutoff <= -0x400) { - baseCutoff = -400; - } - } else { - if (baseCutoff < -2048) { - baseCutoff = -2048; - } - } - baseCutoff += 2056; - baseCutoff >>= 4; // PORTABILITY NOTE: Hmm... Depends whether it could've been below -2056, but maybe arithmetic shift assumed? - if (baseCutoff > 255) { - baseCutoff = 255; - } - return Bit8u(baseCutoff); -} - -TVF::TVF(const Partial *usePartial, LA32Ramp *useCutoffModifierRamp) : - partial(usePartial), cutoffModifierRamp(useCutoffModifierRamp) { -} - -void TVF::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { - target = newTarget; - phase = newPhase; - cutoffModifierRamp->startRamp(newTarget, newIncrement); -#if MT32EMU_MONITOR_TVF >= 1 - partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,ramp,%x,%s%x,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? "-" : "+", (newIncrement & 0x7F), newPhase); -#endif -} - -void TVF::reset(const TimbreParam::PartialParam *newPartialParam, unsigned int basePitch) { - partialParam = newPartialParam; - - unsigned int key = partial->getPoly()->getKey(); - unsigned int velocity = partial->getPoly()->getVelocity(); - - const Tables *tables = &Tables::getInstance(); - - baseCutoff = calcBaseCutoff(newPartialParam, basePitch, key, partial->getSynth()->controlROMFeatures->quirkTVFBaseCutoffLimit); -#if MT32EMU_MONITOR_TVF >= 1 - partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,base,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), baseCutoff); -#endif - - int newLevelMult = velocity * newPartialParam->tvf.envVeloSensitivity; - newLevelMult >>= 6; - newLevelMult += 109 - newPartialParam->tvf.envVeloSensitivity; - newLevelMult += (signed(key) - 60) >> (4 - newPartialParam->tvf.envDepthKeyfollow); - if (newLevelMult < 0) { - newLevelMult = 0; - } - newLevelMult *= newPartialParam->tvf.envDepth; - newLevelMult >>= 6; - if (newLevelMult > 255) { - newLevelMult = 255; - } - levelMult = newLevelMult; - - if (newPartialParam->tvf.envTimeKeyfollow != 0) { - keyTimeSubtraction = (signed(key) - 60) >> (5 - newPartialParam->tvf.envTimeKeyfollow); - } else { - keyTimeSubtraction = 0; - } - - int newTarget = (newLevelMult * newPartialParam->tvf.envLevel[0]) >> 8; - int envTimeSetting = newPartialParam->tvf.envTime[0] - keyTimeSubtraction; - int newIncrement; - if (envTimeSetting <= 0) { - newIncrement = (0x80 | 127); - } else { - newIncrement = tables->envLogarithmicTime[newTarget] - envTimeSetting; - if (newIncrement <= 0) { - newIncrement = 1; - } - } - cutoffModifierRamp->reset(); - startRamp(newTarget, newIncrement, PHASE_2 - 1); -} - -Bit8u TVF::getBaseCutoff() const { - return baseCutoff; -} - -void TVF::handleInterrupt() { - nextPhase(); -} - -void TVF::startDecay() { - if (phase >= PHASE_RELEASE) { - return; - } - if (partialParam->tvf.envTime[4] == 0) { - startRamp(0, 1, PHASE_DONE - 1); - } else { - startRamp(0, -partialParam->tvf.envTime[4], PHASE_DONE - 1); - } -} - -void TVF::nextPhase() { - const Tables *tables = &Tables::getInstance(); - int newPhase = phase + 1; - - switch (newPhase) { - case PHASE_DONE: - startRamp(0, 0, newPhase); - return; - case PHASE_SUSTAIN: - case PHASE_RELEASE: - // FIXME: Afaict newPhase should never be PHASE_RELEASE here. And if it were, this is an odd way to handle it. - if (!partial->getPoly()->canSustain()) { - phase = newPhase; // FIXME: Correct? - startDecay(); // FIXME: This should actually start decay even if phase is already 6. Does that matter? - return; - } - startRamp((levelMult * partialParam->tvf.envLevel[3]) >> 8, 0, newPhase); - return; - } - - int envPointIndex = phase; - int envTimeSetting = partialParam->tvf.envTime[envPointIndex] - keyTimeSubtraction; - - int newTarget = (levelMult * partialParam->tvf.envLevel[envPointIndex]) >> 8; - int newIncrement; - if (envTimeSetting > 0) { - int targetDelta = newTarget - target; - if (targetDelta == 0) { - if (newTarget == 0) { - targetDelta = 1; - newTarget = 1; - } else { - targetDelta = -1; - newTarget--; - } - } - newIncrement = tables->envLogarithmicTime[targetDelta < 0 ? -targetDelta : targetDelta] - envTimeSetting; - if (newIncrement <= 0) { - newIncrement = 1; - } - if (targetDelta < 0) { - newIncrement |= 0x80; - } - } else { - newIncrement = newTarget >= target ? (0x80 | 127) : 127; - } - startRamp(newTarget, newIncrement, newPhase); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/TVF.h b/src - Cópia/sound/munt/TVF.h deleted file mode 100644 index e637aa5b4..000000000 --- a/src - Cópia/sound/munt/TVF.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_TVF_H -#define MT32EMU_TVF_H - -#include "globals.h" -#include "Types.h" -#include "Structures.h" - -namespace MT32Emu { - -class LA32Ramp; -class Partial; - -class TVF { -private: - const Partial * const partial; - LA32Ramp *cutoffModifierRamp; - const TimbreParam::PartialParam *partialParam; - - Bit8u baseCutoff; - int keyTimeSubtraction; - unsigned int levelMult; - - Bit8u target; - unsigned int phase; - - void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase); - void nextPhase(); - -public: - TVF(const Partial *partial, LA32Ramp *cutoffModifierRamp); - void reset(const TimbreParam::PartialParam *partialParam, Bit32u basePitch); - // Returns the base cutoff (without envelope modification). - // The base cutoff is calculated when reset() is called and remains static - // for the lifetime of the partial. - // Barring bugs, the number returned is confirmed accurate - // (based on specs from Mok). - Bit8u getBaseCutoff() const; - void handleInterrupt(); - void startDecay(); -}; // class TVF - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_TVF_H diff --git a/src - Cópia/sound/munt/TVP.cpp b/src - Cópia/sound/munt/TVP.cpp deleted file mode 100644 index a3b364048..000000000 --- a/src - Cópia/sound/munt/TVP.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "internals.h" - -#include "TVP.h" -#include "Part.h" -#include "Partial.h" -#include "Poly.h" -#include "Synth.h" -#include "TVA.h" - -namespace MT32Emu { - -// FIXME: Add Explanation -static Bit16u lowerDurationToDivisor[] = {34078, 37162, 40526, 44194, 48194, 52556, 57312, 62499}; - -// These values represent unique options with no consistent pattern, so we have to use something like a table in any case. -// The table matches exactly what the manual claims (when divided by 8192): -// -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2 -// ...except for the last two entries, which are supposed to be "1 cent above 1" and "2 cents above 1", respectively. They can only be roughly approximated with this integer math. -static Bit16s pitchKeyfollowMult[] = {-8192, -4096, -2048, 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 10240, 12288, 16384, 8198, 8226}; - -// Note: Keys < 60 use keyToPitchTable[60 - key], keys >= 60 use keyToPitchTable[key - 60]. -// FIXME: This table could really be shorter, since we never use e.g. key 127. -static Bit16u keyToPitchTable[] = { - 0, 341, 683, 1024, 1365, 1707, 2048, 2389, - 2731, 3072, 3413, 3755, 4096, 4437, 4779, 5120, - 5461, 5803, 6144, 6485, 6827, 7168, 7509, 7851, - 8192, 8533, 8875, 9216, 9557, 9899, 10240, 10581, - 10923, 11264, 11605, 11947, 12288, 12629, 12971, 13312, - 13653, 13995, 14336, 14677, 15019, 15360, 15701, 16043, - 16384, 16725, 17067, 17408, 17749, 18091, 18432, 18773, - 19115, 19456, 19797, 20139, 20480, 20821, 21163, 21504, - 21845, 22187, 22528, 22869 -}; - -// We want to do processing 4000 times per second. FIXME: This is pretty arbitrary. -static const int NOMINAL_PROCESS_TIMER_PERIOD_SAMPLES = SAMPLE_RATE / 4000; - -// The timer runs at 500kHz. This is how much to increment it after 8 samples passes. -// We multiply by 8 to get rid of the fraction and deal with just integers. -static const int PROCESS_TIMER_INCREMENT_x8 = 8 * 500000 / SAMPLE_RATE; - -TVP::TVP(const Partial *usePartial) : - partial(usePartial), system(&usePartial->getSynth()->mt32ram.system) { -} - -static Bit16s keyToPitch(unsigned int key) { - // We're using a table to do: return round_to_nearest_or_even((key - 60) * (4096.0 / 12.0)) - // Banker's rounding is just slightly annoying to do in C++ - int k = int(key); - Bit16s pitch = keyToPitchTable[abs(k - 60)]; - return key < 60 ? -pitch : pitch; -} - -static inline Bit32s coarseToPitch(Bit8u coarse) { - return (coarse - 36) * 4096 / 12; // One semitone per coarse offset -} - -static inline Bit32s fineToPitch(Bit8u fine) { - return (fine - 50) * 4096 / 1200; // One cent per fine offset -} - -static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, unsigned int key, const ControlROMFeatureSet *controlROMFeatures) { - Bit32s basePitch = keyToPitch(key); - basePitch = (basePitch * pitchKeyfollowMult[partialParam->wg.pitchKeyfollow]) >> 13; // PORTABILITY NOTE: Assumes arithmetic shift - basePitch += coarseToPitch(partialParam->wg.pitchCoarse); - basePitch += fineToPitch(partialParam->wg.pitchFine); - if (controlROMFeatures->quirkKeyShift) { - // NOTE:Mok: This is done on MT-32, but not LAPC-I: - basePitch += coarseToPitch(patchTemp->patch.keyShift + 12); - } - basePitch += fineToPitch(patchTemp->patch.fineTune); - - const ControlROMPCMStruct *controlROMPCMStruct = partial->getControlROMPCMStruct(); - if (controlROMPCMStruct != NULL) { - basePitch += (Bit32s(controlROMPCMStruct->pitchMSB) << 8) | Bit32s(controlROMPCMStruct->pitchLSB); - } else { - if ((partialParam->wg.waveform & 1) == 0) { - basePitch += 37133; // This puts Middle C at around 261.64Hz (assuming no other modifications, masterTune of 64, etc.) - } else { - // Sawtooth waves are effectively double the frequency of square waves. - // Thus we add 4096 less than for square waves here, which results in halving the frequency. - basePitch += 33037; - } - } - - // MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow. - // This quirk is observable playing the patch defined for timbre "HIT BOTTOM" in Larry 3. - if (controlROMFeatures->quirkBasePitchOverflow) { - basePitch = basePitch & 0xffff; - } else if (basePitch < 0) { - basePitch = 0; - } - if (basePitch > 59392) { - basePitch = 59392; - } - return Bit32u(basePitch); -} - -static Bit32u calcVeloMult(Bit8u veloSensitivity, unsigned int velocity) { - if (veloSensitivity == 0) { - return 21845; // aka floor(4096 / 12 * 64), aka ~64 semitones - } - unsigned int reversedVelocity = 127 - velocity; - unsigned int scaledReversedVelocity; - if (veloSensitivity > 3) { - // Note that on CM-32L/LAPC-I veloSensitivity is never > 3, since it's clipped to 3 by the max tables. - // MT-32 GEN0 has a bug here that leads to unspecified behaviour. We assume it is as follows. - scaledReversedVelocity = (reversedVelocity << 8) >> ((3 - veloSensitivity) & 0x1f); - } else { - scaledReversedVelocity = reversedVelocity << (5 + veloSensitivity); - } - // When velocity is 127, the multiplier is 21845, aka ~64 semitones (regardless of veloSensitivity). - // The lower the velocity, the lower the multiplier. The veloSensitivity determines the amount decreased per velocity value. - // The minimum multiplier on CM-32L/LAPC-I (with velocity 0, veloSensitivity 3) is 170 (~half a semitone). - return ((32768 - scaledReversedVelocity) * 21845) >> 15; -} - -static Bit32s calcTargetPitchOffsetWithoutLFO(const TimbreParam::PartialParam *partialParam, int levelIndex, unsigned int velocity) { - int veloMult = calcVeloMult(partialParam->pitchEnv.veloSensitivity, velocity); - int targetPitchOffsetWithoutLFO = partialParam->pitchEnv.level[levelIndex] - 50; - targetPitchOffsetWithoutLFO = (targetPitchOffsetWithoutLFO * veloMult) >> (16 - partialParam->pitchEnv.depth); // PORTABILITY NOTE: Assumes arithmetic shift - return targetPitchOffsetWithoutLFO; -} - -void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartialParam) { - part = usePart; - partialParam = usePartialParam; - patchTemp = part->getPatchTemp(); - - unsigned int key = partial->getPoly()->getKey(); - unsigned int velocity = partial->getPoly()->getVelocity(); - - // FIXME: We're using a per-TVP timer instead of a system-wide one for convenience. - timeElapsed = 0; - - basePitch = calcBasePitch(partial, partialParam, patchTemp, key, partial->getSynth()->controlROMFeatures); - currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity); - targetPitchOffsetWithoutLFO = currentPitchOffset; - phase = 0; - - if (partialParam->pitchEnv.timeKeyfollow) { - timeKeyfollowSubtraction = Bit32s(key - 60) >> (5 - partialParam->pitchEnv.timeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift - } else { - timeKeyfollowSubtraction = 0; - } - lfoPitchOffset = 0; - counter = 0; - pitch = basePitch; - - // These don't really need to be initialised, but it aids debugging. - pitchOffsetChangePerBigTick = 0; - targetPitchOffsetReachedBigTick = 0; - shifts = 0; -} - -Bit32u TVP::getBasePitch() const { - return basePitch; -} - -void TVP::updatePitch() { - Bit32s newPitch = basePitch + currentPitchOffset; - if (!partial->isPCM() || (partial->getControlROMPCMStruct()->len & 0x01) == 0) { // FIXME: Use !partial->pcmWaveEntry->unaffectedByMasterTune instead - // FIXME: There are various bugs not yet emulated - // 171 is ~half a semitone. - newPitch += partial->getSynth()->getMasterTunePitchDelta(); - } - if ((partialParam->wg.pitchBenderEnabled & 1) != 0) { - newPitch += part->getPitchBend(); - } - - // MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow. - // This quirk is exploited e.g. in Colonel's Bequest timbres "Lightning" and "SwmpBackgr". - if (partial->getSynth()->controlROMFeatures->quirkPitchEnvelopeOverflow) { - newPitch = newPitch & 0xffff; - } else if (newPitch < 0) { - newPitch = 0; - } - if (newPitch > 59392) { - newPitch = 59392; - } - pitch = Bit16u(newPitch); - - // FIXME: We're doing this here because that's what the CM-32L does - we should probably move this somewhere more appropriate in future. - partial->getTVA()->recalcSustain(); -} - -void TVP::targetPitchOffsetReached() { - currentPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset; - - switch (phase) { - case 3: - case 4: - { - int newLFOPitchOffset = (part->getModulation() * partialParam->pitchLFO.modSensitivity) >> 7; - newLFOPitchOffset = (newLFOPitchOffset + partialParam->pitchLFO.depth) << 1; - if (pitchOffsetChangePerBigTick > 0) { - // Go in the opposite direction to last time - newLFOPitchOffset = -newLFOPitchOffset; - } - lfoPitchOffset = newLFOPitchOffset; - int targetPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset; - setupPitchChange(targetPitchOffset, 101 - partialParam->pitchLFO.rate); - updatePitch(); - break; - } - case 6: - updatePitch(); - break; - default: - nextPhase(); - } -} - -void TVP::nextPhase() { - phase++; - int envIndex = phase == 6 ? 4 : phase; - - targetPitchOffsetWithoutLFO = calcTargetPitchOffsetWithoutLFO(partialParam, envIndex, partial->getPoly()->getVelocity()); // pitch we'll reach at the end - - int changeDuration = partialParam->pitchEnv.time[envIndex - 1]; - changeDuration -= timeKeyfollowSubtraction; - if (changeDuration > 0) { - setupPitchChange(targetPitchOffsetWithoutLFO, changeDuration); // changeDuration between 0 and 112 now - updatePitch(); - } else { - targetPitchOffsetReached(); - } -} - -// Shifts val to the left until bit 31 is 1 and returns the number of shifts -static Bit8u normalise(Bit32u &val) { - Bit8u leftShifts; - for (leftShifts = 0; leftShifts < 31; leftShifts++) { - if ((val & 0x80000000) != 0) { - break; - } - val = val << 1; - } - return leftShifts; -} - -void TVP::setupPitchChange(int targetPitchOffset, Bit8u changeDuration) { - bool negativeDelta = targetPitchOffset < currentPitchOffset; - Bit32s pitchOffsetDelta = targetPitchOffset - currentPitchOffset; - if (pitchOffsetDelta > 32767 || pitchOffsetDelta < -32768) { - pitchOffsetDelta = 32767; - } - if (negativeDelta) { - pitchOffsetDelta = -pitchOffsetDelta; - } - // We want to maximise the number of bits of the Bit16s "pitchOffsetChangePerBigTick" we use in order to get the best possible precision later - Bit32u absPitchOffsetDelta = pitchOffsetDelta << 16; - Bit8u normalisationShifts = normalise(absPitchOffsetDelta); // FIXME: Double-check: normalisationShifts is usually between 0 and 15 here, unless the delta is 0, in which case it's 31 - absPitchOffsetDelta = absPitchOffsetDelta >> 1; // Make room for the sign bit - - changeDuration--; // changeDuration's now between 0 and 111 - unsigned int upperDuration = changeDuration >> 3; // upperDuration's now between 0 and 13 - shifts = normalisationShifts + upperDuration + 2; - Bit16u divisor = lowerDurationToDivisor[changeDuration & 7]; - Bit16s newPitchOffsetChangePerBigTick = ((absPitchOffsetDelta & 0xFFFF0000) / divisor) >> 1; // Result now fits within 15 bits. FIXME: Check nothing's getting sign-extended incorrectly - if (negativeDelta) { - newPitchOffsetChangePerBigTick = -newPitchOffsetChangePerBigTick; - } - pitchOffsetChangePerBigTick = newPitchOffsetChangePerBigTick; - - int currentBigTick = timeElapsed >> 8; - int durationInBigTicks = divisor >> (12 - upperDuration); - if (durationInBigTicks > 32767) { - durationInBigTicks = 32767; - } - // The result of the addition may exceed 16 bits, but wrapping is fine and intended here. - targetPitchOffsetReachedBigTick = currentBigTick + durationInBigTicks; -} - -void TVP::startDecay() { - phase = 5; - lfoPitchOffset = 0; - targetPitchOffsetReachedBigTick = timeElapsed >> 8; // FIXME: Afaict there's no good reason for this - check -} - -Bit16u TVP::nextPitch() { - // We emulate MCU software timer using these counter and processTimerIncrement variables. - // The value of nominalProcessTimerPeriod approximates the period in samples - // between subsequent firings of the timer that normally occur. - // However, accurate emulation is quite complicated because the timer is not guaranteed to fire in time. - // This makes pitch variations on real unit non-deterministic and dependent on various factors. - if (counter == 0) { - timeElapsed = (timeElapsed + processTimerIncrement) & 0x00FFFFFF; - // This roughly emulates pitch deviations observed on real units when playing a single partial that uses TVP/LFO. - counter = NOMINAL_PROCESS_TIMER_PERIOD_SAMPLES + (rand() & 3); - processTimerIncrement = (PROCESS_TIMER_INCREMENT_x8 * counter) >> 3; - process(); - } - counter--; - return pitch; -} - -void TVP::process() { - if (phase == 0) { - targetPitchOffsetReached(); - return; - } - if (phase == 5) { - nextPhase(); - return; - } - if (phase > 7) { - updatePitch(); - return; - } - - Bit16s negativeBigTicksRemaining = (timeElapsed >> 8) - targetPitchOffsetReachedBigTick; - if (negativeBigTicksRemaining >= 0) { - // We've reached the time for a phase change - targetPitchOffsetReached(); - return; - } - // FIXME: Write explanation for this stuff - int rightShifts = shifts; - if (rightShifts > 13) { - rightShifts -= 13; - negativeBigTicksRemaining = negativeBigTicksRemaining >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift - rightShifts = 13; - } - int newResult = (negativeBigTicksRemaining * pitchOffsetChangePerBigTick) >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift - newResult += targetPitchOffsetWithoutLFO + lfoPitchOffset; - currentPitchOffset = newResult; - updatePitch(); -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/TVP.h b/src - Cópia/sound/munt/TVP.h deleted file mode 100644 index 896e8c11a..000000000 --- a/src - Cópia/sound/munt/TVP.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_TVP_H -#define MT32EMU_TVP_H - -#include "globals.h" -#include "Types.h" -#include "Structures.h" - -namespace MT32Emu { - -class Part; -class Partial; - -class TVP { -private: - const Partial * const partial; - const MemParams::System * const system; // FIXME: Only necessary because masterTune calculation is done in the wrong place atm. - - const Part *part; - const TimbreParam::PartialParam *partialParam; - const MemParams::PatchTemp *patchTemp; - - int processTimerIncrement; - int counter; - Bit32u timeElapsed; - - int phase; - Bit32u basePitch; - Bit32s targetPitchOffsetWithoutLFO; - Bit32s currentPitchOffset; - - Bit16s lfoPitchOffset; - // In range -12 - 36 - Bit8s timeKeyfollowSubtraction; - - Bit16s pitchOffsetChangePerBigTick; - Bit16u targetPitchOffsetReachedBigTick; - unsigned int shifts; - - Bit16u pitch; - - void updatePitch(); - void setupPitchChange(int targetPitchOffset, Bit8u changeDuration); - void targetPitchOffsetReached(); - void nextPhase(); - void process(); -public: - TVP(const Partial *partial); - void reset(const Part *part, const TimbreParam::PartialParam *partialParam); - Bit32u getBasePitch() const; - Bit16u nextPitch(); - void startDecay(); -}; // class TVP - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_TVP_H diff --git a/src - Cópia/sound/munt/Tables.cpp b/src - Cópia/sound/munt/Tables.cpp deleted file mode 100644 index f12caa6b6..000000000 --- a/src - Cópia/sound/munt/Tables.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "internals.h" - -#include "Tables.h" -#include "mmath.h" - -namespace MT32Emu { - -// UNUSED: const int MIDDLEC = 60; - -const Tables &Tables::getInstance() { - static const Tables instance; - return instance; -} - -Tables::Tables() { - for (int lf = 0; lf <= 100; lf++) { - // CONFIRMED:KG: This matches a ROM table found by Mok - float fVal = (2.0f - LOG10F(float(lf) + 1.0f)) * 128.0f; - int val = int(fVal + 1.0); - if (val > 255) { - val = 255; - } - levelToAmpSubtraction[lf] = Bit8u(val); - } - - envLogarithmicTime[0] = 64; - for (int lf = 1; lf <= 255; lf++) { - // CONFIRMED:KG: This matches a ROM table found by Mok - envLogarithmicTime[lf] = Bit8u(ceil(64.0f + LOG2F(float(lf)) * 8.0f)); - } - -#if 0 - // The table below is to be used in conjunction with emulation of VCA of newer generation units which is currently missing. - // These relatively small values are rather intended to fine-tune the overall amplification of the VCA. - // CONFIRMED: Based on a table found by Mok in the LAPC-I control ROM - // Note that this matches the MT-32 table, but with the values clamped to a maximum of 8. - memset(masterVolToAmpSubtraction, 8, 71); - memset(masterVolToAmpSubtraction + 71, 7, 3); - memset(masterVolToAmpSubtraction + 74, 6, 4); - memset(masterVolToAmpSubtraction + 78, 5, 3); - memset(masterVolToAmpSubtraction + 81, 4, 4); - memset(masterVolToAmpSubtraction + 85, 3, 3); - memset(masterVolToAmpSubtraction + 88, 2, 4); - memset(masterVolToAmpSubtraction + 92, 1, 4); - memset(masterVolToAmpSubtraction + 96, 0, 5); -#else - // CONFIRMED: Based on a table found by Mok in the MT-32 control ROM - masterVolToAmpSubtraction[0] = 255; - for (int masterVol = 1; masterVol <= 100; masterVol++) { - masterVolToAmpSubtraction[masterVol] = Bit8u(106.31 - 16.0f * LOG2F(float(masterVol))); - } -#endif - - for (int i = 0; i <= 100; i++) { - pulseWidth100To255[i] = Bit8u(i * 255 / 100.0f + 0.5f); - //synth->printDebug("%d: %d", i, pulseWidth100To255[i]); - } - - // The LA32 chip contains an exponent table inside. The table contains 12-bit integer values. - // The actual table size is 512 rows. The 9 higher bits of the fractional part of the argument are used as a lookup address. - // To improve the precision of computations, the lower bits are supposed to be used for interpolation as the LA32 chip also - // contains another 512-row table with inverted differences between the main table values. - for (int i = 0; i < 512; i++) { - exp9[i] = Bit16u(8191.5f - EXP2F(13.0f + ~i / 512.0f)); - } - - // There is a logarithmic sine table inside the LA32 chip. The table contains 13-bit integer values. - for (int i = 1; i < 512; i++) { - logsin9[i] = Bit16u(0.5f - LOG2F(sin((i + 0.5f) / 1024.0f * FLOAT_PI)) * 1024.0f); - } - - // The very first value is clamped to the maximum possible 13-bit integer - logsin9[0] = 8191; - - // found from sample analysis - static const Bit8u resAmpDecayFactorTable[] = {31, 16, 12, 8, 5, 3, 2, 1}; - resAmpDecayFactor = resAmpDecayFactorTable; -} - -} // namespace MT32Emu diff --git a/src - Cópia/sound/munt/Tables.h b/src - Cópia/sound/munt/Tables.h deleted file mode 100644 index 47465097e..000000000 --- a/src - Cópia/sound/munt/Tables.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_TABLES_H -#define MT32EMU_TABLES_H - -#include "globals.h" -#include "Types.h" - -namespace MT32Emu { - -class Tables { -private: - Tables(); - Tables(Tables &); - ~Tables() {} - -public: - static const Tables &getInstance(); - - // Constant LUTs - - // CONFIRMED: This is used to convert several parameters to amp-modifying values in the TVA envelope: - // - PatchTemp.outputLevel - // - RhythmTemp.outlevel - // - PartialParam.tva.level - // - expression - // It's used to determine how much to subtract from the amp envelope's target value - Bit8u levelToAmpSubtraction[101]; - - // CONFIRMED: ... - Bit8u envLogarithmicTime[256]; - - // CONFIRMED: ... - Bit8u masterVolToAmpSubtraction[101]; - - // CONFIRMED: - Bit8u pulseWidth100To255[101]; - - Bit16u exp9[512]; - Bit16u logsin9[512]; - - const Bit8u *resAmpDecayFactor; -}; // class Tables - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_TABLES_H diff --git a/src - Cópia/sound/munt/Types.h b/src - Cópia/sound/munt/Types.h deleted file mode 100644 index f70e4795c..000000000 --- a/src - Cópia/sound/munt/Types.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_TYPES_H -#define MT32EMU_TYPES_H - -namespace MT32Emu { - -typedef unsigned int Bit32u; -typedef signed int Bit32s; -typedef unsigned short int Bit16u; -typedef signed short int Bit16s; -typedef unsigned char Bit8u; -typedef signed char Bit8s; - -} - -#endif diff --git a/src - Cópia/sound/munt/c_interface/c_interface.cpp b/src - Cópia/sound/munt/c_interface/c_interface.cpp deleted file mode 100644 index 24bb1460e..000000000 --- a/src - Cópia/sound/munt/c_interface/c_interface.cpp +++ /dev/null @@ -1,719 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "../globals.h" -#include "../Types.h" -#include "../File.h" -#include "../FileStream.h" -#include "../ROMInfo.h" -#include "../Synth.h" -#include "../MidiStreamParser.h" -#include "../SampleRateConverter.h" - -#include "c_types.h" -#include "c_interface.h" - -using namespace MT32Emu; - -namespace MT32Emu { - -struct SamplerateConversionState { - double outputSampleRate; - SamplerateConversionQuality srcQuality; - SampleRateConverter *src; -}; - -static mt32emu_service_version getSynthVersionID(mt32emu_service_i) { - return MT32EMU_SERVICE_VERSION_CURRENT; -} - -static const mt32emu_service_i_v2 SERVICE_VTABLE = { - getSynthVersionID, - mt32emu_get_supported_report_handler_version, - mt32emu_get_supported_midi_receiver_version, - mt32emu_get_library_version_int, - mt32emu_get_library_version_string, - mt32emu_get_stereo_output_samplerate, - mt32emu_create_context, - mt32emu_free_context, - mt32emu_add_rom_data, - mt32emu_add_rom_file, - mt32emu_get_rom_info, - mt32emu_set_partial_count, - mt32emu_set_analog_output_mode, - mt32emu_open_synth, - mt32emu_close_synth, - mt32emu_is_open, - mt32emu_get_actual_stereo_output_samplerate, - mt32emu_flush_midi_queue, - mt32emu_set_midi_event_queue_size, - mt32emu_set_midi_receiver, - mt32emu_parse_stream, - mt32emu_parse_stream_at, - mt32emu_play_short_message, - mt32emu_play_short_message_at, - mt32emu_play_msg, - mt32emu_play_sysex, - mt32emu_play_msg_at, - mt32emu_play_sysex_at, - mt32emu_play_msg_now, - mt32emu_play_msg_on_part, - mt32emu_play_sysex_now, - mt32emu_write_sysex, - mt32emu_set_reverb_enabled, - mt32emu_is_reverb_enabled, - mt32emu_set_reverb_overridden, - mt32emu_is_reverb_overridden, - mt32emu_set_reverb_compatibility_mode, - mt32emu_is_mt32_reverb_compatibility_mode, - mt32emu_is_default_reverb_mt32_compatible, - mt32emu_set_dac_input_mode, - mt32emu_get_dac_input_mode, - mt32emu_set_midi_delay_mode, - mt32emu_get_midi_delay_mode, - mt32emu_set_output_gain, - mt32emu_get_output_gain, - mt32emu_set_reverb_output_gain, - mt32emu_get_reverb_output_gain, - mt32emu_set_reversed_stereo_enabled, - mt32emu_is_reversed_stereo_enabled, - mt32emu_render_bit16s, - mt32emu_render_float, - mt32emu_render_bit16s_streams, - mt32emu_render_float_streams, - mt32emu_has_active_partials, - mt32emu_is_active, - mt32emu_get_partial_count, - mt32emu_get_part_states, - mt32emu_get_partial_states, - mt32emu_get_playing_notes, - mt32emu_get_patch_name, - mt32emu_read_memory, - mt32emu_get_best_analog_output_mode, - mt32emu_set_stereo_output_samplerate, - mt32emu_set_samplerate_conversion_quality, - mt32emu_select_renderer_type, - mt32emu_get_selected_renderer_type, - mt32emu_convert_output_to_synth_timestamp, - mt32emu_convert_synth_to_output_timestamp, - mt32emu_get_internal_rendered_sample_count, - mt32emu_set_nice_amp_ramp_enabled, - mt32emu_is_nice_amp_ramp_enabled -}; - -} // namespace MT32Emu - -struct mt32emu_data { - ReportHandler *reportHandler; - Synth *synth; - const ROMImage *controlROMImage; - const ROMImage *pcmROMImage; - DefaultMidiStreamParser *midiParser; - Bit32u partialCount; - AnalogOutputMode analogOutputMode; - SamplerateConversionState *srcState; -}; - -// Internal C++ utility stuff - -namespace MT32Emu { - -class DelegatingReportHandlerAdapter : public ReportHandler { -public: - DelegatingReportHandlerAdapter(mt32emu_report_handler_i useReportHandler, void *useInstanceData) : - delegate(useReportHandler), instanceData(useInstanceData) {} - -protected: - const mt32emu_report_handler_i delegate; - void * const instanceData; - -private: - void printDebug(const char *fmt, va_list list) { - if (delegate.v0->printDebug == NULL) { - ReportHandler::printDebug(fmt, list); - } else { - delegate.v0->printDebug(instanceData, fmt, list); - } - } - - void onErrorControlROM() { - if (delegate.v0->onErrorControlROM == NULL) { - ReportHandler::onErrorControlROM(); - } else { - delegate.v0->onErrorControlROM(instanceData); - } - } - - void onErrorPCMROM() { - if (delegate.v0->onErrorPCMROM == NULL) { - ReportHandler::onErrorPCMROM(); - } else { - delegate.v0->onErrorPCMROM(instanceData); - } - } - - void showLCDMessage(const char *message) { - if (delegate.v0->showLCDMessage == NULL) { - ReportHandler::showLCDMessage(message); - } else { - delegate.v0->showLCDMessage(instanceData, message); - } - } - - void onMIDIMessagePlayed() { - if (delegate.v0->onMIDIMessagePlayed == NULL) { - ReportHandler::onMIDIMessagePlayed(); - } else { - delegate.v0->onMIDIMessagePlayed(instanceData); - } - } - - bool onMIDIQueueOverflow() { - if (delegate.v0->onMIDIQueueOverflow == NULL) { - return ReportHandler::onMIDIQueueOverflow(); - } - return delegate.v0->onMIDIQueueOverflow(instanceData) != MT32EMU_BOOL_FALSE; - } - - void onMIDISystemRealtime(Bit8u systemRealtime) { - if (delegate.v0->onMIDISystemRealtime == NULL) { - ReportHandler::onMIDISystemRealtime(systemRealtime); - } else { - delegate.v0->onMIDISystemRealtime(instanceData, systemRealtime); - } - } - - void onDeviceReset() { - if (delegate.v0->onDeviceReset == NULL) { - ReportHandler::onDeviceReset(); - } else { - delegate.v0->onDeviceReset(instanceData); - } - } - - void onDeviceReconfig() { - if (delegate.v0->onDeviceReconfig == NULL) { - ReportHandler::onDeviceReconfig(); - } else { - delegate.v0->onDeviceReconfig(instanceData); - } - } - - void onNewReverbMode(Bit8u mode) { - if (delegate.v0->onNewReverbMode == NULL) { - ReportHandler::onNewReverbMode(mode); - } else { - delegate.v0->onNewReverbMode(instanceData, mode); - } - } - - void onNewReverbTime(Bit8u time) { - if (delegate.v0->onNewReverbTime == NULL) { - ReportHandler::onNewReverbTime(time); - } else { - delegate.v0->onNewReverbTime(instanceData, time); - } - } - - void onNewReverbLevel(Bit8u level) { - if (delegate.v0->onNewReverbLevel == NULL) { - ReportHandler::onNewReverbLevel(level); - } else { - delegate.v0->onNewReverbLevel(instanceData, level); - } - } - - void onPolyStateChanged(Bit8u partNum) { - if (delegate.v0->onPolyStateChanged == NULL) { - ReportHandler::onPolyStateChanged(partNum); - } else { - delegate.v0->onPolyStateChanged(instanceData, partNum); - } - } - - void onProgramChanged(Bit8u partNum, const char *soundGroupName, const char *patchName) { - if (delegate.v0->onProgramChanged == NULL) { - ReportHandler::onProgramChanged(partNum, soundGroupName, patchName); - } else { - delegate.v0->onProgramChanged(instanceData, partNum, soundGroupName, patchName); - } - } -}; - -class DelegatingMidiStreamParser : public DefaultMidiStreamParser { -public: - DelegatingMidiStreamParser(const mt32emu_data *useData, mt32emu_midi_receiver_i useMIDIReceiver, void *useInstanceData) : - DefaultMidiStreamParser(*useData->synth), delegate(useMIDIReceiver), instanceData(useInstanceData) {} - -protected: - mt32emu_midi_receiver_i delegate; - void *instanceData; - -private: - void handleShortMessage(const Bit32u message) { - if (delegate.v0->handleShortMessage == NULL) { - DefaultMidiStreamParser::handleShortMessage(message); - } else { - delegate.v0->handleShortMessage(instanceData, message); - } - } - - void handleSysex(const Bit8u *stream, const Bit32u length) { - if (delegate.v0->handleSysex == NULL) { - DefaultMidiStreamParser::handleSysex(stream, length); - } else { - delegate.v0->handleSysex(instanceData, stream, length); - } - } - - void handleSystemRealtimeMessage(const Bit8u realtime) { - if (delegate.v0->handleSystemRealtimeMessage == NULL) { - DefaultMidiStreamParser::handleSystemRealtimeMessage(realtime); - } else { - delegate.v0->handleSystemRealtimeMessage(instanceData, realtime); - } - } -}; - -static mt32emu_return_code addROMFile(mt32emu_data *data, File *file) { - const ROMImage *image = ROMImage::makeROMImage(file); - const ROMInfo *info = image->getROMInfo(); - if (info == NULL) { - ROMImage::freeROMImage(image); - return MT32EMU_RC_ROM_NOT_IDENTIFIED; - } - if (info->type == ROMInfo::Control) { - if (data->controlROMImage != NULL) { - delete data->controlROMImage->getFile(); - ROMImage::freeROMImage(data->controlROMImage); - } - data->controlROMImage = image; - return MT32EMU_RC_ADDED_CONTROL_ROM; - } else if (info->type == ROMInfo::PCM) { - if (data->pcmROMImage != NULL) { - delete data->pcmROMImage->getFile(); - ROMImage::freeROMImage(data->pcmROMImage); - } - data->pcmROMImage = image; - return MT32EMU_RC_ADDED_PCM_ROM; - } - ROMImage::freeROMImage(image); - return MT32EMU_RC_OK; // No support for reverb ROM yet. -} - -} // namespace MT32Emu - -// C-visible implementation - -extern "C" { - -mt32emu_service_i mt32emu_get_service_i() { - mt32emu_service_i i; - i.v2 = &SERVICE_VTABLE; - return i; -} - -mt32emu_report_handler_version mt32emu_get_supported_report_handler_version() { - return MT32EMU_REPORT_HANDLER_VERSION_CURRENT; -} - -mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version() { - return MT32EMU_MIDI_RECEIVER_VERSION_CURRENT; -} - -mt32emu_bit32u mt32emu_get_library_version_int() { - return Synth::getLibraryVersionInt(); -} - -const char *mt32emu_get_library_version_string() { - return Synth::getLibraryVersionString(); -} - -mt32emu_bit32u mt32emu_get_stereo_output_samplerate(const mt32emu_analog_output_mode analog_output_mode) { - return Synth::getStereoOutputSampleRate(static_cast(analog_output_mode)); -} - -mt32emu_analog_output_mode mt32emu_get_best_analog_output_mode(const double target_samplerate) { - return mt32emu_analog_output_mode(SampleRateConverter::getBestAnalogOutputMode(target_samplerate)); -} - -mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler, void *instance_data) { - mt32emu_data *data = new mt32emu_data; - data->reportHandler = (report_handler.v0 != NULL) ? new DelegatingReportHandlerAdapter(report_handler, instance_data) : new ReportHandler; - data->synth = new Synth(data->reportHandler); - data->midiParser = new DefaultMidiStreamParser(*data->synth); - data->controlROMImage = NULL; - data->pcmROMImage = NULL; - data->partialCount = DEFAULT_MAX_PARTIALS; - data->analogOutputMode = AnalogOutputMode_COARSE; - - data->srcState = new SamplerateConversionState; - data->srcState->outputSampleRate = 0.0; - data->srcState->srcQuality = SamplerateConversionQuality_GOOD; - data->srcState->src = NULL; - - return data; -} - -void mt32emu_free_context(mt32emu_context data) { - if (data == NULL) return; - - delete data->srcState->src; - data->srcState->src = NULL; - delete data->srcState; - data->srcState = NULL; - - if (data->controlROMImage != NULL) { - delete data->controlROMImage->getFile(); - ROMImage::freeROMImage(data->controlROMImage); - data->controlROMImage = NULL; - } - if (data->pcmROMImage != NULL) { - delete data->pcmROMImage->getFile(); - ROMImage::freeROMImage(data->pcmROMImage); - data->pcmROMImage = NULL; - } - delete data->midiParser; - data->midiParser = NULL; - delete data->synth; - data->synth = NULL; - delete data->reportHandler; - data->reportHandler = NULL; - delete data; -} - -mt32emu_return_code mt32emu_add_rom_data(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest) { - if (sha1_digest == NULL) return addROMFile(context, new ArrayFile(data, data_size)); - return addROMFile(context, new ArrayFile(data, data_size, *sha1_digest)); -} - -mt32emu_return_code mt32emu_add_rom_file(mt32emu_context context, const char *filename) { - mt32emu_return_code rc = MT32EMU_RC_OK; - FileStream *fs = new FileStream; - if (fs->open(filename)) { - if (fs->getData() != NULL) { - rc = addROMFile(context, fs); - if (rc > 0) return rc; - } else { - rc = MT32EMU_RC_FILE_NOT_LOADED; - } - } else { - rc = MT32EMU_RC_FILE_NOT_FOUND; - } - delete fs; - return rc; -} - -void mt32emu_get_rom_info(mt32emu_const_context context, mt32emu_rom_info *rom_info) { - const ROMInfo *romInfo = context->controlROMImage == NULL ? NULL : context->controlROMImage->getROMInfo(); - if (romInfo != NULL) { - rom_info->control_rom_id = romInfo->shortName; - rom_info->control_rom_description = romInfo->description; - rom_info->control_rom_sha1_digest = romInfo->sha1Digest; - } else { - rom_info->control_rom_id = NULL; - rom_info->control_rom_description = NULL; - rom_info->control_rom_sha1_digest = NULL; - } - romInfo = context->pcmROMImage == NULL ? NULL : context->pcmROMImage->getROMInfo(); - if (romInfo != NULL) { - rom_info->pcm_rom_id = romInfo->shortName; - rom_info->pcm_rom_description = romInfo->description; - rom_info->pcm_rom_sha1_digest = romInfo->sha1Digest; - } else { - rom_info->pcm_rom_id = NULL; - rom_info->pcm_rom_description = NULL; - rom_info->pcm_rom_sha1_digest = NULL; - } -} - -void mt32emu_set_partial_count(mt32emu_context context, const mt32emu_bit32u partial_count) { - context->partialCount = partial_count; -} - -void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode) { - context->analogOutputMode = static_cast(analog_output_mode); -} - -void mt32emu_set_stereo_output_samplerate(mt32emu_context context, const double samplerate) { - if (0.0 <= samplerate) { - context->srcState->outputSampleRate = samplerate; - } -} - -void mt32emu_set_samplerate_conversion_quality(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality) { - context->srcState->srcQuality = SamplerateConversionQuality(quality); -} - -void mt32emu_select_renderer_type(mt32emu_context context, const mt32emu_renderer_type renderer_type) { - context->synth->selectRendererType(static_cast(renderer_type)); -} - -mt32emu_renderer_type mt32emu_get_selected_renderer_type(mt32emu_context context) { - return static_cast(context->synth->getSelectedRendererType()); -} - -mt32emu_return_code mt32emu_open_synth(mt32emu_const_context context) { - if ((context->controlROMImage == NULL) || (context->pcmROMImage == NULL)) { - return MT32EMU_RC_MISSING_ROMS; - } - if (!context->synth->open(*context->controlROMImage, *context->pcmROMImage, context->partialCount, context->analogOutputMode)) { - return MT32EMU_RC_FAILED; - } - SamplerateConversionState &srcState = *context->srcState; - const double outputSampleRate = (0.0 < srcState.outputSampleRate) ? srcState.outputSampleRate : context->synth->getStereoOutputSampleRate(); - srcState.src = new SampleRateConverter(*context->synth, outputSampleRate, srcState.srcQuality); - return MT32EMU_RC_OK; -} - -void mt32emu_close_synth(mt32emu_const_context context) { - context->synth->close(); - delete context->srcState->src; - context->srcState->src = NULL; -} - -mt32emu_boolean mt32emu_is_open(mt32emu_const_context context) { - return context->synth->isOpen() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -mt32emu_bit32u mt32emu_get_actual_stereo_output_samplerate(mt32emu_const_context context) { - if (context->srcState->src == NULL) { - return context->synth->getStereoOutputSampleRate(); - } - return mt32emu_bit32u(0.5 + context->srcState->src->convertSynthToOutputTimestamp(SAMPLE_RATE)); -} - -mt32emu_bit32u mt32emu_convert_output_to_synth_timestamp(mt32emu_const_context context, mt32emu_bit32u output_timestamp) { - if (context->srcState->src == NULL) { - return output_timestamp; - } - return mt32emu_bit32u(0.5 + context->srcState->src->convertOutputToSynthTimestamp(output_timestamp)); -} - -mt32emu_bit32u mt32emu_convert_synth_to_output_timestamp(mt32emu_const_context context, mt32emu_bit32u synth_timestamp) { - if (context->srcState->src == NULL) { - return synth_timestamp; - } - return mt32emu_bit32u(0.5 + context->srcState->src->convertSynthToOutputTimestamp(synth_timestamp)); -} - -void mt32emu_flush_midi_queue(mt32emu_const_context context) { - context->synth->flushMIDIQueue(); -} - -mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size) { - return context->synth->setMIDIEventQueueSize(queue_size); -} - -void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data) { - delete context->midiParser; - context->midiParser = (midi_receiver.v0 != NULL) ? new DelegatingMidiStreamParser(context, midi_receiver, instance_data) : new DefaultMidiStreamParser(*context->synth); -} - -mt32emu_bit32u mt32emu_get_internal_rendered_sample_count(mt32emu_const_context context) { - return context->synth->getInternalRenderedSampleCount(); -} - -void mt32emu_parse_stream(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length) { - context->midiParser->resetTimestamp(); - context->midiParser->parseStream(stream, length); -} - -void mt32emu_parse_stream_at(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp) { - context->midiParser->setTimestamp(timestamp); - context->midiParser->parseStream(stream, length); -} - -void mt32emu_play_short_message(mt32emu_const_context context, mt32emu_bit32u message) { - context->midiParser->resetTimestamp(); - context->midiParser->processShortMessage(message); -} - -void mt32emu_play_short_message_at(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp) { - context->midiParser->setTimestamp(timestamp); - context->midiParser->processShortMessage(message); -} - -mt32emu_return_code mt32emu_play_msg(mt32emu_const_context context, mt32emu_bit32u msg) { - if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; - return (context->synth->playMsg(msg)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; -} - -mt32emu_return_code mt32emu_play_sysex(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { - if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; - return (context->synth->playSysex(sysex, len)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; -} - -mt32emu_return_code mt32emu_play_msg_at(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp) { - if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; - return (context->synth->playMsg(msg, timestamp)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; -} - -mt32emu_return_code mt32emu_play_sysex_at(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp) { - if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; - return (context->synth->playSysex(sysex, len, timestamp)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; -} - -void mt32emu_play_msg_now(mt32emu_const_context context, mt32emu_bit32u msg) { - context->synth->playMsgNow(msg); -} - -void mt32emu_play_msg_on_part(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity) { - context->synth->playMsgOnPart(part, code, note, velocity); -} - -void mt32emu_play_sysex_now(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { - context->synth->playSysexNow(sysex, len); -} - -void mt32emu_write_sysex(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { - context->synth->writeSysex(channel, sysex, len); -} - -void mt32emu_set_reverb_enabled(mt32emu_const_context context, const mt32emu_boolean reverb_enabled) { - context->synth->setReverbEnabled(reverb_enabled != MT32EMU_BOOL_FALSE); -} - -mt32emu_boolean mt32emu_is_reverb_enabled(mt32emu_const_context context) { - return context->synth->isReverbEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -void mt32emu_set_reverb_overridden(mt32emu_const_context context, const mt32emu_boolean reverb_overridden) { - context->synth->setReverbOverridden(reverb_overridden != MT32EMU_BOOL_FALSE); -} - -mt32emu_boolean mt32emu_is_reverb_overridden(mt32emu_const_context context) { - return context->synth->isReverbOverridden() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -void mt32emu_set_reverb_compatibility_mode(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode) { - context->synth->setReverbCompatibilityMode(mt32_compatible_mode != MT32EMU_BOOL_FALSE); -} - -mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu_const_context context) { - return context->synth->isMT32ReverbCompatibilityMode() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context) { - return context->synth->isDefaultReverbMT32Compatible() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode) { - context->synth->setDACInputMode(static_cast(mode)); -} - -mt32emu_dac_input_mode mt32emu_get_dac_input_mode(mt32emu_const_context context) { - return static_cast(context->synth->getDACInputMode()); -} - -void mt32emu_set_midi_delay_mode(mt32emu_const_context context, const mt32emu_midi_delay_mode mode) { - context->synth->setMIDIDelayMode(static_cast(mode)); -} - -mt32emu_midi_delay_mode mt32emu_get_midi_delay_mode(mt32emu_const_context context) { - return static_cast(context->synth->getMIDIDelayMode()); -} - -void mt32emu_set_output_gain(mt32emu_const_context context, float gain) { - context->synth->setOutputGain(gain); -} - -float mt32emu_get_output_gain(mt32emu_const_context context) { - return context->synth->getOutputGain(); -} - -void mt32emu_set_reverb_output_gain(mt32emu_const_context context, float gain) { - context->synth->setReverbOutputGain(gain); -} - -float mt32emu_get_reverb_output_gain(mt32emu_const_context context) { - return context->synth->getReverbOutputGain(); -} - -void mt32emu_set_reversed_stereo_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) { - context->synth->setReversedStereoEnabled(enabled != MT32EMU_BOOL_FALSE); -} - -mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context) { - return context->synth->isReversedStereoEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) { - context->synth->setNiceAmpRampEnabled(enabled != MT32EMU_BOOL_FALSE); -} - -mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context) { - return context->synth->isNiceAmpRampEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len) { - if (context->srcState->src != NULL) { - context->srcState->src->getOutputSamples(stream, len); - } else { - context->synth->render(stream, len); - } -} - -void mt32emu_render_float(mt32emu_const_context context, float *stream, mt32emu_bit32u len) { - if (context->srcState->src != NULL) { - context->srcState->src->getOutputSamples(stream, len); - } else { - context->synth->render(stream, len); - } -} - -void mt32emu_render_bit16s_streams(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len) { - context->synth->renderStreams(*reinterpret_cast *>(streams), len); -} - -void mt32emu_render_float_streams(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len) { - context->synth->renderStreams(*reinterpret_cast *>(streams), len); -} - -mt32emu_boolean mt32emu_has_active_partials(mt32emu_const_context context) { - return context->synth->hasActivePartials() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -mt32emu_boolean mt32emu_is_active(mt32emu_const_context context) { - return context->synth->isActive() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -mt32emu_bit32u mt32emu_get_partial_count(mt32emu_const_context context) { - return context->synth->getPartialCount(); -} - -mt32emu_bit32u mt32emu_get_part_states(mt32emu_const_context context) { - return context->synth->getPartStates(); -} - -void mt32emu_get_partial_states(mt32emu_const_context context, mt32emu_bit8u *partial_states) { - context->synth->getPartialStates(partial_states); -} - -mt32emu_bit32u mt32emu_get_playing_notes(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities) { - return context->synth->getPlayingNotes(part_number, keys, velocities); -} - -const char *mt32emu_get_patch_name(mt32emu_const_context context, mt32emu_bit8u part_number) { - return context->synth->getPatchName(part_number); -} - -void mt32emu_read_memory(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data) { - context->synth->readMemory(addr, len, data); -} - -} // extern "C" diff --git a/src - Cópia/sound/munt/c_interface/c_interface.h b/src - Cópia/sound/munt/c_interface/c_interface.h deleted file mode 100644 index 2ca3a3b04..000000000 --- a/src - Cópia/sound/munt/c_interface/c_interface.h +++ /dev/null @@ -1,434 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_C_INTERFACE_H -#define MT32EMU_C_INTERFACE_H - -#include - -#include "../globals.h" -#include "c_types.h" - -#undef MT32EMU_EXPORT -#define MT32EMU_EXPORT MT32EMU_EXPORT_ATTRIBUTE - -#ifdef __cplusplus -extern "C" { -#endif - -/* == Context-independent functions == */ - -/* === Interface handling === */ - -/** Returns mt32emu_service_i interface. */ -MT32EMU_EXPORT mt32emu_service_i mt32emu_get_service_i(); - -#if MT32EMU_EXPORTS_TYPE == 2 -#undef MT32EMU_EXPORT -#define MT32EMU_EXPORT -#endif - -/** - * Returns the version ID of mt32emu_report_handler_i interface the library has been compiled with. - * This allows a client to fall-back gracefully instead of silently not receiving expected event reports. - */ -MT32EMU_EXPORT mt32emu_report_handler_version mt32emu_get_supported_report_handler_version(); - -/** - * Returns the version ID of mt32emu_midi_receiver_version_i interface the library has been compiled with. - * This allows a client to fall-back gracefully instead of silently not receiving expected MIDI messages. - */ -MT32EMU_EXPORT mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version(); - -/** - * Returns library version as an integer in format: 0x00MMmmpp, where: - * MM - major version number - * mm - minor version number - * pp - patch number - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_library_version_int(); - -/** - * Returns library version as a C-string in format: "MAJOR.MINOR.PATCH". - */ -MT32EMU_EXPORT const char *mt32emu_get_library_version_string(); - -/** - * Returns output sample rate used in emulation of stereo analog circuitry of hardware units for particular analog_output_mode. - * See comment for mt32emu_analog_output_mode. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_stereo_output_samplerate(const mt32emu_analog_output_mode analog_output_mode); - -/** - * Returns the value of analog_output_mode for which the output signal may retain its full frequency spectrum - * at the sample rate specified by the target_samplerate argument. - * See comment for mt32emu_analog_output_mode. - */ -MT32EMU_EXPORT mt32emu_analog_output_mode mt32emu_get_best_analog_output_mode(const double target_samplerate); - -/* == Context-dependent functions == */ - -/** Initialises a new emulation context and installs custom report handler if non-NULL. */ -MT32EMU_EXPORT mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler, void *instance_data); - -/** Closes and destroys emulation context. */ -MT32EMU_EXPORT void mt32emu_free_context(mt32emu_context context); - -/** - * Adds new ROM identified by its SHA1 digest to the emulation context replacing previously added ROM of the same type if any. - * Argument sha1_digest can be NULL, in this case the digest will be computed using the actual ROM data. - * If sha1_digest is set to non-NULL, it is assumed being correct and will not be recomputed. - * This function doesn't immediately change the state of already opened synth. Newly added ROM will take effect upon next call of mt32emu_open_synth(). - * Returns positive value upon success. - */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_add_rom_data(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest); - -/** - * Loads a ROM file, identify it by SHA1 digest, and adds it to the emulation context replacing previously added ROM of the same type if any. - * This function doesn't immediately change the state of already opened synth. Newly added ROM will take effect upon next call of mt32emu_open_synth(). - * Returns positive value upon success. - */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_add_rom_file(mt32emu_context context, const char *filename); - -/** - * Fills in mt32emu_rom_info structure with identifiers and descriptions of control and PCM ROM files identified and added to the synth context. - * If one of the ROM files is not loaded and identified yet, NULL is returned in the corresponding fields of the mt32emu_rom_info structure. - */ -MT32EMU_EXPORT void mt32emu_get_rom_info(mt32emu_const_context context, mt32emu_rom_info *rom_info); - -/** - * Allows to override the default maximum number of partials playing simultaneously within the emulation session. - * This function doesn't immediately change the state of already opened synth. Newly set value will take effect upon next call of mt32emu_open_synth(). - */ -MT32EMU_EXPORT void mt32emu_set_partial_count(mt32emu_context context, const mt32emu_bit32u partial_count); - -/** - * Allows to override the default mode for emulation of analogue circuitry of the hardware units within the emulation session. - * This function doesn't immediately change the state of already opened synth. Newly set value will take effect upon next call of mt32emu_open_synth(). - */ -MT32EMU_EXPORT void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode); - -/** - * Allows to convert the synthesiser output to any desired sample rate. The samplerate conversion - * processes the completely mixed stereo output signal as it passes the analogue circuit emulation, - * so emulating the synthesiser output signal passing further through an ADC. When the samplerate - * argument is set to 0, the default output sample rate is used which depends on the current - * mode of analog circuitry emulation. See mt32emu_analog_output_mode. - * This function doesn't immediately change the state of already opened synth. - * Newly set value will take effect upon next call of mt32emu_open_synth(). - */ -MT32EMU_EXPORT void mt32emu_set_stereo_output_samplerate(mt32emu_context context, const double samplerate); - -/** - * Several samplerate conversion quality options are provided which allow to trade-off the conversion speed vs. - * the retained passband width. All the options except FASTEST guarantee full suppression of the aliasing noise - * in terms of the 16-bit integer samples. - * This function doesn't immediately change the state of already opened synth. - * Newly set value will take effect upon next call of mt32emu_open_synth(). - */ -MT32EMU_EXPORT void mt32emu_set_samplerate_conversion_quality(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality); - -/** - * Selects new type of the wave generator and renderer to be used during subsequent calls to mt32emu_open_synth(). - * By default, MT32EMU_RT_BIT16S is selected. - * See mt32emu_renderer_type for details. - */ -MT32EMU_EXPORT void mt32emu_select_renderer_type(mt32emu_context context, const mt32emu_renderer_type renderer_type); - -/** - * Returns previously selected type of the wave generator and renderer. - * See mt32emu_renderer_type for details. - */ -MT32EMU_EXPORT mt32emu_renderer_type mt32emu_get_selected_renderer_type(mt32emu_context context); - -/** - * Prepares the emulation context to receive MIDI messages and produce output audio data using aforehand added set of ROMs, - * and optionally set the maximum partial count and the analog output mode. - * Returns MT32EMU_RC_OK upon success. - */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_open_synth(mt32emu_const_context context); - -/** Closes the emulation context freeing allocated resources. Added ROMs remain unaffected and ready for reuse. */ -MT32EMU_EXPORT void mt32emu_close_synth(mt32emu_const_context context); - -/** Returns true if the synth is in completely initialized state, otherwise returns false. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_open(mt32emu_const_context context); - -/** - * Returns actual sample rate of the fully processed output stereo signal. - * If samplerate conversion is used (i.e. when mt32emu_set_stereo_output_samplerate() has been invoked with a non-zero value), - * the returned value is the desired output samplerate rounded down to the closest integer. - * Otherwise, the output samplerate is choosen depending on the emulation mode of stereo analog circuitry of hardware units. - * See comment for mt32emu_analog_output_mode for more info. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_actual_stereo_output_samplerate(mt32emu_const_context context); - -/** - * Returns the number of samples produced at the internal synth sample rate (32000 Hz) - * that correspond to the given number of samples at the output sample rate. - * Intended to facilitate audio time synchronisation. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_convert_output_to_synth_timestamp(mt32emu_const_context context, mt32emu_bit32u output_timestamp); - -/** - * Returns the number of samples produced at the output sample rate - * that correspond to the given number of samples at the internal synth sample rate (32000 Hz). - * Intended to facilitate audio time synchronisation. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_convert_synth_to_output_timestamp(mt32emu_const_context context, mt32emu_bit32u synth_timestamp); - -/** All the enqueued events are processed by the synth immediately. */ -MT32EMU_EXPORT void mt32emu_flush_midi_queue(mt32emu_const_context context); - -/** - * Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified. - * The queue is flushed before reallocation. - * Returns the actual queue size being used. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size); - -/** - * Installs custom MIDI receiver object intended for receiving MIDI messages generated by MIDI stream parser. - * MIDI stream parser is involved when functions mt32emu_parse_stream() and mt32emu_play_short_message() or the likes are called. - * By default, parsed short MIDI messages and System Exclusive messages are sent to the synth input MIDI queue. - * This function allows to override default behaviour. If midi_receiver argument is set to NULL, the default behaviour is restored. - */ -MT32EMU_EXPORT void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data); - -/** - * Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz). - * This method helps to compute accurate timestamp of a MIDI message to use with the methods below. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_internal_rendered_sample_count(mt32emu_const_context context); - -/* Enqueues a MIDI event for subsequent playback. - * The MIDI event will be processed not before the specified timestamp. - * The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz). - * The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface - * and emulation of the MCU busy-loop while it frees partials for use by a new Poly. - * Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread. - * onMIDIQueueOverflow callback is invoked when the MIDI event queue is full and the message cannot be enqueued. - */ - -/** - * Parses a block of raw MIDI bytes and enqueues parsed MIDI messages for further processing ASAP. - * SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. - * When a System Realtime MIDI message is parsed, onMIDISystemRealtime callback is invoked. - * NOTE: the total length of a SysEx message being fragmented shall not exceed MT32EMU_MAX_STREAM_BUFFER_SIZE (32768 bytes). - */ -MT32EMU_EXPORT void mt32emu_parse_stream(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length); - -/** - * Parses a block of raw MIDI bytes and enqueues parsed MIDI messages to play at specified time. - * SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. - * When a System Realtime MIDI message is parsed, onMIDISystemRealtime callback is invoked. - * NOTE: the total length of a SysEx message being fragmented shall not exceed MT32EMU_MAX_STREAM_BUFFER_SIZE (32768 bytes). - */ -MT32EMU_EXPORT void mt32emu_parse_stream_at(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp); - -/** - * Enqueues a single mt32emu_bit32u-encoded short MIDI message with full processing ASAP. - * The short MIDI message may contain no status byte, the running status is used in this case. - * When the argument is a System Realtime MIDI message, onMIDISystemRealtime callback is invoked. - */ -MT32EMU_EXPORT void mt32emu_play_short_message(mt32emu_const_context context, mt32emu_bit32u message); - -/** - * Enqueues a single mt32emu_bit32u-encoded short MIDI message to play at specified time with full processing. - * The short MIDI message may contain no status byte, the running status is used in this case. - * When the argument is a System Realtime MIDI message, onMIDISystemRealtime callback is invoked. - */ -MT32EMU_EXPORT void mt32emu_play_short_message_at(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp); - -/** Enqueues a single short MIDI message to be processed ASAP. The message must contain a status byte. */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_play_msg(mt32emu_const_context context, mt32emu_bit32u msg); -/** Enqueues a single well formed System Exclusive MIDI message to be processed ASAP. */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_play_sysex(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); - -/** Enqueues a single short MIDI message to play at specified time. The message must contain a status byte. */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_play_msg_at(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp); -/** Enqueues a single well formed System Exclusive MIDI message to play at specified time. */ -MT32EMU_EXPORT mt32emu_return_code mt32emu_play_sysex_at(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp); - -/* WARNING: - * The methods below don't ensure minimum 1-sample delay between sequential MIDI events, - * and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent. - * A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering. - */ - -/** - * Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte. - * See the WARNING above. - */ -MT32EMU_EXPORT void mt32emu_play_msg_now(mt32emu_const_context context, mt32emu_bit32u msg); -/** - * Sends unpacked short MIDI message to the synth for immediate playback. The message must contain a status byte. - * See the WARNING above. - */ -MT32EMU_EXPORT void mt32emu_play_msg_on_part(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity); - -/** - * Sends a single well formed System Exclusive MIDI message for immediate processing. The length is in bytes. - * See the WARNING above. - */ -MT32EMU_EXPORT void mt32emu_play_sysex_now(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); -/** - * Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. - * See the WARNING above. - */ -MT32EMU_EXPORT void mt32emu_write_sysex(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len); - -/** Allows to disable wet reverb output altogether. */ -MT32EMU_EXPORT void mt32emu_set_reverb_enabled(mt32emu_const_context context, const mt32emu_boolean reverb_enabled); -/** Returns whether wet reverb output is enabled. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reverb_enabled(mt32emu_const_context context); -/** - * Sets override reverb mode. In this mode, emulation ignores sysexes (or the related part of them) which control the reverb parameters. - * This mode is in effect until it is turned off. When the synth is re-opened, the override mode is unchanged but the state - * of the reverb model is reset to default. - */ -MT32EMU_EXPORT void mt32emu_set_reverb_overridden(mt32emu_const_context context, const mt32emu_boolean reverb_overridden); -/** Returns whether reverb settings are overridden. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reverb_overridden(mt32emu_const_context context); -/** - * Forces reverb model compatibility mode. By default, the compatibility mode corresponds to the used control ROM version. - * Invoking this method with the argument set to true forces emulation of old MT-32 reverb circuit. - * When the argument is false, emulation of the reverb circuit used in new generation of MT-32 compatible modules is enforced - * (these include CM-32L and LAPC-I). - */ -MT32EMU_EXPORT void mt32emu_set_reverb_compatibility_mode(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode); -/** Returns whether reverb is in old MT-32 compatibility mode. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu_const_context context); -/** Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context); - -/** Sets new DAC input mode. See mt32emu_dac_input_mode for details. */ -MT32EMU_EXPORT void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode); -/** Returns current DAC input mode. See mt32emu_dac_input_mode for details. */ -MT32EMU_EXPORT mt32emu_dac_input_mode mt32emu_get_dac_input_mode(mt32emu_const_context context); - -/** Sets new MIDI delay mode. See mt32emu_midi_delay_mode for details. */ -MT32EMU_EXPORT void mt32emu_set_midi_delay_mode(mt32emu_const_context context, const mt32emu_midi_delay_mode mode); -/** Returns current MIDI delay mode. See mt32emu_midi_delay_mode for details. */ -MT32EMU_EXPORT mt32emu_midi_delay_mode mt32emu_get_midi_delay_mode(mt32emu_const_context context); - -/** - * Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume, - * it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with mt32emu_set_reverb_output_gain() - * it offers to the user a capability to control the gain of reverb and non-reverb output channels independently. - */ -MT32EMU_EXPORT void mt32emu_set_output_gain(mt32emu_const_context context, float gain); -/** Returns current output gain factor for synth output channels. */ -MT32EMU_EXPORT float mt32emu_get_output_gain(mt32emu_const_context context); - -/** - * Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output - * analog circuitry of the hardware units. However, together with mt32emu_set_output_gain() it offers to the user a capability - * to control the gain of reverb and non-reverb output channels independently. - * - * Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely - * corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic, - * there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68 - * of that for LA32 analogue output. This factor is applied to the reverb output gain. - */ -MT32EMU_EXPORT void mt32emu_set_reverb_output_gain(mt32emu_const_context context, float gain); -/** Returns current output gain factor for reverb wet output channels. */ -MT32EMU_EXPORT float mt32emu_get_reverb_output_gain(mt32emu_const_context context); - -/** Swaps left and right output channels. */ -MT32EMU_EXPORT void mt32emu_set_reversed_stereo_enabled(mt32emu_const_context context, const mt32emu_boolean enabled); -/** Returns whether left and right output channels are swapped. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context); - -/** - * Allows to toggle the NiceAmpRamp mode. - * In this mode, we want to ensure that amp ramp never jumps to the target - * value and always gradually increases or decreases. It seems that real units - * do not bother to always check if a newly started ramp leads to a jump. - * We also prefer the quality improvement over the emulation accuracy, - * so this mode is enabled by default. - */ -MT32EMU_EXPORT void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context context, const mt32emu_boolean enabled); -/** Returns whether NiceAmpRamp mode is enabled. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context); - -/** - * Renders samples to the specified output stream as if they were sampled at the analog stereo output at the desired sample rate. - * If the output sample rate is not specified explicitly, the default output sample rate is used which depends on the current - * mode of analog circuitry emulation. See mt32emu_analog_output_mode. - * The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes). Uses NATIVE byte ordering. - */ -MT32EMU_EXPORT void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len); -/** Same as above but outputs to a float stereo stream. */ -MT32EMU_EXPORT void mt32emu_render_float(mt32emu_const_context context, float *stream, mt32emu_bit32u len); - -/** - * Renders samples to the specified output streams as if they appeared at the DAC entrance. - * No further processing performed in analog circuitry emulation is applied to the signal. - * NULL may be specified in place of any or all of the stream buffers to skip it. - * The length is in samples, not bytes. Uses NATIVE byte ordering. - */ -MT32EMU_EXPORT void mt32emu_render_bit16s_streams(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len); -/** Same as above but outputs to float streams. */ -MT32EMU_EXPORT void mt32emu_render_float_streams(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len); - -/** Returns true when there is at least one active partial, otherwise false. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_has_active_partials(mt32emu_const_context context); - -/** Returns true if mt32emu_has_active_partials() returns true, or reverb is (somewhat unreliably) detected as being active. */ -MT32EMU_EXPORT mt32emu_boolean mt32emu_is_active(mt32emu_const_context context); - -/** Returns the maximum number of partials playing simultaneously. */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_partial_count(mt32emu_const_context context); - -/** - * Returns current states of all the parts as a bit set. The least significant bit corresponds to the state of part 1, - * total of 9 bits hold the states of all the parts. If the returned bit for a part is set, there is at least one active - * non-releasing partial playing on this part. This info is useful in emulating behaviour of LCD display of the hardware units. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_part_states(mt32emu_const_context context); - -/** - * Fills in current states of all the partials into the array provided. Each byte in the array holds states of 4 partials - * starting from the least significant bits. The state of each partial is packed in a pair of bits. - * The array must be large enough to accommodate states of all the partials. - * @see getPartialCount() - */ -MT32EMU_EXPORT void mt32emu_get_partial_states(mt32emu_const_context context, mt32emu_bit8u *partial_states); - -/** - * Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough - * to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials. - * Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. - * Returns the number of currently playing notes on the specified part. - */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_playing_notes(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities); - -/** - * Returns name of the patch set on the specified part. - * Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. - */ -MT32EMU_EXPORT const char *mt32emu_get_patch_name(mt32emu_const_context context, mt32emu_bit8u part_number); - -/** Stores internal state of emulated synth into an array provided (as it would be acquired from hardware). */ -MT32EMU_EXPORT void mt32emu_read_memory(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* #ifndef MT32EMU_C_INTERFACE_H */ diff --git a/src - Cópia/sound/munt/c_interface/c_types.h b/src - Cópia/sound/munt/c_interface/c_types.h deleted file mode 100644 index db612e282..000000000 --- a/src - Cópia/sound/munt/c_interface/c_types.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_C_TYPES_H -#define MT32EMU_C_TYPES_H - -#include -#include - -#include "../globals.h" - -#define MT32EMU_C_ENUMERATIONS -#include "../Enumerations.h" -#undef MT32EMU_C_ENUMERATIONS - -typedef unsigned int mt32emu_bit32u; -typedef signed int mt32emu_bit32s; -typedef unsigned short int mt32emu_bit16u; -typedef signed short int mt32emu_bit16s; -typedef unsigned char mt32emu_bit8u; -typedef signed char mt32emu_bit8s; - -typedef char mt32emu_sha1_digest[41]; - -typedef enum { - MT32EMU_BOOL_FALSE, MT32EMU_BOOL_TRUE -} mt32emu_boolean; - -typedef enum { - /* Operation completed normally. */ - MT32EMU_RC_OK = 0, - MT32EMU_RC_ADDED_CONTROL_ROM = 1, - MT32EMU_RC_ADDED_PCM_ROM = 2, - - /* Definite error occurred. */ - MT32EMU_RC_ROM_NOT_IDENTIFIED = -1, - MT32EMU_RC_FILE_NOT_FOUND = -2, - MT32EMU_RC_FILE_NOT_LOADED = -3, - MT32EMU_RC_MISSING_ROMS = -4, - MT32EMU_RC_NOT_OPENED = -5, - MT32EMU_RC_QUEUE_FULL = -6, - - /* Undefined error occurred. */ - MT32EMU_RC_FAILED = -100 -} mt32emu_return_code; - -/** Emulation context */ -typedef struct mt32emu_data *mt32emu_context; -typedef const struct mt32emu_data *mt32emu_const_context; - -/* Convenience aliases */ -#ifndef __cplusplus -typedef enum mt32emu_analog_output_mode mt32emu_analog_output_mode; -typedef enum mt32emu_dac_input_mode mt32emu_dac_input_mode; -typedef enum mt32emu_midi_delay_mode mt32emu_midi_delay_mode; -typedef enum mt32emu_partial_state mt32emu_partial_state; -typedef enum mt32emu_samplerate_conversion_quality mt32emu_samplerate_conversion_quality; -typedef enum mt32emu_renderer_type mt32emu_renderer_type; -#endif - -/** Contains identifiers and descriptions of ROM files being used. */ -typedef struct { - const char *control_rom_id; - const char *control_rom_description; - const char *control_rom_sha1_digest; - const char *pcm_rom_id; - const char *pcm_rom_description; - const char *pcm_rom_sha1_digest; -} mt32emu_rom_info; - -/** Set of multiplexed output bit16s streams appeared at the DAC entrance. */ -typedef struct { - mt32emu_bit16s *nonReverbLeft; - mt32emu_bit16s *nonReverbRight; - mt32emu_bit16s *reverbDryLeft; - mt32emu_bit16s *reverbDryRight; - mt32emu_bit16s *reverbWetLeft; - mt32emu_bit16s *reverbWetRight; -} mt32emu_dac_output_bit16s_streams; - -/** Set of multiplexed output float streams appeared at the DAC entrance. */ -typedef struct { - float *nonReverbLeft; - float *nonReverbRight; - float *reverbDryLeft; - float *reverbDryRight; - float *reverbWetLeft; - float *reverbWetRight; -} mt32emu_dac_output_float_streams; - -/* === Interface handling === */ - -/** Report handler interface versions */ -typedef enum { - MT32EMU_REPORT_HANDLER_VERSION_0 = 0, - MT32EMU_REPORT_HANDLER_VERSION_CURRENT = MT32EMU_REPORT_HANDLER_VERSION_0 -} mt32emu_report_handler_version; - -/** MIDI receiver interface versions */ -typedef enum { - MT32EMU_MIDI_RECEIVER_VERSION_0 = 0, - MT32EMU_MIDI_RECEIVER_VERSION_CURRENT = MT32EMU_MIDI_RECEIVER_VERSION_0 -} mt32emu_midi_receiver_version; - -/** Synth interface versions */ -typedef enum { - MT32EMU_SERVICE_VERSION_0 = 0, - MT32EMU_SERVICE_VERSION_1 = 1, - MT32EMU_SERVICE_VERSION_2 = 2, - MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_2 -} mt32emu_service_version; - -/* === Report Handler Interface === */ - -typedef union mt32emu_report_handler_i mt32emu_report_handler_i; - -/** Interface for handling reported events (initial version) */ -typedef struct { - /** Returns the actual interface version ID */ - mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); - - /** Callback for debug messages, in vprintf() format */ - void (*printDebug)(void *instance_data, const char *fmt, va_list list); - /** Callbacks for reporting errors */ - void (*onErrorControlROM)(void *instance_data); - void (*onErrorPCMROM)(void *instance_data); - /** Callback for reporting about displaying a new custom message on LCD */ - void (*showLCDMessage)(void *instance_data, const char *message); - /** Callback for reporting actual processing of a MIDI message */ - void (*onMIDIMessagePlayed)(void *instance_data); - /** - * Callback for reporting an overflow of the input MIDI queue. - * Returns MT32EMU_BOOL_TRUE if a recovery action was taken - * and yet another attempt to enqueue the MIDI event is desired. - */ - mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); - /** - * Callback invoked when a System Realtime MIDI message is detected in functions - * mt32emu_parse_stream and mt32emu_play_short_message and the likes. - */ - void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); - /** Callbacks for reporting system events */ - void (*onDeviceReset)(void *instance_data); - void (*onDeviceReconfig)(void *instance_data); - /** Callbacks for reporting changes of reverb settings */ - void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); - void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); - void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); - /** Callbacks for reporting various information */ - void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); - void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); -} mt32emu_report_handler_i_v0; - -/** - * Extensible interface for handling reported events. - * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. - * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. - */ -union mt32emu_report_handler_i { - const mt32emu_report_handler_i_v0 *v0; -}; - -/* === MIDI Receiver Interface === */ - -typedef union mt32emu_midi_receiver_i mt32emu_midi_receiver_i; - -/** Interface for receiving MIDI messages generated by MIDI stream parser (initial version) */ -typedef struct { - /** Returns the actual interface version ID */ - mt32emu_midi_receiver_version (*getVersionID)(mt32emu_midi_receiver_i i); - - /** Invoked when a complete short MIDI message is parsed in the input MIDI stream. */ - void (*handleShortMessage)(void *instance_data, const mt32emu_bit32u message); - - /** Invoked when a complete well-formed System Exclusive MIDI message is parsed in the input MIDI stream. */ - void (*handleSysex)(void *instance_data, const mt32emu_bit8u stream[], const mt32emu_bit32u length); - - /** Invoked when a System Realtime MIDI message is parsed in the input MIDI stream. */ - void (*handleSystemRealtimeMessage)(void *instance_data, const mt32emu_bit8u realtime); -} mt32emu_midi_receiver_i_v0; - -/** - * Extensible interface for receiving MIDI messages. - * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. - * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. - */ -union mt32emu_midi_receiver_i { - const mt32emu_midi_receiver_i_v0 *v0; -}; - -/* === Service Interface === */ - -typedef union mt32emu_service_i mt32emu_service_i; - -/** - * Basic interface that defines all the library services (initial version). - * The members closely resemble C functions declared in c_interface.h, and the intention is to provide for easier - * access when the library is dynamically loaded in run-time, e.g. as a plugin. This way the client only needs - * to bind to mt32emu_get_service_i() function instead of binding to each function it needs to use. - * See c_interface.h for parameter description. - */ -#define MT32EMU_SERVICE_I_V0 \ - /** Returns the actual interface version ID */ \ - mt32emu_service_version (*getVersionID)(mt32emu_service_i i); \ - mt32emu_report_handler_version (*getSupportedReportHandlerVersionID)(); \ - mt32emu_midi_receiver_version (*getSupportedMIDIReceiverVersionID)(); \ -\ - mt32emu_bit32u (*getLibraryVersionInt)(); \ - const char *(*getLibraryVersionString)(); \ -\ - mt32emu_bit32u (*getStereoOutputSamplerate)(const mt32emu_analog_output_mode analog_output_mode); \ -\ - mt32emu_context (*createContext)(mt32emu_report_handler_i report_handler, void *instance_data); \ - void (*freeContext)(mt32emu_context context); \ - mt32emu_return_code (*addROMData)(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest); \ - mt32emu_return_code (*addROMFile)(mt32emu_context context, const char *filename); \ - void (*getROMInfo)(mt32emu_const_context context, mt32emu_rom_info *rom_info); \ - void (*setPartialCount)(mt32emu_context context, const mt32emu_bit32u partial_count); \ - void (*setAnalogOutputMode)(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode); \ - mt32emu_return_code (*openSynth)(mt32emu_const_context context); \ - void (*closeSynth)(mt32emu_const_context context); \ - mt32emu_boolean (*isOpen)(mt32emu_const_context context); \ - mt32emu_bit32u (*getActualStereoOutputSamplerate)(mt32emu_const_context context); \ - void (*flushMIDIQueue)(mt32emu_const_context context); \ - mt32emu_bit32u (*setMIDIEventQueueSize)(mt32emu_const_context context, const mt32emu_bit32u queue_size); \ - void (*setMIDIReceiver)(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data); \ -\ - void (*parseStream)(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length); \ - void (*parseStream_At)(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp); \ - void (*playShortMessage)(mt32emu_const_context context, mt32emu_bit32u message); \ - void (*playShortMessageAt)(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp); \ - mt32emu_return_code (*playMsg)(mt32emu_const_context context, mt32emu_bit32u msg); \ - mt32emu_return_code (*playSysex)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ - mt32emu_return_code (*playMsgAt)(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp); \ - mt32emu_return_code (*playSysexAt)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp); \ -\ - void (*playMsgNow)(mt32emu_const_context context, mt32emu_bit32u msg); \ - void (*playMsgOnPart)(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity); \ - void (*playSysexNow)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ - void (*writeSysex)(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ -\ - void (*setReverbEnabled)(mt32emu_const_context context, const mt32emu_boolean reverb_enabled); \ - mt32emu_boolean (*isReverbEnabled)(mt32emu_const_context context); \ - void (*setReverbOverridden)(mt32emu_const_context context, const mt32emu_boolean reverb_overridden); \ - mt32emu_boolean (*isReverbOverridden)(mt32emu_const_context context); \ - void (*setReverbCompatibilityMode)(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode); \ - mt32emu_boolean (*isMT32ReverbCompatibilityMode)(mt32emu_const_context context); \ - mt32emu_boolean (*isDefaultReverbMT32Compatible)(mt32emu_const_context context); \ -\ - void (*setDACInputMode)(mt32emu_const_context context, const mt32emu_dac_input_mode mode); \ - mt32emu_dac_input_mode (*getDACInputMode)(mt32emu_const_context context); \ -\ - void (*setMIDIDelayMode)(mt32emu_const_context context, const mt32emu_midi_delay_mode mode); \ - mt32emu_midi_delay_mode (*getMIDIDelayMode)(mt32emu_const_context context); \ -\ - void (*setOutputGain)(mt32emu_const_context context, float gain); \ - float (*getOutputGain)(mt32emu_const_context context); \ - void (*setReverbOutputGain)(mt32emu_const_context context, float gain); \ - float (*getReverbOutputGain)(mt32emu_const_context context); \ -\ - void (*setReversedStereoEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ - mt32emu_boolean (*isReversedStereoEnabled)(mt32emu_const_context context); \ -\ - void (*renderBit16s)(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len); \ - void (*renderFloat)(mt32emu_const_context context, float *stream, mt32emu_bit32u len); \ - void (*renderBit16sStreams)(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len); \ - void (*renderFloatStreams)(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len); \ -\ - mt32emu_boolean (*hasActivePartials)(mt32emu_const_context context); \ - mt32emu_boolean (*isActive)(mt32emu_const_context context); \ - mt32emu_bit32u (*getPartialCount)(mt32emu_const_context context); \ - mt32emu_bit32u (*getPartStates)(mt32emu_const_context context); \ - void (*getPartialStates)(mt32emu_const_context context, mt32emu_bit8u *partial_states); \ - mt32emu_bit32u (*getPlayingNotes)(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities); \ - const char *(*getPatchName)(mt32emu_const_context context, mt32emu_bit8u part_number); \ - void (*readMemory)(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data); - -#define MT32EMU_SERVICE_I_V1 \ - mt32emu_analog_output_mode (*getBestAnalogOutputMode)(const double target_samplerate); \ - void (*setStereoOutputSampleRate)(mt32emu_context context, const double samplerate); \ - void (*setSamplerateConversionQuality)(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality); \ - void (*selectRendererType)(mt32emu_context context, mt32emu_renderer_type renderer_type); \ - mt32emu_renderer_type (*getSelectedRendererType)(mt32emu_context context); \ - mt32emu_bit32u (*convertOutputToSynthTimestamp)(mt32emu_const_context context, mt32emu_bit32u output_timestamp); \ - mt32emu_bit32u (*convertSynthToOutputTimestamp)(mt32emu_const_context context, mt32emu_bit32u synth_timestamp); - -#define MT32EMU_SERVICE_I_V2 \ - mt32emu_bit32u (*getInternalRenderedSampleCount)(mt32emu_const_context context); \ - void (*setNiceAmpRampEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ - mt32emu_boolean (*isNiceAmpRampEnabled)(mt32emu_const_context context); - -typedef struct { - MT32EMU_SERVICE_I_V0 -} mt32emu_service_i_v0; - -typedef struct { - MT32EMU_SERVICE_I_V0 - MT32EMU_SERVICE_I_V1 -} mt32emu_service_i_v1; - -typedef struct { - MT32EMU_SERVICE_I_V0 - MT32EMU_SERVICE_I_V1 - MT32EMU_SERVICE_I_V2 -} mt32emu_service_i_v2; - -/** - * Extensible interface for all the library services. - * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. - * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. - */ -union mt32emu_service_i { - const mt32emu_service_i_v0 *v0; - const mt32emu_service_i_v1 *v1; - const mt32emu_service_i_v2 *v2; -}; - -#undef MT32EMU_SERVICE_I_V0 -#undef MT32EMU_SERVICE_I_V1 -#undef MT32EMU_SERVICE_I_V2 - -#endif /* #ifndef MT32EMU_C_TYPES_H */ diff --git a/src - Cópia/sound/munt/c_interface/cpp_interface.h b/src - Cópia/sound/munt/c_interface/cpp_interface.h deleted file mode 100644 index 3b02c0325..000000000 --- a/src - Cópia/sound/munt/c_interface/cpp_interface.h +++ /dev/null @@ -1,479 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_CPP_INTERFACE_H -#define MT32EMU_CPP_INTERFACE_H - -#include - -#include "../globals.h" -#include "c_types.h" - -#include "../Types.h" -#include "../Enumerations.h" - -#if MT32EMU_API_TYPE == 2 - -extern "C" { - -/** Returns mt32emu_service_i interface. */ -mt32emu_service_i mt32emu_get_service_i(); - -} - -#define mt32emu_get_supported_report_handler_version i.v0->getSupportedReportHandlerVersionID -#define mt32emu_get_supported_midi_receiver_version i.v0->getSupportedMIDIReceiverVersionID -#define mt32emu_get_library_version_int i.v0->getLibraryVersionInt -#define mt32emu_get_library_version_string i.v0->getLibraryVersionString -#define mt32emu_get_stereo_output_samplerate i.v0->getStereoOutputSamplerate -#define mt32emu_get_best_analog_output_mode iV1()->getBestAnalogOutputMode -#define mt32emu_create_context i.v0->createContext -#define mt32emu_free_context i.v0->freeContext -#define mt32emu_add_rom_data i.v0->addROMData -#define mt32emu_add_rom_file i.v0->addROMFile -#define mt32emu_get_rom_info i.v0->getROMInfo -#define mt32emu_set_partial_count i.v0->setPartialCount -#define mt32emu_set_analog_output_mode i.v0->setAnalogOutputMode -#define mt32emu_set_stereo_output_samplerate iV1()->setStereoOutputSampleRate -#define mt32emu_set_samplerate_conversion_quality iV1()->setSamplerateConversionQuality -#define mt32emu_select_renderer_type iV1()->selectRendererType -#define mt32emu_get_selected_renderer_type iV1()->getSelectedRendererType -#define mt32emu_open_synth i.v0->openSynth -#define mt32emu_close_synth i.v0->closeSynth -#define mt32emu_is_open i.v0->isOpen -#define mt32emu_get_actual_stereo_output_samplerate i.v0->getActualStereoOutputSamplerate -#define mt32emu_convert_output_to_synth_timestamp iV1()->convertOutputToSynthTimestamp -#define mt32emu_convert_synth_to_output_timestamp iV1()->convertSynthToOutputTimestamp -#define mt32emu_flush_midi_queue i.v0->flushMIDIQueue -#define mt32emu_set_midi_event_queue_size i.v0->setMIDIEventQueueSize -#define mt32emu_set_midi_receiver i.v0->setMIDIReceiver -#define mt32emu_get_internal_rendered_sample_count iV2()->getInternalRenderedSampleCount -#define mt32emu_parse_stream i.v0->parseStream -#define mt32emu_parse_stream_at i.v0->parseStream_At -#define mt32emu_play_short_message i.v0->playShortMessage -#define mt32emu_play_short_message_at i.v0->playShortMessageAt -#define mt32emu_play_msg i.v0->playMsg -#define mt32emu_play_sysex i.v0->playSysex -#define mt32emu_play_msg_at i.v0->playMsgAt -#define mt32emu_play_sysex_at i.v0->playSysexAt -#define mt32emu_play_msg_now i.v0->playMsgNow -#define mt32emu_play_msg_on_part i.v0->playMsgOnPart -#define mt32emu_play_sysex_now i.v0->playSysexNow -#define mt32emu_write_sysex i.v0->writeSysex -#define mt32emu_set_reverb_enabled i.v0->setReverbEnabled -#define mt32emu_is_reverb_enabled i.v0->isReverbEnabled -#define mt32emu_set_reverb_overridden i.v0->setReverbOverridden -#define mt32emu_is_reverb_overridden i.v0->isReverbOverridden -#define mt32emu_set_reverb_compatibility_mode i.v0->setReverbCompatibilityMode -#define mt32emu_is_mt32_reverb_compatibility_mode i.v0->isMT32ReverbCompatibilityMode -#define mt32emu_is_default_reverb_mt32_compatible i.v0->isDefaultReverbMT32Compatible -#define mt32emu_set_dac_input_mode i.v0->setDACInputMode -#define mt32emu_get_dac_input_mode i.v0->getDACInputMode -#define mt32emu_set_midi_delay_mode i.v0->setMIDIDelayMode -#define mt32emu_get_midi_delay_mode i.v0->getMIDIDelayMode -#define mt32emu_set_output_gain i.v0->setOutputGain -#define mt32emu_get_output_gain i.v0->getOutputGain -#define mt32emu_set_reverb_output_gain i.v0->setReverbOutputGain -#define mt32emu_get_reverb_output_gain i.v0->getReverbOutputGain -#define mt32emu_set_reversed_stereo_enabled i.v0->setReversedStereoEnabled -#define mt32emu_is_reversed_stereo_enabled i.v0->isReversedStereoEnabled -#define mt32emu_set_nice_amp_ramp_enabled iV2()->setNiceAmpRampEnabled -#define mt32emu_is_nice_amp_ramp_enabled iV2()->isNiceAmpRampEnabled -#define mt32emu_render_bit16s i.v0->renderBit16s -#define mt32emu_render_float i.v0->renderFloat -#define mt32emu_render_bit16s_streams i.v0->renderBit16sStreams -#define mt32emu_render_float_streams i.v0->renderFloatStreams -#define mt32emu_has_active_partials i.v0->hasActivePartials -#define mt32emu_is_active i.v0->isActive -#define mt32emu_get_partial_count i.v0->getPartialCount -#define mt32emu_get_part_states i.v0->getPartStates -#define mt32emu_get_partial_states i.v0->getPartialStates -#define mt32emu_get_playing_notes i.v0->getPlayingNotes -#define mt32emu_get_patch_name i.v0->getPatchName -#define mt32emu_read_memory i.v0->readMemory - -#else // #if MT32EMU_API_TYPE == 2 - -#include "c_interface.h" - -#endif // #if MT32EMU_API_TYPE == 2 - -namespace MT32Emu { - -namespace CppInterfaceImpl { - -static const mt32emu_report_handler_i NULL_REPORT_HANDLER = { NULL }; -static mt32emu_report_handler_i getReportHandlerThunk(); -static mt32emu_midi_receiver_i getMidiReceiverThunk(); - -} - -/* - * The classes below correspond to the interfaces defined in c_types.h and provided for convenience when using C++. - * The approach used makes no assumption of any internal class data memory layout, since the C++ standard does not - * provide any detail in this area and leaves it up to the implementation. Therefore, this way portability is guaranteed, - * despite the implementation may be a little inefficient. - * See c_types.h and c_interface.h for description of the corresponding interface methods. - */ - -// Defines the interface for handling reported events. -// Corresponds to the current version of mt32emu_report_handler_i interface. -class IReportHandler { -public: - virtual void printDebug(const char *fmt, va_list list) = 0; - virtual void onErrorControlROM() = 0; - virtual void onErrorPCMROM() = 0; - virtual void showLCDMessage(const char *message) = 0; - virtual void onMIDIMessagePlayed() = 0; - virtual bool onMIDIQueueOverflow() = 0; - virtual void onMIDISystemRealtime(Bit8u system_realtime) = 0; - virtual void onDeviceReset() = 0; - virtual void onDeviceReconfig() = 0; - virtual void onNewReverbMode(Bit8u mode) = 0; - virtual void onNewReverbTime(Bit8u time) = 0; - virtual void onNewReverbLevel(Bit8u level) = 0; - virtual void onPolyStateChanged(Bit8u part_num) = 0; - virtual void onProgramChanged(Bit8u part_num, const char *sound_group_name, const char *patch_name) = 0; - -protected: - ~IReportHandler() {} -}; - -// Defines the interface for receiving MIDI messages generated by MIDI stream parser. -// Corresponds to the current version of mt32emu_midi_receiver_i interface. -class IMidiReceiver { -public: - virtual void handleShortMessage(const Bit32u message) = 0; - virtual void handleSysex(const Bit8u stream[], const Bit32u length) = 0; - virtual void handleSystemRealtimeMessage(const Bit8u realtime) = 0; - -protected: - ~IMidiReceiver() {} -}; - -// Defines all the library services. -// Corresponds to the current version of mt32emu_service_i interface. -class Service { -public: -#if MT32EMU_API_TYPE == 2 - explicit Service(mt32emu_service_i interface, mt32emu_context context = NULL) : i(interface), c(context) {} -#else - explicit Service(mt32emu_context context = NULL) : c(context) {} -#endif - ~Service() { if (c != NULL) mt32emu_free_context(c); } - - // Context-independent methods - -#if MT32EMU_API_TYPE == 2 - mt32emu_service_version getVersionID() { return i.v0->getVersionID(i); } -#endif - mt32emu_report_handler_version getSupportedReportHandlerVersionID() { return mt32emu_get_supported_report_handler_version(); } - mt32emu_midi_receiver_version getSupportedMIDIReceiverVersionID() { return mt32emu_get_supported_midi_receiver_version(); } - - Bit32u getLibraryVersionInt() { return mt32emu_get_library_version_int(); } - const char *getLibraryVersionString() { return mt32emu_get_library_version_string(); } - - Bit32u getStereoOutputSamplerate(const AnalogOutputMode analog_output_mode) { return mt32emu_get_stereo_output_samplerate(static_cast(analog_output_mode)); } - AnalogOutputMode getBestAnalogOutputMode(const double target_samplerate) { return static_cast(mt32emu_get_best_analog_output_mode(target_samplerate)); } - - // Context-dependent methods - - mt32emu_context getContext() { return c; } - void createContext(mt32emu_report_handler_i report_handler = CppInterfaceImpl::NULL_REPORT_HANDLER, void *instance_data = NULL) { freeContext(); c = mt32emu_create_context(report_handler, instance_data); } - void createContext(IReportHandler &report_handler) { createContext(CppInterfaceImpl::getReportHandlerThunk(), &report_handler); } - void freeContext() { if (c != NULL) { mt32emu_free_context(c); c = NULL; } } - mt32emu_return_code addROMData(const Bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest = NULL) { return mt32emu_add_rom_data(c, data, data_size, sha1_digest); } - mt32emu_return_code addROMFile(const char *filename) { return mt32emu_add_rom_file(c, filename); } - void getROMInfo(mt32emu_rom_info *rom_info) { mt32emu_get_rom_info(c, rom_info); } - void setPartialCount(const Bit32u partial_count) { mt32emu_set_partial_count(c, partial_count); } - void setAnalogOutputMode(const AnalogOutputMode analog_output_mode) { mt32emu_set_analog_output_mode(c, static_cast(analog_output_mode)); } - void setStereoOutputSampleRate(const double samplerate) { mt32emu_set_stereo_output_samplerate(c, samplerate); } - void setSamplerateConversionQuality(const SamplerateConversionQuality quality) { mt32emu_set_samplerate_conversion_quality(c, static_cast(quality)); } - void selectRendererType(const RendererType newRendererType) { mt32emu_select_renderer_type(c, static_cast(newRendererType)); } - RendererType getSelectedRendererType() { return static_cast(mt32emu_get_selected_renderer_type(c)); } - mt32emu_return_code openSynth() { return mt32emu_open_synth(c); } - void closeSynth() { mt32emu_close_synth(c); } - bool isOpen() { return mt32emu_is_open(c) != MT32EMU_BOOL_FALSE; } - Bit32u getActualStereoOutputSamplerate() { return mt32emu_get_actual_stereo_output_samplerate(c); } - Bit32u convertOutputToSynthTimestamp(Bit32u output_timestamp) { return mt32emu_convert_output_to_synth_timestamp(c, output_timestamp); } - Bit32u convertSynthToOutputTimestamp(Bit32u synth_timestamp) { return mt32emu_convert_synth_to_output_timestamp(c, synth_timestamp); } - void flushMIDIQueue() { mt32emu_flush_midi_queue(c); } - Bit32u setMIDIEventQueueSize(const Bit32u queue_size) { return mt32emu_set_midi_event_queue_size(c, queue_size); } - void setMIDIReceiver(mt32emu_midi_receiver_i midi_receiver, void *instance_data) { mt32emu_set_midi_receiver(c, midi_receiver, instance_data); } - void setMIDIReceiver(IMidiReceiver &midi_receiver) { setMIDIReceiver(CppInterfaceImpl::getMidiReceiverThunk(), &midi_receiver); } - - Bit32u getInternalRenderedSampleCount() { return mt32emu_get_internal_rendered_sample_count(c); } - void parseStream(const Bit8u *stream, Bit32u length) { mt32emu_parse_stream(c, stream, length); } - void parseStream_At(const Bit8u *stream, Bit32u length, Bit32u timestamp) { mt32emu_parse_stream_at(c, stream, length, timestamp); } - void playShortMessage(Bit32u message) { mt32emu_play_short_message(c, message); } - void playShortMessageAt(Bit32u message, Bit32u timestamp) { mt32emu_play_short_message_at(c, message, timestamp); } - mt32emu_return_code playMsg(Bit32u msg) { return mt32emu_play_msg(c, msg); } - mt32emu_return_code playSysex(const Bit8u *sysex, Bit32u len) { return mt32emu_play_sysex(c, sysex, len); } - mt32emu_return_code playMsgAt(Bit32u msg, Bit32u timestamp) { return mt32emu_play_msg_at(c, msg, timestamp); } - mt32emu_return_code playSysexAt(const Bit8u *sysex, Bit32u len, Bit32u timestamp) { return mt32emu_play_sysex_at(c, sysex, len, timestamp); } - - void playMsgNow(Bit32u msg) { mt32emu_play_msg_now(c, msg); } - void playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity) { mt32emu_play_msg_on_part(c, part, code, note, velocity); } - void playSysexNow(const Bit8u *sysex, Bit32u len) { mt32emu_play_sysex_now(c, sysex, len); } - void writeSysex(Bit8u channel, const Bit8u *sysex, Bit32u len) { mt32emu_write_sysex(c, channel, sysex, len); } - - void setReverbEnabled(const bool reverb_enabled) { mt32emu_set_reverb_enabled(c, reverb_enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } - bool isReverbEnabled() { return mt32emu_is_reverb_enabled(c) != MT32EMU_BOOL_FALSE; } - void setReverbOverridden(const bool reverb_overridden) { mt32emu_set_reverb_overridden(c, reverb_overridden ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } - bool isReverbOverridden() { return mt32emu_is_reverb_overridden(c) != MT32EMU_BOOL_FALSE; } - void setReverbCompatibilityMode(const bool mt32_compatible_mode) { mt32emu_set_reverb_compatibility_mode(c, mt32_compatible_mode ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } - bool isMT32ReverbCompatibilityMode() { return mt32emu_is_mt32_reverb_compatibility_mode(c) != MT32EMU_BOOL_FALSE; } - bool isDefaultReverbMT32Compatible() { return mt32emu_is_default_reverb_mt32_compatible(c) != MT32EMU_BOOL_FALSE; } - - void setDACInputMode(const DACInputMode mode) { mt32emu_set_dac_input_mode(c, static_cast(mode)); } - DACInputMode getDACInputMode() { return static_cast(mt32emu_get_dac_input_mode(c)); } - - void setMIDIDelayMode(const MIDIDelayMode mode) { mt32emu_set_midi_delay_mode(c, static_cast(mode)); } - MIDIDelayMode getMIDIDelayMode() { return static_cast(mt32emu_get_midi_delay_mode(c)); } - - void setOutputGain(float gain) { mt32emu_set_output_gain(c, gain); } - float getOutputGain() { return mt32emu_get_output_gain(c); } - void setReverbOutputGain(float gain) { mt32emu_set_reverb_output_gain(c, gain); } - float getReverbOutputGain() { return mt32emu_get_reverb_output_gain(c); } - - void setReversedStereoEnabled(const bool enabled) { mt32emu_set_reversed_stereo_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } - bool isReversedStereoEnabled() { return mt32emu_is_reversed_stereo_enabled(c) != MT32EMU_BOOL_FALSE; } - - void setNiceAmpRampEnabled(const bool enabled) { mt32emu_set_nice_amp_ramp_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } - bool isNiceAmpRampEnabled() { return mt32emu_is_nice_amp_ramp_enabled(c) != MT32EMU_BOOL_FALSE; } - - void renderBit16s(Bit16s *stream, Bit32u len) { mt32emu_render_bit16s(c, stream, len); } - void renderFloat(float *stream, Bit32u len) { mt32emu_render_float(c, stream, len); } - void renderBit16sStreams(const mt32emu_dac_output_bit16s_streams *streams, Bit32u len) { mt32emu_render_bit16s_streams(c, streams, len); } - void renderFloatStreams(const mt32emu_dac_output_float_streams *streams, Bit32u len) { mt32emu_render_float_streams(c, streams, len); } - - bool hasActivePartials() { return mt32emu_has_active_partials(c) != MT32EMU_BOOL_FALSE; } - bool isActive() { return mt32emu_is_active(c) != MT32EMU_BOOL_FALSE; } - Bit32u getPartialCount() { return mt32emu_get_partial_count(c); } - Bit32u getPartStates() { return mt32emu_get_part_states(c); } - void getPartialStates(Bit8u *partial_states) { mt32emu_get_partial_states(c, partial_states); } - Bit32u getPlayingNotes(Bit8u part_number, Bit8u *keys, Bit8u *velocities) { return mt32emu_get_playing_notes(c, part_number, keys, velocities); } - const char *getPatchName(Bit8u part_number) { return mt32emu_get_patch_name(c, part_number); } - void readMemory(Bit32u addr, Bit32u len, Bit8u *data) { mt32emu_read_memory(c, addr, len, data); } - -private: -#if MT32EMU_API_TYPE == 2 - const mt32emu_service_i i; -#endif - mt32emu_context c; - -#if MT32EMU_API_TYPE == 2 - const mt32emu_service_i_v1 *iV1() { return (getVersionID() < MT32EMU_SERVICE_VERSION_1) ? NULL : i.v1; } - const mt32emu_service_i_v2 *iV2() { return (getVersionID() < MT32EMU_SERVICE_VERSION_2) ? NULL : i.v2; } -#endif -}; - -namespace CppInterfaceImpl { - -static mt32emu_report_handler_version getReportHandlerVersionID(mt32emu_report_handler_i) { - return MT32EMU_REPORT_HANDLER_VERSION_CURRENT; -} - -static void printDebug(void *instance_data, const char *fmt, va_list list) { - static_cast(instance_data)->printDebug(fmt, list); -} - -static void onErrorControlROM(void *instance_data) { - static_cast(instance_data)->onErrorControlROM(); -} - -static void onErrorPCMROM(void *instance_data) { - static_cast(instance_data)->onErrorPCMROM(); -} - -static void showLCDMessage(void *instance_data, const char *message) { - static_cast(instance_data)->showLCDMessage(message); -} - -static void onMIDIMessagePlayed(void *instance_data) { - static_cast(instance_data)->onMIDIMessagePlayed(); -} - -static mt32emu_boolean onMIDIQueueOverflow(void *instance_data) { - return static_cast(instance_data)->onMIDIQueueOverflow() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; -} - -static void onMIDISystemRealtime(void *instance_data, mt32emu_bit8u system_realtime) { - static_cast(instance_data)->onMIDISystemRealtime(system_realtime); -} - -static void onDeviceReset(void *instance_data) { - static_cast(instance_data)->onDeviceReset(); -} - -static void onDeviceReconfig(void *instance_data) { - static_cast(instance_data)->onDeviceReconfig(); -} - -static void onNewReverbMode(void *instance_data, mt32emu_bit8u mode) { - static_cast(instance_data)->onNewReverbMode(mode); -} - -static void onNewReverbTime(void *instance_data, mt32emu_bit8u time) { - static_cast(instance_data)->onNewReverbTime(time); -} - -static void onNewReverbLevel(void *instance_data, mt32emu_bit8u level) { - static_cast(instance_data)->onNewReverbLevel(level); -} - -static void onPolyStateChanged(void *instance_data, mt32emu_bit8u part_num) { - static_cast(instance_data)->onPolyStateChanged(part_num); -} - -static void onProgramChanged(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name) { - static_cast(instance_data)->onProgramChanged(part_num, sound_group_name, patch_name); -} - -static mt32emu_report_handler_i getReportHandlerThunk() { - static const mt32emu_report_handler_i_v0 REPORT_HANDLER_V0_THUNK = { - getReportHandlerVersionID, - printDebug, - onErrorControlROM, - onErrorPCMROM, - showLCDMessage, - onMIDIMessagePlayed, - onMIDIQueueOverflow, - onMIDISystemRealtime, - onDeviceReset, - onDeviceReconfig, - onNewReverbMode, - onNewReverbTime, - onNewReverbLevel, - onPolyStateChanged, - onProgramChanged - }; - - static const mt32emu_report_handler_i REPORT_HANDLER_THUNK = { &REPORT_HANDLER_V0_THUNK }; - - return REPORT_HANDLER_THUNK; -} - -static mt32emu_midi_receiver_version getMidiReceiverVersionID(mt32emu_midi_receiver_i) { - return MT32EMU_MIDI_RECEIVER_VERSION_CURRENT; -} - -static void handleShortMessage(void *instance_data, const mt32emu_bit32u message) { - static_cast(instance_data)->handleShortMessage(message); -} - -static void handleSysex(void *instance_data, const mt32emu_bit8u stream[], const mt32emu_bit32u length) { - static_cast(instance_data)->handleSysex(stream, length); -} - -static void handleSystemRealtimeMessage(void *instance_data, const mt32emu_bit8u realtime) { - static_cast(instance_data)->handleSystemRealtimeMessage(realtime); -} - -static mt32emu_midi_receiver_i getMidiReceiverThunk() { - static const mt32emu_midi_receiver_i_v0 MIDI_RECEIVER_V0_THUNK = { - getMidiReceiverVersionID, - handleShortMessage, - handleSysex, - handleSystemRealtimeMessage - }; - - static const mt32emu_midi_receiver_i MIDI_RECEIVER_THUNK = { &MIDI_RECEIVER_V0_THUNK }; - - return MIDI_RECEIVER_THUNK; -} - -} // namespace CppInterfaceImpl - -} // namespace MT32Emu - -#if MT32EMU_API_TYPE == 2 - -#undef mt32emu_get_supported_report_handler_version -#undef mt32emu_get_supported_midi_receiver_version -#undef mt32emu_get_library_version_int -#undef mt32emu_get_library_version_string -#undef mt32emu_get_stereo_output_samplerate -#undef mt32emu_get_best_analog_output_mode -#undef mt32emu_create_context -#undef mt32emu_free_context -#undef mt32emu_add_rom_data -#undef mt32emu_add_rom_file -#undef mt32emu_get_rom_info -#undef mt32emu_set_partial_count -#undef mt32emu_set_analog_output_mode -#undef mt32emu_set_stereo_output_samplerate -#undef mt32emu_set_samplerate_conversion_quality -#undef mt32emu_select_renderer_type -#undef mt32emu_get_selected_renderer_type -#undef mt32emu_open_synth -#undef mt32emu_close_synth -#undef mt32emu_is_open -#undef mt32emu_get_actual_stereo_output_samplerate -#undef mt32emu_convert_output_to_synth_timestamp -#undef mt32emu_convert_synth_to_output_timestamp -#undef mt32emu_flush_midi_queue -#undef mt32emu_set_midi_event_queue_size -#undef mt32emu_set_midi_receiver -#undef mt32emu_get_internal_rendered_sample_count -#undef mt32emu_parse_stream -#undef mt32emu_parse_stream_at -#undef mt32emu_play_short_message -#undef mt32emu_play_short_message_at -#undef mt32emu_play_msg -#undef mt32emu_play_sysex -#undef mt32emu_play_msg_at -#undef mt32emu_play_sysex_at -#undef mt32emu_play_msg_now -#undef mt32emu_play_msg_on_part -#undef mt32emu_play_sysex_now -#undef mt32emu_write_sysex -#undef mt32emu_set_reverb_enabled -#undef mt32emu_is_reverb_enabled -#undef mt32emu_set_reverb_overridden -#undef mt32emu_is_reverb_overridden -#undef mt32emu_set_reverb_compatibility_mode -#undef mt32emu_is_mt32_reverb_compatibility_mode -#undef mt32emu_is_default_reverb_mt32_compatible -#undef mt32emu_set_dac_input_mode -#undef mt32emu_get_dac_input_mode -#undef mt32emu_set_midi_delay_mode -#undef mt32emu_get_midi_delay_mode -#undef mt32emu_set_output_gain -#undef mt32emu_get_output_gain -#undef mt32emu_set_reverb_output_gain -#undef mt32emu_get_reverb_output_gain -#undef mt32emu_set_reversed_stereo_enabled -#undef mt32emu_is_reversed_stereo_enabled -#undef mt32emu_set_nice_amp_ramp_enabled -#undef mt32emu_is_nice_amp_ramp_enabled -#undef mt32emu_render_bit16s -#undef mt32emu_render_float -#undef mt32emu_render_bit16s_streams -#undef mt32emu_render_float_streams -#undef mt32emu_has_active_partials -#undef mt32emu_is_active -#undef mt32emu_get_partial_count -#undef mt32emu_get_part_states -#undef mt32emu_get_partial_states -#undef mt32emu_get_playing_notes -#undef mt32emu_get_patch_name -#undef mt32emu_read_memory - -#endif // #if MT32EMU_API_TYPE == 2 - -#endif /* #ifndef MT32EMU_CPP_INTERFACE_H */ diff --git a/src - Cópia/sound/munt/config.h b/src - Cópia/sound/munt/config.h deleted file mode 100644 index 5f5b6c9fb..000000000 --- a/src - Cópia/sound/munt/config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_CONFIG_H -#define MT32EMU_CONFIG_H - -#define MT32EMU_VERSION "2.2.0" -#define MT32EMU_VERSION_MAJOR 2 -#define MT32EMU_VERSION_MINOR 2 -#define MT32EMU_VERSION_PATCH 0 - -/* Library Exports Configuration - * - * This reflects the API types actually provided by the library build. - * 0: The full-featured C++ API is only available in this build. The client application may ONLY use MT32EMU_API_TYPE 0. - * 1: The C-compatible API is only available. The library is built as a shared object, only C functions are exported, - * and thus the client application may NOT use MT32EMU_API_TYPE 0. - * 2: The C-compatible API is only available. The library is built as a shared object, only the factory function - * is exported, and thus the client application may ONLY use MT32EMU_API_TYPE 2. - * 3: All the available API types are provided by the library build. - */ -#define MT32EMU_EXPORTS_TYPE 3 - -#define MT32EMU_API_TYPE 0 - -#endif diff --git a/src - Cópia/sound/munt/globals.h b/src - Cópia/sound/munt/globals.h deleted file mode 100644 index 2d984c82b..000000000 --- a/src - Cópia/sound/munt/globals.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_GLOBALS_H -#define MT32EMU_GLOBALS_H - -#include "config.h" - -/* Support for compiling shared library. */ -#ifdef MT32EMU_SHARED -#if defined _WIN32 || defined __CYGWIN__ -#ifdef _MSC_VER -#ifdef mt32emu_EXPORTS -#define MT32EMU_EXPORT_ATTRIBUTE _declspec(dllexport) -#else /* #ifdef mt32emu_EXPORTS */ -#define MT32EMU_EXPORT_ATTRIBUTE _declspec(dllimport) -#endif /* #ifdef mt32emu_EXPORTS */ -#else /* #ifdef _MSC_VER */ -#ifdef mt32emu_EXPORTS -#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((dllexport)) -#else /* #ifdef mt32emu_EXPORTS */ -#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((dllimport)) -#endif /* #ifdef mt32emu_EXPORTS */ -#endif /* #ifdef _MSC_VER */ -#else /* #if defined _WIN32 || defined __CYGWIN__ */ -#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((visibility("default"))) -#endif /* #if defined _WIN32 || defined __CYGWIN__ */ -#else /* #ifdef MT32EMU_SHARED */ -#define MT32EMU_EXPORT_ATTRIBUTE -#endif /* #ifdef MT32EMU_SHARED */ - -#if MT32EMU_EXPORTS_TYPE == 1 || MT32EMU_EXPORTS_TYPE == 2 -#define MT32EMU_EXPORT -#else -#define MT32EMU_EXPORT MT32EMU_EXPORT_ATTRIBUTE -#endif - -/* Useful constants */ - -/* Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent. - * In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator, - * except the emulation of analogue path. - * The output from the synth is supposed to be resampled externally in order to convert to the desired sample rate. - */ -#define MT32EMU_SAMPLE_RATE 32000 - -/* The default value for the maximum number of partials playing simultaneously. */ -#define MT32EMU_DEFAULT_MAX_PARTIALS 32 - -/* The higher this number, the more memory will be used, but the more samples can be processed in one run - - * various parts of sample generation can be processed more efficiently in a single run. - * A run's maximum length is that given to Synth::render(), so giving a value here higher than render() is ever - * called with will give no gain (but simply waste the memory). - * Note that this value does *not* in any way impose limitations on the length given to render(), and has no effect - * on the generated audio. - * This value must be >= 1. - */ -#define MT32EMU_MAX_SAMPLES_PER_RUN 4096 - -/* The default size of the internal MIDI event queue. - * It holds the incoming MIDI events before the rendering engine actually processes them. - * The main goal is to fairly emulate the real hardware behaviour which obviously - * uses an internal MIDI event queue to gather incoming data as well as the delays - * introduced by transferring data via the MIDI interface. - * This also facilitates building of an external rendering loop - * as the queue stores timestamped MIDI events. - */ -#define MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE 1024 - -/* Maximum allowed size of MIDI parser input stream buffer. - * Should suffice for any reasonable bulk dump SysEx, as the h/w units have only 32K of RAM onboard. - */ -#define MT32EMU_MAX_STREAM_BUFFER_SIZE 32768 - -/* This should correspond to the MIDI buffer size used in real h/w devices. - * CM-32L control ROM is using 1000 bytes, and MT-32 GEN0 is using only 240 bytes (semi-confirmed by now). - */ -#define MT32EMU_SYSEX_BUFFER_SIZE 1000 - -#if defined(__cplusplus) && MT32EMU_API_TYPE != 1 - -namespace MT32Emu -{ -const unsigned int SAMPLE_RATE = MT32EMU_SAMPLE_RATE; -#undef MT32EMU_SAMPLE_RATE - -const unsigned int DEFAULT_MAX_PARTIALS = MT32EMU_DEFAULT_MAX_PARTIALS; -#undef MT32EMU_DEFAULT_MAX_PARTIALS - -const unsigned int MAX_SAMPLES_PER_RUN = MT32EMU_MAX_SAMPLES_PER_RUN; -#undef MT32EMU_MAX_SAMPLES_PER_RUN - -const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE; -#undef MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE - -const unsigned int MAX_STREAM_BUFFER_SIZE = MT32EMU_MAX_STREAM_BUFFER_SIZE; -#undef MT32EMU_MAX_STREAM_BUFFER_SIZE - -const unsigned int SYSEX_BUFFER_SIZE = MT32EMU_SYSEX_BUFFER_SIZE; -#undef MT32EMU_SYSEX_BUFFER_SIZE -} - -#endif /* #if defined(__cplusplus) && MT32EMU_API_TYPE != 1 */ - -#endif /* #ifndef MT32EMU_GLOBALS_H */ diff --git a/src - Cópia/sound/munt/internals.h b/src - Cópia/sound/munt/internals.h deleted file mode 100644 index 0bae8d9f7..000000000 --- a/src - Cópia/sound/munt/internals.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_INTERNALS_H -#define MT32EMU_INTERNALS_H - -#include "Types.h" - -// Debugging - -// 0: Standard debug output is not stamped with the rendered sample count -// 1: Standard debug output is stamped with the rendered sample count -// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run. -// This is important to bear in mind for debug output that occurs during a run. -#ifndef MT32EMU_DEBUG_SAMPLESTAMPS -#define MT32EMU_DEBUG_SAMPLESTAMPS 0 -#endif - -// 0: No debug output for initialisation progress -// 1: Debug output for initialisation progress -#ifndef MT32EMU_MONITOR_INIT -#define MT32EMU_MONITOR_INIT 0 -#endif - -// 0: No debug output for MIDI events -// 1: Debug output for weird MIDI events -#ifndef MT32EMU_MONITOR_MIDI -#define MT32EMU_MONITOR_MIDI 0 -#endif - -// 0: No debug output for note on/off -// 1: Basic debug output for note on/off -// 2: Comprehensive debug output for note on/off -#ifndef MT32EMU_MONITOR_INSTRUMENTS -#define MT32EMU_MONITOR_INSTRUMENTS 0 -#endif - -// 0: No debug output for partial allocations -// 1: Show partial stats when an allocation fails -// 2: Show partial stats with every new poly -// 3: Show individual partial allocations/deactivations -#ifndef MT32EMU_MONITOR_PARTIALS -#define MT32EMU_MONITOR_PARTIALS 0 -#endif - -// 0: No debug output for sysex -// 1: Basic debug output for sysex -#ifndef MT32EMU_MONITOR_SYSEX -#define MT32EMU_MONITOR_SYSEX 0 -#endif - -// 0: No debug output for sysex writes to the timbre areas -// 1: Debug output with the name and location of newly-written timbres -// 2: Complete dump of timbre parameters for newly-written timbres -#ifndef MT32EMU_MONITOR_TIMBRES -#define MT32EMU_MONITOR_TIMBRES 0 -#endif - -// 0: No TVA/TVF-related debug output. -// 1: Shows changes to TVA/TVF target, increment and phase. -#ifndef MT32EMU_MONITOR_TVA -#define MT32EMU_MONITOR_TVA 0 -#endif -#ifndef MT32EMU_MONITOR_TVF -#define MT32EMU_MONITOR_TVF 0 -#endif - -// Configuration - -// If non-zero, deletes reverb buffers that are not in use to save memory. -// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path. -#ifndef MT32EMU_REDUCE_REVERB_MEMORY -#define MT32EMU_REDUCE_REVERB_MEMORY 1 -#endif - -// 0: Maximum speed at the cost of a bit lower emulation accuracy. -// 1: Maximum achievable emulation accuracy. -#ifndef MT32EMU_BOSS_REVERB_PRECISE_MODE -#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0 -#endif - -namespace MT32Emu { - -typedef Bit16s IntSample; -typedef Bit32s IntSampleEx; -typedef float FloatSample; - -enum PolyState { - POLY_Playing, - POLY_Held, // This marks keys that have been released on the keyboard, but are being held by the pedal - POLY_Releasing, - POLY_Inactive -}; - -enum ReverbMode { - REVERB_MODE_ROOM, - REVERB_MODE_HALL, - REVERB_MODE_PLATE, - REVERB_MODE_TAP_DELAY -}; - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_INTERNALS_H diff --git a/src - Cópia/sound/munt/mmath.h b/src - Cópia/sound/munt/mmath.h deleted file mode 100644 index 9a9e642ba..000000000 --- a/src - Cópia/sound/munt/mmath.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_MMATH_H -#define MT32EMU_MMATH_H - -#include - -namespace MT32Emu { - -// Mathematical constants -const double DOUBLE_PI = 3.141592653589793; -const double DOUBLE_LN_10 = 2.302585092994046; -const float FLOAT_PI = 3.1415927f; -const float FLOAT_2PI = 6.2831853f; -const float FLOAT_LN_2 = 0.6931472f; -const float FLOAT_LN_10 = 2.3025851f; - -static inline float POWF(float x, float y) { - return pow(x, y); -} - -static inline float EXPF(float x) { - return exp(x); -} - -static inline float EXP2F(float x) { -#ifdef __APPLE__ - // on OSX exp2f() is 1.59 times faster than "exp() and the multiplication with FLOAT_LN_2" - return exp2f(x); -#else - return exp(FLOAT_LN_2 * x); -#endif -} - -static inline float EXP10F(float x) { - return exp(FLOAT_LN_10 * x); -} - -static inline float LOGF(float x) { - return log(x); -} - -static inline float LOG2F(float x) { - return log(x) / FLOAT_LN_2; -} - -static inline float LOG10F(float x) { - return log10(x); -} - -} // namespace MT32Emu - -#endif // #ifndef MT32EMU_MMATH_H diff --git a/src - Cópia/sound/munt/mt32emu.h b/src - Cópia/sound/munt/mt32emu.h deleted file mode 100644 index 6b93121be..000000000 --- a/src - Cópia/sound/munt/mt32emu.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_MT32EMU_H -#define MT32EMU_MT32EMU_H - -#include "config.h" - -/* API Configuration */ - -/* 0: Use full-featured C++ API. Well suitable when the library is to be linked statically. - * When the library is shared, ABI compatibility may be an issue. Therefore, it should - * only be used within a project comprising of several modules to share the library code. - * 1: Use C-compatible API. Make the library looks as a regular C library with well-defined ABI. - * This is also crucial when the library is to be linked with modules in a different - * language, either statically or dynamically. - * 2: Use plugin-like API via C-interface wrapped in a C++ class. This is mainly intended - * for a shared library being dynamically loaded in run-time. To get access to all the library - * services, a client application only needs to bind with a single factory function. - * 3: Use optimised C++ API compatible with the plugin API (type 2). The facade class also wraps - * the C functions but they are invoked directly. This enables the compiler to generate better - * code for the library when linked statically yet being consistent with the plugin-like API. - */ - -#ifdef MT32EMU_API_TYPE -#if MT32EMU_API_TYPE == 0 && (MT32EMU_EXPORTS_TYPE == 1 || MT32EMU_EXPORTS_TYPE == 2) -#error Incompatible setting MT32EMU_API_TYPE=0 -#elif MT32EMU_API_TYPE == 1 && (MT32EMU_EXPORTS_TYPE == 0 || MT32EMU_EXPORTS_TYPE == 2) -#error Incompatible setting MT32EMU_API_TYPE=1 -#elif MT32EMU_API_TYPE == 2 && (MT32EMU_EXPORTS_TYPE == 0) -#error Incompatible setting MT32EMU_API_TYPE=2 -#elif MT32EMU_API_TYPE == 3 && (MT32EMU_EXPORTS_TYPE == 0 || MT32EMU_EXPORTS_TYPE == 2) -#error Incompatible setting MT32EMU_API_TYPE=3 -#endif -#else /* #ifdef MT32EMU_API_TYPE */ -#if 0 < MT32EMU_EXPORTS_TYPE && MT32EMU_EXPORTS_TYPE < 3 -#define MT32EMU_API_TYPE MT32EMU_EXPORTS_TYPE -#else -#define MT32EMU_API_TYPE 0 -#endif -#endif /* #ifdef MT32EMU_API_TYPE */ - -/* MT32EMU_SHARED should be defined when building shared library, especially for Windows platforms. */ -/* -#define MT32EMU_SHARED -*/ - -#include "globals.h" - -#if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 - -#include "c_interface/c_interface.h" - -#elif MT32EMU_API_TYPE == 2 || MT32EMU_API_TYPE == 3 - -#include "c_interface/cpp_interface.h" - -#else /* #if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 */ - -#include "Types.h" -#include "File.h" -#include "FileStream.h" -#include "ROMInfo.h" -#include "Synth.h" -#include "MidiStreamParser.h" -#include "SampleRateConverter.h" - -#endif /* #if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 */ - -#endif /* #ifndef MT32EMU_MT32EMU_H */ diff --git a/src - Cópia/sound/munt/sha1/sha1.cpp b/src - Cópia/sound/munt/sha1/sha1.cpp deleted file mode 100644 index 9b91cd9f2..000000000 --- a/src - Cópia/sound/munt/sha1/sha1.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - Copyright (c) 2011, Micael Hildenborg - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Micael Hildenborg nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - Contributors: - Gustav - Several members in the gamedev.se forum. - Gregory Petrosyan - */ - -#include "sha1.h" - -namespace sha1 -{ - namespace // local - { - // Rotate an integer value to left. - inline unsigned int rol(const unsigned int value, - const unsigned int steps) - { - return ((value << steps) | (value >> (32 - steps))); - } - - // Sets the first 16 integers in the buffert to zero. - // Used for clearing the W buffert. - inline void clearWBuffert(unsigned int* buffert) - { - for (int pos = 16; --pos >= 0;) - { - buffert[pos] = 0; - } - } - - void innerHash(unsigned int* result, unsigned int* w) - { - unsigned int a = result[0]; - unsigned int b = result[1]; - unsigned int c = result[2]; - unsigned int d = result[3]; - unsigned int e = result[4]; - - int round = 0; - - #define sha1macro(func,val) \ - { \ - const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \ - e = d; \ - d = c; \ - c = rol(b, 30); \ - b = a; \ - a = t; \ - } - - while (round < 16) - { - sha1macro((b & c) | (~b & d), 0x5a827999) - ++round; - } - while (round < 20) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro((b & c) | (~b & d), 0x5a827999) - ++round; - } - while (round < 40) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro(b ^ c ^ d, 0x6ed9eba1) - ++round; - } - while (round < 60) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc) - ++round; - } - while (round < 80) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro(b ^ c ^ d, 0xca62c1d6) - ++round; - } - - #undef sha1macro - - result[0] += a; - result[1] += b; - result[2] += c; - result[3] += d; - result[4] += e; - } - } // namespace - - void calc(const void* src, const int bytelength, unsigned char* hash) - { - // Init the result array. - unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; - - // Cast the void src pointer to be the byte array we can work with. - const unsigned char* sarray = static_cast(src); - - // The reusable round buffer - unsigned int w[80]; - - // Loop through all complete 64byte blocks. - const int endOfFullBlocks = bytelength - 64; - int endCurrentBlock; - int currentBlock = 0; - - while (currentBlock <= endOfFullBlocks) - { - endCurrentBlock = currentBlock + 64; - - // Init the round buffer with the 64 byte block data. - for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4) - { - // This line will swap endian on big endian and keep endian on little endian. - w[roundPos++] = static_cast(sarray[currentBlock + 3]) - | (static_cast(sarray[currentBlock + 2]) << 8) - | (static_cast(sarray[currentBlock + 1]) << 16) - | (static_cast(sarray[currentBlock]) << 24); - } - innerHash(result, w); - } - - // Handle the last and not full 64 byte block if existing. - endCurrentBlock = bytelength - currentBlock; - clearWBuffert(w); - int lastBlockBytes = 0; - for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) - { - w[lastBlockBytes >> 2] |= static_cast(sarray[lastBlockBytes + currentBlock]) << ((3 - (lastBlockBytes & 3)) << 3); - } - w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3); - if (endCurrentBlock >= 56) - { - innerHash(result, w); - clearWBuffert(w); - } - w[15] = bytelength << 3; - innerHash(result, w); - - // Store hash in result pointer, and make sure we get in in the correct order on both endian models. - for (int hashByte = 20; --hashByte >= 0;) - { - hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff; - } - } - - void toHexString(const unsigned char* hash, char* hexstring) - { - const char hexDigits[] = { "0123456789abcdef" }; - - for (int hashByte = 20; --hashByte >= 0;) - { - hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf]; - hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf]; - } - hexstring[40] = 0; - } -} // namespace sha1 diff --git a/src - Cópia/sound/munt/sha1/sha1.h b/src - Cópia/sound/munt/sha1/sha1.h deleted file mode 100644 index 96d8ce4da..000000000 --- a/src - Cópia/sound/munt/sha1/sha1.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2011, Micael Hildenborg - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Micael Hildenborg nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SHA1_DEFINED -#define SHA1_DEFINED - -namespace sha1 -{ - - /** - @param src points to any kind of data to be hashed. - @param bytelength the number of bytes to hash from the src pointer. - @param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in. - */ - void calc(const void* src, const int bytelength, unsigned char* hash); - - /** - @param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function. - @param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string. - */ - void toHexString(const unsigned char* hash, char* hexstring); - -} // namespace sha1 - -#endif // SHA1_DEFINED diff --git a/src - Cópia/sound/munt/srchelper/InternalResampler.cpp b/src - Cópia/sound/munt/srchelper/InternalResampler.cpp deleted file mode 100644 index 782d39bbe..000000000 --- a/src - Cópia/sound/munt/srchelper/InternalResampler.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "InternalResampler.h" - -#include -#include - -#include "../Synth.h" - -using namespace SRCTools; - -namespace MT32Emu { - -class SynthWrapper : public FloatSampleProvider { - Synth &synth; - -public: - SynthWrapper(Synth &useSynth) : synth(useSynth) - {} - - void getOutputSamples(FloatSample *outBuffer, unsigned int size) { - synth.render(outBuffer, size); - } -}; - -static FloatSampleProvider &createModel(Synth &synth, SRCTools::FloatSampleProvider &synthSource, double targetSampleRate, SamplerateConversionQuality quality) { - static const double MAX_AUDIBLE_FREQUENCY = 20000.0; - - const double sourceSampleRate = synth.getStereoOutputSampleRate(); - if (quality != SamplerateConversionQuality_FASTEST) { - const bool oversampledMode = synth.getStereoOutputSampleRate() == Synth::getStereoOutputSampleRate(AnalogOutputMode_OVERSAMPLED); - // Oversampled input allows to bypass IIR interpolation stage and, in some cases, IIR decimation stage - if (oversampledMode && (0.5 * sourceSampleRate) <= targetSampleRate) { - // NOTE: In the oversampled mode, the transition band starts at 20kHz and ends at 28kHz - double passband = MAX_AUDIBLE_FREQUENCY; - double stopband = 0.5 * sourceSampleRate + MAX_AUDIBLE_FREQUENCY; - ResamplerStage &resamplerStage = *SincResampler::createSincResampler(sourceSampleRate, targetSampleRate, passband, stopband, ResamplerModel::DEFAULT_DB_SNR, ResamplerModel::DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR); - return ResamplerModel::createResamplerModel(synthSource, resamplerStage); - } - } - return ResamplerModel::createResamplerModel(synthSource, sourceSampleRate, targetSampleRate, static_cast(quality)); -} - -} // namespace MT32Emu - -using namespace MT32Emu; - -InternalResampler::InternalResampler(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality) : - synthSource(*new SynthWrapper(synth)), - model(createModel(synth, synthSource, targetSampleRate, quality)) -{} - -InternalResampler::~InternalResampler() { - ResamplerModel::freeResamplerModel(model, synthSource); - delete &synthSource; -} - -void InternalResampler::getOutputSamples(float *buffer, unsigned int length) { - model.getOutputSamples(buffer, length); -} diff --git a/src - Cópia/sound/munt/srchelper/InternalResampler.h b/src - Cópia/sound/munt/srchelper/InternalResampler.h deleted file mode 100644 index 87f8ff25d..000000000 --- a/src - Cópia/sound/munt/srchelper/InternalResampler.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_INTERNAL_RESAMPLER_H -#define MT32EMU_INTERNAL_RESAMPLER_H - -#include "../Enumerations.h" - -#include "FloatSampleProvider.h" - -namespace MT32Emu { - -class Synth; - -class InternalResampler { -public: - InternalResampler(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); - ~InternalResampler(); - - void getOutputSamples(float *buffer, unsigned int length); - -private: - SRCTools::FloatSampleProvider &synthSource; - SRCTools::FloatSampleProvider &model; -}; - -} // namespace MT32Emu - -#endif // MT32EMU_INTERNAL_RESAMPLER_H diff --git a/src - Cópia/sound/munt/srchelper/SamplerateAdapter.cpp b/src - Cópia/sound/munt/srchelper/SamplerateAdapter.cpp deleted file mode 100644 index 715d29872..000000000 --- a/src - Cópia/sound/munt/srchelper/SamplerateAdapter.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "SamplerateAdapter.h" - -#include "../Synth.h" - -using namespace MT32Emu; - -static const unsigned int CHANNEL_COUNT = 2; - -long SamplerateAdapter::getInputSamples(void *cb_data, float **data) { - SamplerateAdapter *instance = static_cast(cb_data); - unsigned int length = instance->inBufferSize < 1 ? 1 : (MAX_SAMPLES_PER_RUN < instance->inBufferSize ? MAX_SAMPLES_PER_RUN : instance->inBufferSize); - instance->synth.render(instance->inBuffer, length); - *data = instance->inBuffer; - instance->inBufferSize -= length; - return length; -} - -SamplerateAdapter::SamplerateAdapter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality quality) : - synth(useSynth), - inBuffer(new float[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]), - inBufferSize(MAX_SAMPLES_PER_RUN), - inputToOutputRatio(useSynth.getStereoOutputSampleRate() / targetSampleRate), - outputToInputRatio(targetSampleRate / useSynth.getStereoOutputSampleRate()) -{ - int error; - int conversionType; - switch (quality) { - case SamplerateConversionQuality_FASTEST: - conversionType = SRC_LINEAR; - break; - case SamplerateConversionQuality_FAST: - conversionType = SRC_SINC_FASTEST; - break; - case SamplerateConversionQuality_BEST: - conversionType = SRC_SINC_BEST_QUALITY; - break; - case SamplerateConversionQuality_GOOD: - default: - conversionType = SRC_SINC_MEDIUM_QUALITY; - break; - }; - resampler = src_callback_new(getInputSamples, conversionType, CHANNEL_COUNT, &error, this); - if (error != 0) { - synth.printDebug("SamplerateAdapter: Creation of Samplerate instance failed: %s\n", src_strerror(error)); - src_delete(resampler); - resampler = NULL; - } -} - -SamplerateAdapter::~SamplerateAdapter() { - delete[] inBuffer; - src_delete(resampler); -} - -void SamplerateAdapter::getOutputSamples(float *buffer, unsigned int length) { - if (resampler == NULL) { - Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); - return; - } - while (length > 0) { - inBufferSize = static_cast(length * inputToOutputRatio + 0.5); - long gotFrames = src_callback_read(resampler, outputToInputRatio, long(length), buffer); - int error = src_error(resampler); - if (error != 0) { - synth.printDebug("SamplerateAdapter: Samplerate error during processing: %s > resetting\n", src_strerror(error)); - error = src_reset(resampler); - if (error != 0) { - synth.printDebug("SamplerateAdapter: Samplerate failed to reset: %s\n", src_strerror(error)); - src_delete(resampler); - resampler = NULL; - Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); - synth.printDebug("SamplerateAdapter: Samplerate disabled\n"); - return; - } - continue; - } - if (gotFrames <= 0) { - synth.printDebug("SamplerateAdapter: got %li frames from Samplerate, weird\n", gotFrames); - } - buffer += CHANNEL_COUNT * gotFrames; - length -= gotFrames; - } -} diff --git a/src - Cópia/sound/munt/srchelper/SamplerateAdapter.h b/src - Cópia/sound/munt/srchelper/SamplerateAdapter.h deleted file mode 100644 index 0991fd771..000000000 --- a/src - Cópia/sound/munt/srchelper/SamplerateAdapter.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_SAMPLERATE_ADAPTER_H -#define MT32EMU_SAMPLERATE_ADAPTER_H - -#include - -#include "../Enumerations.h" - -namespace MT32Emu { - -class Synth; - -class SamplerateAdapter { -public: - SamplerateAdapter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); - ~SamplerateAdapter(); - - void getOutputSamples(float *outBuffer, unsigned int length); - -private: - Synth &synth; - float * const inBuffer; - unsigned int inBufferSize; - const double inputToOutputRatio; - const double outputToInputRatio; - SRC_STATE *resampler; - - static long getInputSamples(void *cb_data, float **data); -}; - -} // namespace MT32Emu - -#endif // MT32EMU_SAMPLERATE_ADAPTER_H diff --git a/src - Cópia/sound/munt/srchelper/SoxrAdapter.cpp b/src - Cópia/sound/munt/srchelper/SoxrAdapter.cpp deleted file mode 100644 index 5e8dca97d..000000000 --- a/src - Cópia/sound/munt/srchelper/SoxrAdapter.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "SoxrAdapter.h" - -#include "../Synth.h" - -using namespace MT32Emu; - -static const unsigned int CHANNEL_COUNT = 2; - -size_t SoxrAdapter::getInputSamples(void *input_fn_state, soxr_in_t *data, size_t requested_len) { - unsigned int length = requested_len < 1 ? 1 : (MAX_SAMPLES_PER_RUN < requested_len ? MAX_SAMPLES_PER_RUN : static_cast(requested_len)); - SoxrAdapter *instance = static_cast(input_fn_state); - instance->synth.render(instance->inBuffer, length); - *data = instance->inBuffer; - return length; -} - -SoxrAdapter::SoxrAdapter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality quality) : - synth(useSynth), - inBuffer(new float[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]) -{ - soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I); - unsigned long qualityRecipe; - switch (quality) { - case SamplerateConversionQuality_FASTEST: - qualityRecipe = SOXR_QQ; - break; - case SamplerateConversionQuality_FAST: - qualityRecipe = SOXR_LQ; - break; - case SamplerateConversionQuality_GOOD: - qualityRecipe = SOXR_MQ; - break; - case SamplerateConversionQuality_BEST: - default: - qualityRecipe = SOXR_16_BITQ; - break; - }; - soxr_quality_spec_t qSpec = soxr_quality_spec(qualityRecipe, 0); - soxr_runtime_spec_t rtSpec = soxr_runtime_spec(1); - soxr_error_t error; - resampler = soxr_create(synth.getStereoOutputSampleRate(), targetSampleRate, CHANNEL_COUNT, &error, &ioSpec, &qSpec, &rtSpec); - if (error != NULL) { - synth.printDebug("SoxrAdapter: Creation of SOXR instance failed: %s\n", soxr_strerror(error)); - soxr_delete(resampler); - resampler = NULL; - return; - } - error = soxr_set_input_fn(resampler, getInputSamples, this, MAX_SAMPLES_PER_RUN); - if (error != NULL) { - synth.printDebug("SoxrAdapter: Installing sample feed for SOXR failed: %s\n", soxr_strerror(error)); - soxr_delete(resampler); - resampler = NULL; - } -} - -SoxrAdapter::~SoxrAdapter() { - delete[] inBuffer; - if (resampler != NULL) { - soxr_delete(resampler); - } -} - -void SoxrAdapter::getOutputSamples(float *buffer, unsigned int length) { - if (resampler == NULL) { - Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); - return; - } - while (length > 0) { - size_t gotFrames = soxr_output(resampler, buffer, size_t(length)); - soxr_error_t error = soxr_error(resampler); - if (error != NULL) { - synth.printDebug("SoxrAdapter: SOXR error during processing: %s > resetting\n", soxr_strerror(error)); - error = soxr_clear(resampler); - if (error != NULL) { - synth.printDebug("SoxrAdapter: SOXR failed to reset: %s\n", soxr_strerror(error)); - soxr_delete(resampler); - resampler = NULL; - Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); - synth.printDebug("SoxrAdapter: SOXR disabled\n"); - return; - } - continue; - } - if (gotFrames == 0) { - synth.printDebug("SoxrAdapter: got 0 frames from SOXR, weird\n"); - } - buffer += CHANNEL_COUNT * gotFrames; - length -= static_cast(gotFrames); - } -} diff --git a/src - Cópia/sound/munt/srchelper/SoxrAdapter.h b/src - Cópia/sound/munt/srchelper/SoxrAdapter.h deleted file mode 100644 index b97ca4da5..000000000 --- a/src - Cópia/sound/munt/srchelper/SoxrAdapter.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef MT32EMU_SOXR_ADAPTER_H -#define MT32EMU_SOXR_ADAPTER_H - -#include - -#include "../Enumerations.h" - -namespace MT32Emu { - -class Synth; - -class SoxrAdapter { -public: - SoxrAdapter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); - ~SoxrAdapter(); - - void getOutputSamples(float *buffer, unsigned int length); - -private: - Synth &synth; - float * const inBuffer; - soxr_t resampler; - - static size_t getInputSamples(void *input_fn_state, soxr_in_t *data, size_t requested_len); -}; - -} // namespace MT32Emu - -#endif // MT32EMU_SOXR_ADAPTER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/FIRResampler.h b/src - Cópia/sound/munt/srchelper/srctools/include/FIRResampler.h deleted file mode 100644 index 7c09bf8de..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/FIRResampler.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_FIR_RESAMPLER_H -#define SRCTOOLS_FIR_RESAMPLER_H - -#include "ResamplerStage.h" - -namespace SRCTools { - -typedef FloatSample FIRCoefficient; - -static const unsigned int FIR_INTERPOLATOR_CHANNEL_COUNT = 2; - -class FIRResampler : public ResamplerStage { -public: - FIRResampler(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength); - ~FIRResampler(); - - void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); - unsigned int estimateInLength(const unsigned int outLength) const; - -private: - const struct Constants { - // Filter coefficients - const FIRCoefficient *taps; - // Indicates whether to interpolate filter taps - bool usePhaseInterpolation; - // Size of array of filter coefficients - unsigned int numberOfTaps; - // Upsampling factor - unsigned int numberOfPhases; - // Downsampling factor - double phaseIncrement; - // Index of last delay line element, generally greater than numberOfTaps to form a proper binary mask - unsigned int delayLineMask; - // Delay line - FloatSample(*ringBuffer)[FIR_INTERPOLATOR_CHANNEL_COUNT]; - - Constants(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength); - } constants; - // Index of current sample in delay line - unsigned int ringBufferPosition; - // Current phase - double phase; - - bool needNextInSample() const; - void addInSamples(const FloatSample *&inSamples); - void getOutSamplesStereo(FloatSample *&outSamples); -}; // class FIRResampler - -} // namespace SRCTools - -#endif // SRCTOOLS_FIR_RESAMPLER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/FloatSampleProvider.h b/src - Cópia/sound/munt/srchelper/srctools/include/FloatSampleProvider.h deleted file mode 100644 index 9820769f7..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/FloatSampleProvider.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H -#define SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H - -namespace SRCTools { - -typedef float FloatSample; - -/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */ -class FloatSampleProvider { -public: - virtual ~FloatSampleProvider() {} - - virtual void getOutputSamples(FloatSample *outBuffer, unsigned int size) = 0; -}; - -} // namespace SRCTools - -#endif // SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/IIR2xResampler.h b/src - Cópia/sound/munt/srchelper/srctools/include/IIR2xResampler.h deleted file mode 100644 index 0bfe1c4c8..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/IIR2xResampler.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_IIR_2X_RESAMPLER_H -#define SRCTOOLS_IIR_2X_RESAMPLER_H - -#include "ResamplerStage.h" - -namespace SRCTools { - -static const unsigned int IIR_RESAMPER_CHANNEL_COUNT = 2; -static const unsigned int IIR_SECTION_ORDER = 2; - -typedef FloatSample IIRCoefficient; -typedef FloatSample BufferedSample; - -typedef BufferedSample SectionBuffer[IIR_SECTION_ORDER]; - -// Non-trivial coefficients of a 2nd-order section of a parallel bank -// (zero-order numerator coefficient is always zero, zero-order denominator coefficient is always unity) -struct IIRSection { - IIRCoefficient num1; - IIRCoefficient num2; - IIRCoefficient den1; - IIRCoefficient den2; -}; - -class IIRResampler : public ResamplerStage { -public: - enum Quality { - // Used when providing custom IIR filter coefficients. - CUSTOM, - // Use fast elliptic filter with symmetric ripple: N=8, Ap=As=-99 dB, fp=0.125, fs = 0.25 (in terms of sample rate) - FAST, - // Use average elliptic filter with symmetric ripple: N=12, Ap=As=-106 dB, fp=0.193, fs = 0.25 (in terms of sample rate) - GOOD, - // Use sharp elliptic filter with symmetric ripple: N=18, Ap=As=-106 dB, fp=0.238, fs = 0.25 (in terms of sample rate) - BEST - }; - - // Returns the retained fraction of the passband for the given standard quality value - static double getPassbandFractionForQuality(Quality quality); - -protected: - explicit IIRResampler(const Quality quality); - explicit IIRResampler(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); - ~IIRResampler(); - - const struct Constants { - // Coefficient of the 0-order FIR part - IIRCoefficient fir; - // 2nd-order sections that comprise a parallel bank - const IIRSection *sections; - // Number of 2nd-order sections - unsigned int sectionsCount; - // Delay line per channel per section - SectionBuffer *buffer; - - Constants(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[], const Quality quality); - } constants; -}; // class IIRResampler - -class IIR2xInterpolator : public IIRResampler { -public: - explicit IIR2xInterpolator(const Quality quality); - explicit IIR2xInterpolator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); - - void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); - unsigned int estimateInLength(const unsigned int outLength) const; - -private: - FloatSample lastInputSamples[IIR_RESAMPER_CHANNEL_COUNT]; - unsigned int phase; -}; - -class IIR2xDecimator : public IIRResampler { -public: - explicit IIR2xDecimator(const Quality quality); - explicit IIR2xDecimator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); - - void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); - unsigned int estimateInLength(const unsigned int outLength) const; -}; - -} // namespace SRCTools - -#endif // SRCTOOLS_IIR_2X_RESAMPLER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/LinearResampler.h b/src - Cópia/sound/munt/srchelper/srctools/include/LinearResampler.h deleted file mode 100644 index c81ff2a38..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/LinearResampler.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_LINEAR_RESAMPLER_H -#define SRCTOOLS_LINEAR_RESAMPLER_H - -#include "ResamplerStage.h" - -namespace SRCTools { - -static const unsigned int LINEAR_RESAMPER_CHANNEL_COUNT = 2; - -class LinearResampler : public ResamplerStage { -public: - LinearResampler(double sourceSampleRate, double targetSampleRate); - ~LinearResampler() {} - - unsigned int estimateInLength(const unsigned int outLength) const; - void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); - -private: - const double inputToOutputRatio; - double position; - FloatSample lastInputSamples[LINEAR_RESAMPER_CHANNEL_COUNT]; -}; - -} // namespace SRCTools - -#endif // SRCTOOLS_LINEAR_RESAMPLER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerModel.h b/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerModel.h deleted file mode 100644 index f0ac23707..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerModel.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_RESAMPLER_MODEL_H -#define SRCTOOLS_RESAMPLER_MODEL_H - -#include "FloatSampleProvider.h" - -namespace SRCTools { - -class ResamplerStage; - -/** Model consists of one or more ResampleStage instances connected in a cascade. */ -namespace ResamplerModel { - -// Seems to be a good choice for 16-bit integer samples. -static const double DEFAULT_DB_SNR = 106; - -// When using linear interpolation, oversampling factor necessary to achieve the DEFAULT_DB_SNR is about 256. -// This figure is the upper estimation, and it can be found by analysing the frequency response of the linear interpolator. -// When less SNR is desired, this value should also decrease in accordance. -static const unsigned int DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR = 256; - -// In the default resampler model, the input to the windowed sinc filter is always at least 2x oversampled during upsampling, -// so oversampling factor of 128 should be sufficient to achieve the DEFAULT_DB_SNR with linear interpolation. -static const unsigned int DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR = DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR / 2; - - -enum Quality { - // Use when the speed is more important than the audio quality. - FASTEST, - // Use FAST quality setting of the IIR stage (50% of passband retained). - FAST, - // Use GOOD quality setting of the IIR stage (77% of passband retained). - GOOD, - // Use BEST quality setting of the IIR stage (95% of passband retained). - BEST -}; - -FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, double sourceSampleRate, double targetSampleRate, Quality quality); -FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage **stages, unsigned int stageCount); -FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage &stage); - -void freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source); - -} // namespace ResamplerModel - -} // namespace SRCTools - -#endif // SRCTOOLS_RESAMPLER_MODEL_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerStage.h b/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerStage.h deleted file mode 100644 index e335c0c38..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/ResamplerStage.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_RESAMPLER_STAGE_H -#define SRCTOOLS_RESAMPLER_STAGE_H - -#include "FloatSampleProvider.h" - -namespace SRCTools { - -/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */ -class ResamplerStage { -public: - virtual ~ResamplerStage() {} - - /** Returns a lower estimation of required number of input samples to produce the specified number of output samples. */ - virtual unsigned int estimateInLength(const unsigned int outLength) const = 0; - - /** Generates output samples. The arguments are adjusted in accordance with the number of samples processed. */ - virtual void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) = 0; -}; - -} // namespace SRCTools - -#endif // SRCTOOLS_RESAMPLER_STAGE_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/include/SincResampler.h b/src - Cópia/sound/munt/srchelper/srctools/include/SincResampler.h deleted file mode 100644 index 1551a1eda..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/include/SincResampler.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef SRCTOOLS_SINC_RESAMPLER_H -#define SRCTOOLS_SINC_RESAMPLER_H - -#include "FIRResampler.h" - -namespace SRCTools { - -class ResamplerStage; - -namespace SincResampler { - - ResamplerStage *createSincResampler(const double inputFrequency, const double outputFrequency, const double passbandFrequency, const double stopbandFrequency, const double dbSNR, const unsigned int maxUpsampleFactor); - - namespace Utils { - void computeResampleFactors(unsigned int &upsampleFactor, double &downsampleFactor, const double inputFrequency, const double outputFrequency, const unsigned int maxUpsampleFactor); - unsigned int greatestCommonDivisor(unsigned int a, unsigned int b); - } - - namespace KaizerWindow { - double estimateBeta(double dbRipple); - unsigned int estimateOrder(double dbRipple, double fp, double fs); - double bessel(const double x); - void windowedSinc(FIRCoefficient kernel[], const unsigned int order, const double fc, const double beta, const double amp); - } - -} // namespace SincResampler - -} // namespace SRCTools - -#endif // SRCTOOLS_SINC_RESAMPLER_H diff --git a/src - Cópia/sound/munt/srchelper/srctools/src/FIRResampler.cpp b/src - Cópia/sound/munt/srchelper/srctools/src/FIRResampler.cpp deleted file mode 100644 index 2cded0c3d..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/src/FIRResampler.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "FIRResampler.h" - -using namespace SRCTools; - -FIRResampler::Constants::Constants(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength) { - usePhaseInterpolation = downsampleFactor != floor(downsampleFactor); - FIRCoefficient *kernelCopy = new FIRCoefficient[kernelLength]; - memcpy(kernelCopy, kernel, kernelLength * sizeof(FIRCoefficient)); - taps = kernelCopy; - numberOfTaps = kernelLength; - numberOfPhases = upsampleFactor; - phaseIncrement = downsampleFactor; - unsigned int minDelayLineLength = static_cast(ceil(double(kernelLength) / upsampleFactor)); - unsigned int delayLineLength = 2; - while (delayLineLength < minDelayLineLength) delayLineLength <<= 1; - delayLineMask = delayLineLength - 1; - ringBuffer = new FloatSample[delayLineLength][FIR_INTERPOLATOR_CHANNEL_COUNT]; - FloatSample *s = *ringBuffer; - FloatSample *e = ringBuffer[delayLineLength]; - while (s < e) *(s++) = 0; -} - -FIRResampler::FIRResampler(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength) : - constants(upsampleFactor, downsampleFactor, kernel, kernelLength), - ringBufferPosition(0), - phase(constants.numberOfPhases) -{} - -FIRResampler::~FIRResampler() { - delete[] constants.ringBuffer; - delete[] constants.taps; -} - -void FIRResampler::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { - while (outLength > 0) { - while (needNextInSample()) { - if (inLength == 0) return; - addInSamples(inSamples); - --inLength; - } - getOutSamplesStereo(outSamples); - --outLength; - } -} - -unsigned int FIRResampler::estimateInLength(const unsigned int outLength) const { - return static_cast((outLength * constants.phaseIncrement + phase) / constants.numberOfPhases); -} - -bool FIRResampler::needNextInSample() const { - return constants.numberOfPhases <= phase; -} - -void FIRResampler::addInSamples(const FloatSample *&inSamples) { - ringBufferPosition = (ringBufferPosition - 1) & constants.delayLineMask; - for (unsigned int i = 0; i < FIR_INTERPOLATOR_CHANNEL_COUNT; i++) { - constants.ringBuffer[ringBufferPosition][i] = *(inSamples++); - } - phase -= constants.numberOfPhases; -} - -// Optimised for processing stereo interleaved streams -void FIRResampler::getOutSamplesStereo(FloatSample *&outSamples) { - FloatSample leftSample = 0.0; - FloatSample rightSample = 0.0; - unsigned int delaySampleIx = ringBufferPosition; - if (constants.usePhaseInterpolation) { - double phaseFraction = phase - floor(phase); - unsigned int maxTapIx = phaseFraction == 0 ? constants.numberOfTaps : constants.numberOfTaps - 1; - for (unsigned int tapIx = static_cast(phase); tapIx < maxTapIx; tapIx += constants.numberOfPhases) { - FIRCoefficient tap = FIRCoefficient(constants.taps[tapIx] + (constants.taps[tapIx + 1] - constants.taps[tapIx]) * phaseFraction); - leftSample += tap * constants.ringBuffer[delaySampleIx][0]; - rightSample += tap * constants.ringBuffer[delaySampleIx][1]; - delaySampleIx = (delaySampleIx + 1) & constants.delayLineMask; - } - } else { - // Optimised for rational resampling ratios when phase is always integer - for (unsigned int tapIx = static_cast(phase); tapIx < constants.numberOfTaps; tapIx += constants.numberOfPhases) { - FIRCoefficient tap = constants.taps[tapIx]; - leftSample += tap * constants.ringBuffer[delaySampleIx][0]; - rightSample += tap * constants.ringBuffer[delaySampleIx][1]; - delaySampleIx = (delaySampleIx + 1) & constants.delayLineMask; - } - } - *(outSamples++) = leftSample; - *(outSamples++) = rightSample; - phase += constants.phaseIncrement; -} diff --git a/src - Cópia/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp b/src - Cópia/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp deleted file mode 100644 index 0016f23c9..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#include "IIR2xResampler.h" - -namespace SRCTools { - - // Avoid denormals degrading performance, using biased input - static const BufferedSample BIAS = 1e-20f; - - // Sharp elliptic filter with symmetric ripple: N=18, Ap=As=-106 dB, fp=0.238, fs = 0.25 (in terms of sample rate) - static const IIRCoefficient FIR_BEST = 0.0014313792470984f; - static const IIRSection SECTIONS_BEST[] = { - { 2.85800356692148000f,-0.2607342682253230f,-0.602478421807085f, 0.109823442522145f }, - { -4.39519408383016000f, 1.4651975326003500f,-0.533817668127954f, 0.226045921792036f }, - { 0.86638550740991800f,-2.1053851417898500f,-0.429134968401065f, 0.403512574222174f }, - { 1.67161485530774000f, 0.7963595880494520f,-0.324989203363446f, 0.580756666711889f }, - { -1.19962759276471000f, 0.5873595178851540f,-0.241486447489019f, 0.724264899930934f }, - { 0.01631779946479250f,-0.6282334739461620f,-0.182766025706656f, 0.827774001858882f }, - { 0.28404415859352400f, 0.1038619997715160f,-0.145276649558926f, 0.898510501923554f }, - { -0.08105788424234910f, 0.0781551578108934f,-0.123965846623366f, 0.947105257601873f }, - { -0.00872608905948005f,-0.0222098231712466f,-0.115056854360748f, 0.983542001125711f } - }; - - // Average elliptic filter with symmetric ripple: N=12, Ap=As=-106 dB, fp=0.193, fs = 0.25 (in terms of sample rate) - static const IIRCoefficient FIR_GOOD = 0.000891054570268146f; - static const IIRSection SECTIONS_GOOD[] = { - { 2.2650157226725700f,-0.4034180565140230f,-0.750061486095301f, 0.157801404511953f }, - { -3.2788261989161700f, 1.3952152147542600f,-0.705854270206788f, 0.265564985645774f }, - { 0.4397975114813240f,-1.3957634748753100f,-0.639718853965265f, 0.435324134360315f }, - { 0.9827040216680520f, 0.1837182774040940f,-0.578569965618418f, 0.615205557837542f }, - { -0.3759752818621670f, 0.3266073609399490f,-0.540913588637109f, 0.778264420176574f }, - { -0.0253548089519618f,-0.0925779221603846f,-0.537704370375240f, 0.925800083252964f } - }; - - // Fast elliptic filter with symmetric ripple: N=8, Ap=As=-99 dB, fp=0.125, fs = 0.25 (in terms of sample rate) - static const IIRCoefficient FIR_FAST = 0.000882837778745889f; - static const IIRSection SECTIONS_FAST[] = { - { 1.215377077431620f,-0.35864455030878000f,-0.972220718789242f, 0.252934735930620f }, - { -1.525654419254140f, 0.86784918631245500f,-0.977713689358124f, 0.376580616703668f }, - { 0.136094441564220f,-0.50414116798010400f,-1.007004471865290f, 0.584048854845331f }, - { 0.180604082285806f,-0.00467624342403851f,-1.093486919012100f, 0.844904524843996f } - }; - - static inline BufferedSample calcNumerator(const IIRSection §ion, const BufferedSample buffer1, const BufferedSample buffer2) { - return section.num1 * buffer1 + section.num2 * buffer2; - } - - static inline BufferedSample calcDenominator(const IIRSection §ion, const BufferedSample input, const BufferedSample buffer1, const BufferedSample buffer2) { - return input - section.den1 * buffer1 - section.den2 * buffer2; - } - -} // namespace SRCTools - -using namespace SRCTools; - -double IIRResampler::getPassbandFractionForQuality(Quality quality) { - switch (quality) { - case FAST: - return 0.5; - case GOOD: - return 0.7708; - case BEST: - return 0.9524; - default: - return 0; - } -} - -IIRResampler::Constants::Constants(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[], const Quality quality) { - if (quality == CUSTOM) { - sectionsCount = useSectionsCount; - fir = useFIR; - sections = useSections; - } else { - unsigned int sectionsSize; - switch (quality) { - case FAST: - fir = FIR_FAST; - sections = SECTIONS_FAST; - sectionsSize = sizeof(SECTIONS_FAST); - break; - case GOOD: - fir = FIR_GOOD; - sections = SECTIONS_GOOD; - sectionsSize = sizeof(SECTIONS_GOOD); - break; - case BEST: - fir = FIR_BEST; - sections = SECTIONS_BEST; - sectionsSize = sizeof(SECTIONS_BEST); - break; - default: - sectionsSize = 0; - break; - } - sectionsCount = (sectionsSize / sizeof(IIRSection)); - } - const unsigned int delayLineSize = IIR_RESAMPER_CHANNEL_COUNT * sectionsCount; - buffer = new SectionBuffer[delayLineSize]; - BufferedSample *s = buffer[0]; - BufferedSample *e = buffer[delayLineSize]; - while (s < e) *(s++) = 0; -} - -IIRResampler::IIRResampler(const Quality quality) : - constants(0, 0.0f, NULL, quality) -{} - -IIRResampler::IIRResampler(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : - constants(useSectionsCount, useFIR, useSections, IIRResampler::CUSTOM) -{} - -IIRResampler::~IIRResampler() { - delete[] constants.buffer; -} - -IIR2xInterpolator::IIR2xInterpolator(const Quality quality) : - IIRResampler(quality), - phase(1) -{ - for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { - lastInputSamples[chIx] = 0; - } -} - -IIR2xInterpolator::IIR2xInterpolator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : - IIRResampler(useSectionsCount, useFIR, useSections), - phase(1) -{ - for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { - lastInputSamples[chIx] = 0; - } -} - -void IIR2xInterpolator::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { - static const IIRCoefficient INTERPOLATOR_AMP = 2.0; - - while (outLength > 0 && inLength > 0) { - SectionBuffer *bufferp = constants.buffer; - for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { - const FloatSample lastInputSample = lastInputSamples[chIx]; - const FloatSample inSample = inSamples[chIx]; - BufferedSample tmpOut = phase == 0 ? 0 : inSample * constants.fir; - for (unsigned int i = 0; i < constants.sectionsCount; ++i) { - const IIRSection §ion = constants.sections[i]; - SectionBuffer &buffer = *bufferp; - // For 2x interpolation, calculation of the numerator reduces to a single multiplication depending on the phase. - if (phase == 0) { - const BufferedSample numOutSample = section.num1 * lastInputSample; - const BufferedSample denOutSample = calcDenominator(section, BIAS + numOutSample, buffer[0], buffer[1]); - buffer[1] = denOutSample; - tmpOut += denOutSample; - } else { - const BufferedSample numOutSample = section.num2 * lastInputSample; - const BufferedSample denOutSample = calcDenominator(section, BIAS + numOutSample, buffer[1], buffer[0]); - buffer[0] = denOutSample; - tmpOut += denOutSample; - } - bufferp++; - } - *(outSamples++) = FloatSample(INTERPOLATOR_AMP * tmpOut); - if (phase > 0) { - lastInputSamples[chIx] = inSample; - } - } - outLength--; - if (phase > 0) { - inSamples += IIR_RESAMPER_CHANNEL_COUNT; - inLength--; - phase = 0; - } else { - phase = 1; - } - } -} - -unsigned int IIR2xInterpolator::estimateInLength(const unsigned int outLength) const { - return outLength >> 1; -} - -IIR2xDecimator::IIR2xDecimator(const Quality quality) : - IIRResampler(quality) -{} - -IIR2xDecimator::IIR2xDecimator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : - IIRResampler(useSectionsCount, useFIR, useSections) -{} - -void IIR2xDecimator::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { - while (outLength > 0 && inLength > 1) { - SectionBuffer *bufferp = constants.buffer; - for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { - BufferedSample tmpOut = inSamples[chIx] * constants.fir; - for (unsigned int i = 0; i < constants.sectionsCount; ++i) { - const IIRSection §ion = constants.sections[i]; - SectionBuffer &buffer = *bufferp; - // For 2x decimation, calculation of the numerator is not performed for odd output samples which are to be omitted. - tmpOut += calcNumerator(section, buffer[0], buffer[1]); - buffer[1] = calcDenominator(section, BIAS + inSamples[chIx], buffer[0], buffer[1]); - buffer[0] = calcDenominator(section, BIAS + inSamples[chIx + IIR_RESAMPER_CHANNEL_COUNT], buffer[1], buffer[0]); - bufferp++; - } - *(outSamples++) = FloatSample(tmpOut); - } - outLength--; - inLength -= 2; - inSamples += 2 * IIR_RESAMPER_CHANNEL_COUNT; - } -} - -unsigned int IIR2xDecimator::estimateInLength(const unsigned int outLength) const { - return outLength << 1; -} diff --git a/src - Cópia/sound/munt/srchelper/srctools/src/LinearResampler.cpp b/src - Cópia/sound/munt/srchelper/srctools/src/LinearResampler.cpp deleted file mode 100644 index 98b9c77c7..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/src/LinearResampler.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "LinearResampler.h" - -using namespace SRCTools; - -LinearResampler::LinearResampler(double sourceSampleRate, double targetSampleRate) : - inputToOutputRatio(sourceSampleRate / targetSampleRate), - position(1.0) // Preload delay line which effectively makes resampler zero phase -{} - -void LinearResampler::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { - if (inLength == 0) return; - while (outLength > 0) { - while (1.0 <= position) { - position--; - inLength--; - for (unsigned int chIx = 0; chIx < LINEAR_RESAMPER_CHANNEL_COUNT; ++chIx) { - lastInputSamples[chIx] = *(inSamples++); - } - if (inLength == 0) return; - } - for (unsigned int chIx = 0; chIx < LINEAR_RESAMPER_CHANNEL_COUNT; chIx++) { - *(outSamples++) = FloatSample(lastInputSamples[chIx] + position * (inSamples[chIx] - lastInputSamples[chIx])); - } - outLength--; - position += inputToOutputRatio; - } -} - -unsigned int LinearResampler::estimateInLength(const unsigned int outLength) const { - return static_cast(outLength * inputToOutputRatio); -} diff --git a/src - Cópia/sound/munt/srchelper/srctools/src/ResamplerModel.cpp b/src - Cópia/sound/munt/srchelper/srctools/src/ResamplerModel.cpp deleted file mode 100644 index 4d2d93083..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/src/ResamplerModel.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "ResamplerModel.h" - -#include "ResamplerStage.h" -#include "SincResampler.h" -#include "IIR2xResampler.h" -#include "LinearResampler.h" - -namespace SRCTools { - -namespace ResamplerModel { - -static const unsigned int CHANNEL_COUNT = 2; -static const unsigned int MAX_SAMPLES_PER_RUN = 4096; - -class CascadeStage : public FloatSampleProvider { -friend void freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source); -public: - CascadeStage(FloatSampleProvider &source, ResamplerStage &resamplerStage); - - void getOutputSamples(FloatSample *outBuffer, unsigned int size); - -protected: - ResamplerStage &resamplerStage; - -private: - FloatSampleProvider &source; - FloatSample buffer[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]; - const FloatSample *bufferPtr; - unsigned int size; -}; - -class InternalResamplerCascadeStage : public CascadeStage { -public: - InternalResamplerCascadeStage(FloatSampleProvider &useSource, ResamplerStage &useResamplerStage) : - CascadeStage(useSource, useResamplerStage) - {} - - ~InternalResamplerCascadeStage() { - delete &resamplerStage; - } -}; - -} // namespace ResamplerModel - -} // namespace SRCTools - -using namespace SRCTools; - -FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, double sourceSampleRate, double targetSampleRate, Quality quality) { - if (sourceSampleRate == targetSampleRate) { - return source; - } - if (quality == FASTEST) { - return *new InternalResamplerCascadeStage(source, *new LinearResampler(sourceSampleRate, targetSampleRate)); - } - const IIRResampler::Quality iirQuality = static_cast(quality); - const double iirPassbandFraction = IIRResampler::getPassbandFractionForQuality(iirQuality); - if (sourceSampleRate < targetSampleRate) { - ResamplerStage *iir2xInterpolator = new IIR2xInterpolator(iirQuality); - FloatSampleProvider &iir2xInterpolatorStage = *new InternalResamplerCascadeStage(source, *iir2xInterpolator); - - if (2.0 * sourceSampleRate == targetSampleRate) { - return iir2xInterpolatorStage; - } - - double passband = 0.5 * sourceSampleRate * iirPassbandFraction; - double stopband = 1.5 * sourceSampleRate; - ResamplerStage *sincResampler = SincResampler::createSincResampler(2.0 * sourceSampleRate, targetSampleRate, passband, stopband, DEFAULT_DB_SNR, DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR); - return *new InternalResamplerCascadeStage(iir2xInterpolatorStage, *sincResampler); - } - - if (sourceSampleRate == 2.0 * targetSampleRate) { - ResamplerStage *iir2xDecimator = new IIR2xDecimator(iirQuality); - return *new InternalResamplerCascadeStage(source, *iir2xDecimator); - } - - double passband = 0.5 * targetSampleRate * iirPassbandFraction; - double stopband = 1.5 * targetSampleRate; - double sincOutSampleRate = 2.0 * targetSampleRate; - const unsigned int maxUpsampleFactor = static_cast(ceil(DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR * sincOutSampleRate / sourceSampleRate)); - ResamplerStage *sincResampler = SincResampler::createSincResampler(sourceSampleRate, sincOutSampleRate, passband, stopband, DEFAULT_DB_SNR, maxUpsampleFactor); - FloatSampleProvider &sincResamplerStage = *new InternalResamplerCascadeStage(source, *sincResampler); - - ResamplerStage *iir2xDecimator = new IIR2xDecimator(iirQuality); - return *new InternalResamplerCascadeStage(sincResamplerStage, *iir2xDecimator); -} - -FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, ResamplerStage **resamplerStages, unsigned int stageCount) { - FloatSampleProvider *prevStage = &source; - for (unsigned int i = 0; i < stageCount; i++) { - prevStage = new CascadeStage(*prevStage, *(resamplerStages[i])); - } - return *prevStage; -} - -FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, ResamplerStage &stage) { - return *new CascadeStage(source, stage); -} - -void ResamplerModel::freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source) { - FloatSampleProvider *currentStage = &model; - while (currentStage != &source) { - CascadeStage *cascadeStage = dynamic_cast(currentStage); - if (cascadeStage == NULL) return; - FloatSampleProvider &prevStage = cascadeStage->source; - delete currentStage; - currentStage = &prevStage; - } -} - -using namespace ResamplerModel; - -CascadeStage::CascadeStage(FloatSampleProvider &useSource, ResamplerStage &useResamplerStage) : - resamplerStage(useResamplerStage), - source(useSource), - bufferPtr(buffer), - size() -{} - -void CascadeStage::getOutputSamples(FloatSample *outBuffer, unsigned int length) { - while (length > 0) { - if (size == 0) { - size = resamplerStage.estimateInLength(length); - if (size < 1) { - size = 1; - } else if (MAX_SAMPLES_PER_RUN < size) { - size = MAX_SAMPLES_PER_RUN; - } - source.getOutputSamples(buffer, size); - bufferPtr = buffer; - } - resamplerStage.process(bufferPtr, size, outBuffer, length); - } -} diff --git a/src - Cópia/sound/munt/srchelper/srctools/src/SincResampler.cpp b/src - Cópia/sound/munt/srchelper/srctools/src/SincResampler.cpp deleted file mode 100644 index 38d0ebe45..000000000 --- a/src - Cópia/sound/munt/srchelper/srctools/src/SincResampler.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include - -#ifdef SRCTOOLS_SINC_RESAMPLER_DEBUG_LOG -#include -#endif - -#include "SincResampler.h" - -#ifndef M_PI -static const double M_PI = 3.1415926535897932; -#endif - -using namespace SRCTools; - -using namespace SincResampler; - -using namespace Utils; - -void Utils::computeResampleFactors(unsigned int &upsampleFactor, double &downsampleFactor, const double inputFrequency, const double outputFrequency, const unsigned int maxUpsampleFactor) { - static const double RATIONAL_RATIO_ACCURACY_FACTOR = 1E15; - - upsampleFactor = static_cast(outputFrequency); - unsigned int downsampleFactorInt = static_cast(inputFrequency); - if ((upsampleFactor == outputFrequency) && (downsampleFactorInt == inputFrequency)) { - // Input and output frequencies are integers, try to reduce them - const unsigned int gcd = greatestCommonDivisor(upsampleFactor, downsampleFactorInt); - if (gcd > 1) { - upsampleFactor /= gcd; - downsampleFactor = downsampleFactorInt / gcd; - } else { - downsampleFactor = downsampleFactorInt; - } - if (upsampleFactor <= maxUpsampleFactor) return; - } else { - // Try to recover rational resample ratio by brute force - double inputToOutputRatio = inputFrequency / outputFrequency; - for (unsigned int i = 1; i <= maxUpsampleFactor; ++i) { - double testFactor = inputToOutputRatio * i; - if (floor(RATIONAL_RATIO_ACCURACY_FACTOR * testFactor + 0.5) == RATIONAL_RATIO_ACCURACY_FACTOR * floor(testFactor + 0.5)) { - // inputToOutputRatio found to be rational within the accuracy - upsampleFactor = i; - downsampleFactor = floor(testFactor + 0.5); - return; - } - } - } - // Use interpolation of FIR taps as the last resort - upsampleFactor = maxUpsampleFactor; - downsampleFactor = maxUpsampleFactor * inputFrequency / outputFrequency; -} - -unsigned int Utils::greatestCommonDivisor(unsigned int a, unsigned int b) { - while (0 < b) { - unsigned int r = a % b; - a = b; - b = r; - } - return a; -} - -double KaizerWindow::estimateBeta(double dbRipple) { - return 0.1102 * (dbRipple - 8.7); -} - -unsigned int KaizerWindow::estimateOrder(double dbRipple, double fp, double fs) { - const double transBW = (fs - fp); - return static_cast(ceil((dbRipple - 8) / (2.285 * 2 * M_PI * transBW))); -} - -double KaizerWindow::bessel(const double x) { - static const double EPS = 1.11E-16; - - double sum = 0.0; - double f = 1.0; - for (unsigned int i = 1;; ++i) { - f *= (0.5 * x / i); - double f2 = f * f; - if (f2 <= sum * EPS) break; - sum += f2; - } - return 1.0 + sum; -} - -void KaizerWindow::windowedSinc(FIRCoefficient kernel[], const unsigned int order, const double fc, const double beta, const double amp) { - const double fc_pi = M_PI * fc; - const double recipOrder = 1.0 / order; - const double mult = 2.0 * fc * amp / bessel(beta); - for (int i = order, j = 0; 0 <= i; i -= 2, ++j) { - double xw = i * recipOrder; - double win = bessel(beta * sqrt(fabs(1.0 - xw * xw))); - double xs = i * fc_pi; - double sinc = (i == 0) ? 1.0 : sin(xs) / xs; - FIRCoefficient imp = FIRCoefficient(mult * sinc * win); - kernel[j] = imp; - kernel[order - j] = imp; - } -} - -ResamplerStage *SincResampler::createSincResampler(const double inputFrequency, const double outputFrequency, const double passbandFrequency, const double stopbandFrequency, const double dbSNR, const unsigned int maxUpsampleFactor) { - unsigned int upsampleFactor; - double downsampleFactor; - computeResampleFactors(upsampleFactor, downsampleFactor, inputFrequency, outputFrequency, maxUpsampleFactor); - double baseSamplePeriod = 1.0 / (inputFrequency * upsampleFactor); - double fp = passbandFrequency * baseSamplePeriod; - double fs = stopbandFrequency * baseSamplePeriod; - double fc = 0.5 * (fp + fs); - double beta = KaizerWindow::estimateBeta(dbSNR); - unsigned int order = KaizerWindow::estimateOrder(dbSNR, fp, fs); - const unsigned int kernelLength = order + 1; - -#ifdef SRCTOOLS_SINC_RESAMPLER_DEBUG_LOG - std::clog << "FIR: " << upsampleFactor << "/" << downsampleFactor << ", N=" << kernelLength << ", NPh=" << kernelLength / double(upsampleFactor) << ", C=" << 0.5 / fc << ", fp=" << fp << ", fs=" << fs << ", M=" << maxUpsampleFactor << std::endl; -#endif - - FIRCoefficient *windowedSincKernel = new FIRCoefficient[kernelLength]; - KaizerWindow::windowedSinc(windowedSincKernel, order, fc, beta, upsampleFactor); - ResamplerStage *windowedSincStage = new FIRResampler(upsampleFactor, downsampleFactor, windowedSincKernel, kernelLength); - delete[] windowedSincKernel; - return windowedSincStage; -} diff --git a/src - Cópia/sound/nukedopl.cpp b/src - Cópia/sound/nukedopl.cpp deleted file mode 100644 index 0039a63bc..000000000 --- a/src - Cópia/sound/nukedopl.cpp +++ /dev/null @@ -1,1387 +0,0 @@ -// -// Copyright (C) 2013-2018 Alexey Khokholov (Nuke.YKT) -// -// 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. -// -// -// Nuked OPL3 emulator. -// Thanks: -// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): -// Feedback and Rhythm part calculation information. -// forums.submarine.org.uk(carbon14, opl3): -// Tremolo and phase generator calculation information. -// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): -// OPL2 ROMs. -// siliconpr0n.org(John McMaster, digshadow): -// YMF262 and VRC VII decaps and die shots. -// -// version: 1.8 -// - -#include -#include -#include -#include "nukedopl.h" - -#define RSM_FRAC 10 - -// Channel types - -enum { - ch_2op = 0, - ch_4op = 1, - ch_4op2 = 2, - ch_drum = 3 -}; - -// Envelope key types - -enum { - egk_norm = 0x01, - egk_drum = 0x02 -}; - - -// -// logsin table -// - -static const Bit16u logsinrom[256] = { - 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, - 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, - 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, - 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, - 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, - 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, - 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, - 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, - 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, - 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, - 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, - 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, - 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, - 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, - 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, - 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, - 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, - 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, - 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, - 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, - 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, - 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, - 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, - 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, - 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, - 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, - 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, - 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, - 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, - 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, - 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 -}; - -// -// exp table -// - -static const Bit16u exprom[256] = { - 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4, - 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9, - 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f, - 0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756, - 0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e, - 0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706, - 0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0, - 0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba, - 0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695, - 0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671, - 0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e, - 0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b, - 0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609, - 0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8, - 0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8, - 0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8, - 0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589, - 0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b, - 0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d, - 0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530, - 0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514, - 0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8, - 0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc, - 0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2, - 0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8, - 0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e, - 0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475, - 0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d, - 0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445, - 0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d, - 0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416, - 0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400 -}; - -// -// freq mult table multiplied by 2 -// -// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 -// - -static const Bit8u mt[16] = { - 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 -}; - -// -// ksl table -// - -static const Bit8u kslrom[16] = { - 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 -}; - -static const Bit8u kslshift[4] = { - 8, 1, 2, 0 -}; - -// -// envelope generator constants -// - -static const Bit8u eg_incstep[4][4] = { - { 0, 0, 0, 0 }, - { 1, 0, 0, 0 }, - { 1, 0, 1, 0 }, - { 1, 1, 1, 0 } -}; - -// -// address decoding -// - -static const Bit8s ad_slot[0x20] = { - 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, - 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static const Bit8u ch_slot[18] = { - 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 -}; - -// -// Envelope generator -// - -typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope); -typedef void(*envelope_genfunc)(opl3_slot *slott); - -static Bit16s OPL3_EnvelopeCalcExp(Bit32u level) -{ - if (level > 0x1fff) - { - level = 0x1fff; - } - return (exprom[level & 0xff] << 1) >> (level >> 8); -} - -static Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = 0x1000; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if ((phase & 0x300) == 0x100) - { - neg = 0xffff; - } - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope) -{ - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - phase = (phase & 0x1ff) ^ 0x1ff; - } - out = phase << 3; - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static const envelope_sinfunc envelope_sin[8] = { - OPL3_EnvelopeCalcSin0, - OPL3_EnvelopeCalcSin1, - OPL3_EnvelopeCalcSin2, - OPL3_EnvelopeCalcSin3, - OPL3_EnvelopeCalcSin4, - OPL3_EnvelopeCalcSin5, - OPL3_EnvelopeCalcSin6, - OPL3_EnvelopeCalcSin7 -}; - -enum envelope_gen_num -{ - envelope_gen_num_attack = 0, - envelope_gen_num_decay = 1, - envelope_gen_num_sustain = 2, - envelope_gen_num_release = 3 -}; - -static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) -{ - Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - - ((0x08 - slot->channel->block) << 5); - if (ksl < 0) - { - ksl = 0; - } - slot->eg_ksl = (Bit8u)ksl; -} - -static void OPL3_EnvelopeCalc(opl3_slot *slot) -{ - Bit8u nonzero; - Bit8u rate; - Bit8u rate_hi; - Bit8u rate_lo; - Bit8u reg_rate = 0; - Bit8u ks; - Bit8u eg_shift, shift; - Bit16u eg_rout; - Bit16s eg_inc; - Bit8u eg_off; - Bit8u reset = 0; - slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) - + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; - if (slot->key && slot->eg_gen == envelope_gen_num_release) - { - reset = 1; - reg_rate = slot->reg_ar; - } - else - { - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - reg_rate = slot->reg_ar; - break; - case envelope_gen_num_decay: - reg_rate = slot->reg_dr; - break; - case envelope_gen_num_sustain: - if (!slot->reg_type) - { - reg_rate = slot->reg_rr; - } - break; - case envelope_gen_num_release: - reg_rate = slot->reg_rr; - break; - } - } - slot->pg_reset = reset; - ks = slot->channel->ksv >> ((slot->reg_ksr ^ 1) << 1); - nonzero = (reg_rate != 0); - rate = ks + (reg_rate << 2); - rate_hi = rate >> 2; - rate_lo = rate & 0x03; - if (rate_hi & 0x10) - { - rate_hi = 0x0f; - } - eg_shift = rate_hi + slot->chip->eg_add; - shift = 0; - if (nonzero) - { - if (rate_hi < 12) - { - if (slot->chip->eg_state) - { - switch (eg_shift) - { - case 12: - shift = 1; - break; - case 13: - shift = (rate_lo >> 1) & 0x01; - break; - case 14: - shift = rate_lo & 0x01; - break; - default: - break; - } - } - } - else - { - shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->chip->timer & 0x03]; - if (shift & 0x04) - { - shift = 0x03; - } - if (!shift) - { - shift = slot->chip->eg_state; - } - } - } - eg_rout = slot->eg_rout; - eg_inc = 0; - eg_off = 0; - // Instant attack - if (reset && rate_hi == 0x0f) - { - eg_rout = 0x00; - } - // Envelope off - if ((slot->eg_rout & 0x1f8) == 0x1f8) - { - eg_off = 1; - } - if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off) - { - eg_rout = 0x1ff; - } - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - if (!slot->eg_rout) - { - slot->eg_gen = envelope_gen_num_decay; - } - else if (slot->key && shift > 0 && rate_hi != 0x0f) - { - eg_inc = ((~slot->eg_rout) << shift) >> 4; - } - break; - case envelope_gen_num_decay: - if ((slot->eg_rout >> 4) == slot->reg_sl) - { - slot->eg_gen = envelope_gen_num_sustain; - } - else if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - case envelope_gen_num_sustain: - case envelope_gen_num_release: - if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - } - slot->eg_rout = (eg_rout + eg_inc) & 0x1ff; - // Key off - if (reset) - { - slot->eg_gen = envelope_gen_num_attack; - } - if (!slot->key) - { - slot->eg_gen = envelope_gen_num_release; - } -} - -static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) -{ - slot->key |= type; -} - -static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) -{ - slot->key &= ~type; -} - -// -// Phase Generator -// - -static void OPL3_PhaseGenerate(opl3_slot *slot) -{ - opl3_chip *chip; - Bit16u f_num; - Bit32u basefreq; - Bit8u rm_xor, n_bit; - Bit32u noise; - Bit16u phase; - - chip = slot->chip; - f_num = slot->channel->f_num; - if (slot->reg_vib) - { - Bit8s range; - Bit8u vibpos; - - range = (f_num >> 7) & 7; - vibpos = slot->chip->vibpos; - - if (!(vibpos & 3)) - { - range = 0; - } - else if (vibpos & 1) - { - range >>= 1; - } - range >>= slot->chip->vibshift; - - if (vibpos & 4) - { - range = -range; - } - f_num += range; - } - basefreq = (f_num << slot->channel->block) >> 1; - phase = (Bit16u)(slot->pg_phase >> 9); - if (slot->pg_reset) - { - slot->pg_phase = 0; - } - slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1; - // Rhythm mode - noise = chip->noise; - slot->pg_phase_out = phase; - if (slot->slot_num == 13) // hh - { - chip->rm_hh_bit2 = (phase >> 2) & 1; - chip->rm_hh_bit3 = (phase >> 3) & 1; - chip->rm_hh_bit7 = (phase >> 7) & 1; - chip->rm_hh_bit8 = (phase >> 8) & 1; - } - if (slot->slot_num == 17 && (chip->rhy & 0x20)) // tc - { - chip->rm_tc_bit3 = (phase >> 3) & 1; - chip->rm_tc_bit5 = (phase >> 5) & 1; - } - if (chip->rhy & 0x20) - { - rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) - | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) - | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); - switch (slot->slot_num) - { - case 13: // hh - slot->pg_phase_out = rm_xor << 9; - if (rm_xor ^ (noise & 1)) - { - slot->pg_phase_out |= 0xd0; - } - else - { - slot->pg_phase_out |= 0x34; - } - break; - case 16: // sd - slot->pg_phase_out = (chip->rm_hh_bit8 << 9) - | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); - break; - case 17: // tc - slot->pg_phase_out = (rm_xor << 9) | 0x80; - break; - default: - break; - } - } - n_bit = ((noise >> 14) ^ noise) & 0x01; - chip->noise = (noise >> 1) | (n_bit << 22); -} - -// -// Slot -// - -static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) -{ - if ((data >> 7) & 0x01) - { - slot->trem = &slot->chip->tremolo; - } - else - { - slot->trem = (Bit8u*)&slot->chip->zeromod; - } - slot->reg_vib = (data >> 6) & 0x01; - slot->reg_type = (data >> 5) & 0x01; - slot->reg_ksr = (data >> 4) & 0x01; - slot->reg_mult = data & 0x0f; -} - -static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) -{ - slot->reg_ksl = (data >> 6) & 0x03; - slot->reg_tl = data & 0x3f; - OPL3_EnvelopeUpdateKSL(slot); -} - -static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) -{ - slot->reg_ar = (data >> 4) & 0x0f; - slot->reg_dr = data & 0x0f; -} - -static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) -{ - slot->reg_sl = (data >> 4) & 0x0f; - if (slot->reg_sl == 0x0f) - { - slot->reg_sl = 0x1f; - } - slot->reg_rr = data & 0x0f; -} - -static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) -{ - slot->reg_wf = data & 0x07; - if (slot->chip->newm == 0x00) - { - slot->reg_wf &= 0x03; - } -} - -static void OPL3_SlotGenerate(opl3_slot *slot) -{ - slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out); -} - -static void OPL3_SlotCalcFB(opl3_slot *slot) -{ - if (slot->channel->fb != 0x00) - { - slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); - } - else - { - slot->fbmod = 0; - } - slot->prout = slot->out; -} - -// -// Channel -// - -static void OPL3_ChannelSetupAlg(opl3_channel *channel); - -static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) -{ - opl3_channel *channel6; - opl3_channel *channel7; - opl3_channel *channel8; - Bit8u chnum; - - chip->rhy = data & 0x3f; - if (chip->rhy & 0x20) - { - channel6 = &chip->channel[6]; - channel7 = &chip->channel[7]; - channel8 = &chip->channel[8]; - channel6->out[0] = &channel6->slots[1]->out; - channel6->out[1] = &channel6->slots[1]->out; - channel6->out[2] = &chip->zeromod; - channel6->out[3] = &chip->zeromod; - channel7->out[0] = &channel7->slots[0]->out; - channel7->out[1] = &channel7->slots[0]->out; - channel7->out[2] = &channel7->slots[1]->out; - channel7->out[3] = &channel7->slots[1]->out; - channel8->out[0] = &channel8->slots[0]->out; - channel8->out[1] = &channel8->slots[0]->out; - channel8->out[2] = &channel8->slots[1]->out; - channel8->out[3] = &channel8->slots[1]->out; - for (chnum = 6; chnum < 9; chnum++) - { - chip->channel[chnum].chtype = ch_drum; - } - OPL3_ChannelSetupAlg(channel6); - OPL3_ChannelSetupAlg(channel7); - OPL3_ChannelSetupAlg(channel8); - //hh - if (chip->rhy & 0x01) - { - OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); - } - //tc - if (chip->rhy & 0x02) - { - OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); - } - //tom - if (chip->rhy & 0x04) - { - OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); - } - //sd - if (chip->rhy & 0x08) - { - OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); - } - //bd - if (chip->rhy & 0x10) - { - OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); - } - } - else - { - for (chnum = 6; chnum < 9; chnum++) - { - chip->channel[chnum].chtype = ch_2op; - OPL3_ChannelSetupAlg(&chip->channel[chnum]); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); - } - } -} - -static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) -{ - if (channel->chip->newm && channel->chtype == ch_4op2) - { - return; - } - channel->f_num = (channel->f_num & 0x300) | data; - channel->ksv = (channel->block << 1) - | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) - { - channel->pair->f_num = channel->f_num; - channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - } -} - -static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) -{ - if (channel->chip->newm && channel->chtype == ch_4op2) - { - return; - } - channel->f_num = (channel->f_num & 0xff) | ((data & 0x03) << 8); - channel->block = (data >> 2) & 0x07; - channel->ksv = (channel->block << 1) - | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) - { - channel->pair->f_num = channel->f_num; - channel->pair->block = channel->block; - channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - } -} - -static void OPL3_ChannelSetupAlg(opl3_channel *channel) -{ - if (channel->chtype == ch_drum) - { - if (channel->ch_num == 7 || channel->ch_num == 8) - { - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->chip->zeromod; - return; - } - switch (channel->alg & 0x01) - { - case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - break; - case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - break; - } - return; - } - if (channel->alg & 0x08) - { - return; - } - if (channel->alg & 0x04) - { - channel->pair->out[0] = &channel->chip->zeromod; - channel->pair->out[1] = &channel->chip->zeromod; - channel->pair->out[2] = &channel->chip->zeromod; - channel->pair->out[3] = &channel->chip->zeromod; - switch (channel->alg & 0x03) - { - case 0x00: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[1]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x02: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x03: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[0]->out; - channel->out[2] = &channel->slots[1]->out; - channel->out[3] = &channel->chip->zeromod; - break; - } - } - else - { - switch (channel->alg & 0x01) - { - case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - } - } -} - -static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) -{ - channel->fb = (data & 0x0e) >> 1; - channel->con = data & 0x01; - channel->alg = channel->con; - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con); - channel->alg = 0x08; - OPL3_ChannelSetupAlg(channel->pair); - } - else if (channel->chtype == ch_4op2) - { - channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con); - channel->pair->alg = 0x08; - OPL3_ChannelSetupAlg(channel); - } - else - { - OPL3_ChannelSetupAlg(channel); - } - } - else - { - OPL3_ChannelSetupAlg(channel); - } - if (channel->chip->newm) - { - channel->cha = ((data >> 4) & 0x01) ? ~0 : 0; - channel->chb = ((data >> 5) & 0x01) ? ~0 : 0; - } - else - { - channel->cha = channel->chb = (Bit16u)~0; - } -} - -static void OPL3_ChannelKeyOn(opl3_channel *channel) -{ - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); - } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - } - } - else - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - } -} - -static void OPL3_ChannelKeyOff(opl3_channel *channel) -{ - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); - } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - } - } - else - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - } -} - -static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) -{ - Bit8u bit; - Bit8u chnum; - for (bit = 0; bit < 6; bit++) - { - chnum = bit; - if (bit >= 3) - { - chnum += 9 - 3; - } - if ((data >> bit) & 0x01) - { - chip->channel[chnum].chtype = ch_4op; - chip->channel[chnum + 3].chtype = ch_4op2; - } - else - { - chip->channel[chnum].chtype = ch_2op; - chip->channel[chnum + 3].chtype = ch_2op; - } - } -} - -static Bit16s OPL3_ClipSample(Bit32s sample) -{ - if (sample > 32767) - { - sample = 32767; - } - else if (sample < -32768) - { - sample = -32768; - } - return (Bit16s)sample; -} - -void OPL3_Generate(opl3_chip *chip, Bit16s *buf) -{ - Bit8u ii; - Bit8u jj; - Bit16s accm; - Bit8u shift = 0; - - buf[1] = OPL3_ClipSample(chip->mixbuff[1]); - - for (ii = 0; ii < 15; ii++) - { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); - } - - chip->mixbuff[0] = 0; - for (ii = 0; ii < 18; ii++) - { - accm = 0; - for (jj = 0; jj < 4; jj++) - { - accm += *chip->channel[ii].out[jj]; - } - chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); - } - - for (ii = 15; ii < 18; ii++) - { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); - } - - buf[0] = OPL3_ClipSample(chip->mixbuff[0]); - - for (ii = 18; ii < 33; ii++) - { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); - } - - chip->mixbuff[1] = 0; - for (ii = 0; ii < 18; ii++) - { - accm = 0; - for (jj = 0; jj < 4; jj++) - { - accm += *chip->channel[ii].out[jj]; - } - chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); - } - - for (ii = 33; ii < 36; ii++) - { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); - } - - if ((chip->timer & 0x3f) == 0x3f) - { - chip->tremolopos = (chip->tremolopos + 1) % 210; - } - if (chip->tremolopos < 105) - { - chip->tremolo = chip->tremolopos >> chip->tremoloshift; - } - else - { - chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift; - } - - if ((chip->timer & 0x3ff) == 0x3ff) - { - chip->vibpos = (chip->vibpos + 1) & 7; - } - - chip->timer++; - - chip->eg_add = 0; - if (chip->eg_timer) - { - while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) - { - shift++; - } - if (shift > 12) - { - chip->eg_add = 0; - } - else - { - chip->eg_add = shift + 1; - } - } - - if (chip->eg_timerrem || chip->eg_state) - { - if (chip->eg_timer == 0xfffffffff) - { - chip->eg_timer = 0; - chip->eg_timerrem = 1; - } - else - { - chip->eg_timer++; - chip->eg_timerrem = 0; - } - } - - chip->eg_state ^= 1; - - while (chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt) - { - if (!(chip->writebuf[chip->writebuf_cur].reg & 0x200)) - { - break; - } - chip->writebuf[chip->writebuf_cur].reg &= 0x1ff; - OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_cur].reg, - chip->writebuf[chip->writebuf_cur].data); - chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE; - } - chip->writebuf_samplecnt++; -} - -void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) -{ - while (chip->samplecnt >= chip->rateratio) - { - chip->oldsamples[0] = chip->samples[0]; - chip->oldsamples[1] = chip->samples[1]; - OPL3_Generate(chip, chip->samples); - chip->samplecnt -= chip->rateratio; - } - buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) - + chip->samples[0] * chip->samplecnt) / chip->rateratio); - buf[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) - + chip->samples[1] * chip->samplecnt) / chip->rateratio); - chip->samplecnt += 1 << RSM_FRAC; -} - -void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) -{ - Bit8u slotnum; - Bit8u channum; - - memset(chip, 0, sizeof(opl3_chip)); - for (slotnum = 0; slotnum < 36; slotnum++) - { - chip->slot[slotnum].chip = chip; - chip->slot[slotnum].mod = &chip->zeromod; - chip->slot[slotnum].eg_rout = 0x1ff; - chip->slot[slotnum].eg_out = 0x1ff; - chip->slot[slotnum].eg_gen = envelope_gen_num_release; - chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod; - chip->slot[slotnum].slot_num = slotnum; - } - for (channum = 0; channum < 18; channum++) - { - chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]]; - chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3]; - chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; - chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; - if ((channum % 9) < 3) - { - chip->channel[channum].pair = &chip->channel[channum + 3]; - } - else if ((channum % 9) < 6) - { - chip->channel[channum].pair = &chip->channel[channum - 3]; - } - chip->channel[channum].chip = chip; - chip->channel[channum].out[0] = &chip->zeromod; - chip->channel[channum].out[1] = &chip->zeromod; - chip->channel[channum].out[2] = &chip->zeromod; - chip->channel[channum].out[3] = &chip->zeromod; - chip->channel[channum].chtype = ch_2op; - chip->channel[channum].cha = 0xffff; - chip->channel[channum].chb = 0xffff; - chip->channel[channum].ch_num = channum; - OPL3_ChannelSetupAlg(&chip->channel[channum]); - } - chip->noise = 1; - chip->rateratio = (samplerate << RSM_FRAC) / 49716; - chip->tremoloshift = 4; - chip->vibshift = 1; -} - -Bit32u OPL3_WriteAddr(opl3_chip *chip, Bit32u port, Bit8u val) -{ - Bit16u addr; - addr = val; - if ((port & 2) && (addr == 0x05 || chip->newm)) { - addr |= 0x100; - } - return addr; -} - -void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) -{ - Bit8u high = (reg >> 8) & 0x01; - Bit8u regm = reg & 0xff; - switch (regm & 0xf0) - { - case 0x00: - if (high) - { - switch (regm & 0x0f) - { - case 0x04: - OPL3_ChannelSet4Op(chip, v); - break; - case 0x05: - chip->newm = v & 0x01; - break; - } - } - else - { - switch (regm & 0x0f) - { - case 0x08: - chip->nts = (v >> 6) & 0x01; - break; - } - } - break; - case 0x20: - case 0x30: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x40: - case 0x50: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x60: - case 0x70: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x80: - case 0x90: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0xe0: - case 0xf0: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0xa0: - if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteA0(&chip->channel[9 * high + (regm & 0x0f)], v); - } - break; - case 0xb0: - if (regm == 0xbd && !high) - { - chip->tremoloshift = (((v >> 7) ^ 1) << 1) + 2; - chip->vibshift = ((v >> 6) & 0x01) ^ 1; - OPL3_ChannelUpdateRhythm(chip, v); - } - else if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteB0(&chip->channel[9 * high + (regm & 0x0f)], v); - if (v & 0x20) - { - OPL3_ChannelKeyOn(&chip->channel[9 * high + (regm & 0x0f)]); - } - else - { - OPL3_ChannelKeyOff(&chip->channel[9 * high + (regm & 0x0f)]); - } - } - break; - case 0xc0: - if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteC0(&chip->channel[9 * high + (regm & 0x0f)], v); - } - break; - } -} - -void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v) -{ - Bit64u time1, time2; - - if (chip->writebuf[chip->writebuf_last].reg & 0x200) - { - OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_last].reg & 0x1ff, - chip->writebuf[chip->writebuf_last].data); - - chip->writebuf_cur = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; - chip->writebuf_samplecnt = chip->writebuf[chip->writebuf_last].time; - } - - chip->writebuf[chip->writebuf_last].reg = reg | 0x200; - chip->writebuf[chip->writebuf_last].data = v; - time1 = chip->writebuf_lasttime + OPL_WRITEBUF_DELAY; - time2 = chip->writebuf_samplecnt; - - if (time1 < time2) - { - time1 = time2; - } - - chip->writebuf[chip->writebuf_last].time = time1; - chip->writebuf_lasttime = time1; - chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; -} - -void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) -{ - Bit32u i; - - for(i = 0; i < numsamples; i++) - { - OPL3_GenerateResampled(chip, sndptr); - sndptr += 2; - } -} diff --git a/src - Cópia/sound/nukedopl.h b/src - Cópia/sound/nukedopl.h deleted file mode 100644 index 9570298fb..000000000 --- a/src - Cópia/sound/nukedopl.h +++ /dev/null @@ -1,150 +0,0 @@ -// -// Copyright (C) 2013-2018 Alexey Khokholov (Nuke.YKT) -// -// 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. -// -// -// Nuked OPL3 emulator. -// Thanks: -// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): -// Feedback and Rhythm part calculation information. -// forums.submarine.org.uk(carbon14, opl3): -// Tremolo and phase generator calculation information. -// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): -// OPL2 ROMs. -// siliconpr0n.org(John McMaster, digshadow): -// YMF262 and VRC VII decaps and die shots. -// -// version: 1.8 -// - -#ifndef NUKEDOPL_H -#define NUKEDOPL_H -#define OPL_WRITEBUF_SIZE 1024 -#define OPL_WRITEBUF_DELAY 1 - -//#include "dosbox.h" -#include -typedef signed int Bits; -typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; -typedef uint16_t Bit16u; -typedef int32_t Bit32s; -typedef uint32_t Bit32u; -typedef int64_t Bit64s; -typedef uint64_t Bit64u; - -struct opl3_slot; -struct opl3_channel; -struct opl3_chip; - -struct opl3_slot { - opl3_channel *channel; - opl3_chip *chip; - Bit16s out; - Bit16s fbmod; - Bit16s *mod; - Bit16s prout; - Bit16s eg_rout; - Bit16s eg_out; - Bit8u eg_inc; - Bit8u eg_gen; - Bit8u eg_rate; - Bit8u eg_ksl; - Bit8u *trem; - Bit8u reg_vib; - Bit8u reg_type; - Bit8u reg_ksr; - Bit8u reg_mult; - Bit8u reg_ksl; - Bit8u reg_tl; - Bit8u reg_ar; - Bit8u reg_dr; - Bit8u reg_sl; - Bit8u reg_rr; - Bit8u reg_wf; - Bit8u key; - Bit32u pg_reset; - Bit32u pg_phase; - Bit16u pg_phase_out; - Bit8u slot_num; -}; - -struct opl3_channel { - opl3_slot *slots[2]; - opl3_channel *pair; - opl3_chip *chip; - Bit16s *out[4]; - Bit8u chtype; - Bit16u f_num; - Bit8u block; - Bit8u fb; - Bit8u con; - Bit8u alg; - Bit8u ksv; - Bit16u cha, chb; - Bit8u ch_num; -}; - -struct opl3_writebuf { - Bit64u time; - Bit16u reg; - Bit8u data; -}; - -struct opl3_chip { - opl3_channel channel[18]; - opl3_slot slot[36]; - Bit16u timer; - Bit64u eg_timer; - Bit8u eg_timerrem; - Bit8u eg_state; - Bit8u eg_add; - Bit8u newm; - Bit8u nts; - Bit8u rhy; - Bit8u vibpos; - Bit8u vibshift; - Bit8u tremolo; - Bit8u tremolopos; - Bit8u tremoloshift; - Bit32u noise; - Bit16s zeromod; - Bit32s mixbuff[2]; - Bit8u rm_hh_bit2; - Bit8u rm_hh_bit3; - Bit8u rm_hh_bit7; - Bit8u rm_hh_bit8; - Bit8u rm_tc_bit3; - Bit8u rm_tc_bit5; - //OPL3L - Bit32s rateratio; - Bit32s samplecnt; - Bit16s oldsamples[2]; - Bit16s samples[2]; - - Bit64u writebuf_samplecnt; - Bit32u writebuf_cur; - Bit32u writebuf_last; - Bit64u writebuf_lasttime; - opl3_writebuf writebuf[OPL_WRITEBUF_SIZE]; -}; - -void OPL3_Generate(opl3_chip *chip, Bit16s *buf); -void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); -void OPL3_Reset(opl3_chip *chip, Bit32u samplerate); -Bit32u OPL3_WriteAddr(opl3_chip *chip, Bit32u port, Bit8u val); -void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); -void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v); -void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); -#endif diff --git a/src - Cópia/sound/openal.c b/src - Cópia/sound/openal.c deleted file mode 100644 index 319623816..000000000 --- a/src - Cópia/sound/openal.c +++ /dev/null @@ -1,276 +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. - * - * Interface to the OpenAL sound processing library. - * - * Version: @(#)openal.c 1.0.6 2018/04/23 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -# undef AL_API -# undef ALC_API -# define AL_LIBTYPE_STATIC -# define ALC_LIBTYPE_STATIC -# include -# include -# include -#include "../86box.h" -#include "sound.h" -#include "midi.h" - - -#define FREQ 48000 -#define BUFLEN SOUNDBUFLEN - - -ALuint buffers[4]; /* front and back buffers */ -ALuint buffers_cd[4]; /* front and back buffers */ -ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[3]; /* audio source */ - - -static int midi_freq = 44100; -static int midi_buf_size = 4410; -static int initialized = 0; - - -void -al_set_midi(int freq, int buf_size) -{ - midi_freq = freq; - midi_buf_size = buf_size; -} - - -void closeal(void); -ALvoid alutInit(ALint *argc,ALbyte **argv) -{ - ALCcontext *Context; - ALCdevice *Device; - - /* Open device */ - Device = alcOpenDevice((ALCchar *)""); - if (Device != NULL) { - /* Create context(s) */ - Context = alcCreateContext(Device, NULL); - if (Context != NULL) { - /* Set active context */ - alcMakeContextCurrent(Context); - } - } -} - - -ALvoid -alutExit(ALvoid) -{ - ALCcontext *Context; - ALCdevice *Device; - - /* Get active context */ - Context = alcGetCurrentContext(); - if (Context != NULL) { - /* Get device for active context */ - Device = alcGetContextsDevice(Context); - if (Device != NULL) { - /* Disable context */ - alcMakeContextCurrent(NULL); - - /* Close device */ - alcCloseDevice(Device); - } - - /* Release context(s) */ - alcDestroyContext(Context); - } -} - - -void -closeal(void) -{ - if (!initialized) return; - - alutExit(); - - initialized = 0; -} - - -void -inital(void) -{ - float *buf = NULL, *cd_buf = NULL, *midi_buf = NULL; - int16_t *buf_int16 = NULL, *cd_buf_int16 = NULL, *midi_buf_int16 = NULL; - int c; - - char *mdn; - int init_midi = 0; - - if (initialized) return; - - alutInit(0, 0); - atexit(closeal); - - mdn = midi_device_get_internal_name(midi_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) - init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the - MIDI buffer and source, otherwise, do not. */ - - if (sound_is_float) { - buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); - cd_buf = (float *) malloc((CD_BUFLEN << 1) * sizeof(float)); - if (init_midi) - midi_buf = (float *) malloc(midi_buf_size * sizeof(float)); - } else { - buf_int16 = (int16_t *) malloc((BUFLEN << 1) * sizeof(int16_t)); - cd_buf_int16 = (int16_t *) malloc((CD_BUFLEN << 1) * sizeof(int16_t)); - if (init_midi) - midi_buf_int16 = (int16_t *) malloc(midi_buf_size * sizeof(int16_t)); - } - - alGenBuffers(4, buffers); - alGenBuffers(4, buffers_cd); - if (init_midi) - alGenBuffers(4, buffers_midi); - - if (init_midi) - alGenSources(3, source); - else - alGenSources(2, source); - - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); - alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); - if (init_midi) { - alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[2], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[2], AL_SOURCE_RELATIVE, AL_TRUE ); - } - - if (sound_is_float) { - memset(buf,0,BUFLEN*2*sizeof(float)); - memset(cd_buf,0,BUFLEN*2*sizeof(float)); - if (init_midi) - memset(midi_buf,0,midi_buf_size*sizeof(float)); - } else { - memset(buf_int16,0,BUFLEN*2*sizeof(int16_t)); - memset(cd_buf_int16,0,BUFLEN*2*sizeof(int16_t)); - if (init_midi) - memset(midi_buf_int16,0,midi_buf_size*sizeof(int16_t)); - } - - for (c=0; c<4; c++) { - if (sound_is_float) { - alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size*sizeof(float), midi_freq); - } else { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size*sizeof(int16_t), midi_freq); - } - } - - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_cd); - if (init_midi) - alSourceQueueBuffers(source[2], 4, buffers_midi); - alSourcePlay(source[0]); - alSourcePlay(source[1]); - if (init_midi) - alSourcePlay(source[2]); - - if (sound_is_float) { - if (init_midi) - free(midi_buf); - free(cd_buf); - free(buf); - } else { - if (init_midi) - free(midi_buf_int16); - free(cd_buf_int16); - free(buf_int16); - } - - initialized = 1; -} - - -void -givealbuffer_common(void *buf, uint8_t src, int size, int freq) -{ - int processed; - int state; - ALuint buffer; - double gain; - - alGetSourcei(source[src], AL_SOURCE_STATE, &state); - - if (state == 0x1014) { - alSourcePlay(source[src]); - } - - alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); - if (processed >= 1) { - gain = pow(10.0, (double)sound_gain / 20.0); - alListenerf(AL_GAIN, gain); - - alSourceUnqueueBuffers(source[src], 1, &buffer); - - if (sound_is_float) { - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); - } else { - alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); - } - - alSourceQueueBuffers(source[src], 1, &buffer); - } -} - - -void -givealbuffer(void *buf) -{ - givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); -} - - -void -givealbuffer_cd(void *buf) -{ - givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); -} - - -void -givealbuffer_midi(void *buf, uint32_t size) -{ - givealbuffer_common(buf, 2, size, midi_freq); -} diff --git a/src - Cópia/sound/resid-fp/AUTHORS b/src - Cópia/sound/resid-fp/AUTHORS deleted file mode 100644 index cd2ca3fcc..000000000 --- a/src - Cópia/sound/resid-fp/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Authors of reSID. - -Dag Lem: Designed and programmed complete emulation engine. -Antti S. Lankila: Support 6581 filter distortion, envelope & voice nonlinearities, output amp clipping effects. diff --git a/src - Cópia/sound/resid-fp/COPYING b/src - Cópia/sound/resid-fp/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/src - Cópia/sound/resid-fp/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/src - Cópia/sound/resid-fp/ChangeLog b/src - Cópia/sound/resid-fp/ChangeLog deleted file mode 100644 index c12e828b9..000000000 --- a/src - Cópia/sound/resid-fp/ChangeLog +++ /dev/null @@ -1,136 +0,0 @@ -2008-12-05 Antti S. Lankila - - * Sync against V27 patch version. Filter updates described below. - - * Reduce Q maximum to 2.2 or so. This may still be slightly too much, - but it's hard to say exactly... - - * Arrange for about 3 dB boost of lowpass output that is independent - of state variable mixing or other feedback. This seems to produce - the right kind of sounds for songs like AMJ's Blasphemy. - - * Assume that bp is slightly louder than bp (= more distorted). - This seems to help against very large number of songs which sport - lead sounds and effects distorted in a smooth, bassy way. - - * Parameter tuneup. - -2008-10-31 Antti S. Lankila - - * Sync against V25 patch version. Filter updates described below. - - * Tweak filter algorithm to do some state variable mixing in the - 6581 code path. This corresponds with assumed output impedance of - the SID "amplifiers", and is separate effect to the output strip - backmixing. - - * Retire the V24 attempt of dynamically adjusting BP distortion - threshold. It doesn't really seem to work. - - * Increase Q value maximum to 2.5. This may be too much, but it sounds - fine to me. - - * JT's Star Ball was very distorted when played by V24. This related - to the hardclipping I had assumed to occur in the filter output amp, - but maybe that theory is incorrect. I now only add distortion to the - unfiltered voice path, but I'm not happy about it. - -2008-08-29 Antti S. Lankila - - * Optimized resampling to be about 2x faster through using aliasing - to increase passband width and hence reduce FIR length. - - * Fixed some valgrind warnings. - - * Added nuke_denormals() method to periodically flush these to zero, as - this can only be done for SSE registers by the FPU and we can't use - any in order to support CPUs older than P3. - - * Marco, Hannu and me developed a runtime switching system - that detects SSE from cpuinfo and calls some SSE routines when they - are compiled in and the CPU can support them. We lost only very - little performance, but gained compatibility to very, very old - hardware. - - * The old code for ST_lockup proved unnecessary, so it is now removed. - -2008-08-21 Antti S. Lankila - - * Fixed a bug where nonlinearity setting appeared to get lost, and - kenchis discovered further bugs in it. Oh well. - - * I removed a lot of code associated with the lower quality modes of - ReSID, and only left the 1 MHz clock routines. Analysis shows that the - filter code is a major culprit, but the digital side emulation is not - completely cheap, either. I already added some small hacks to optimize - it, and I now think about reinjecting pieces of those clocking modes - that run the analog parts with reduced accuracy. - - * I defined type4 filters based on equation of straight line. These are - characterized by parameters k and b, and the equation is - freq = k * fc. Strictly speaking, straight line is not 100 % - accurate, and a 2nd degree component would help, but based on - measurements against two of Trurl's 8580s, the maximum error - introduced using linear approximation is mere 3 %. - -2008-08-10 Antti S. Lankila - - * I ripped off Type1 definitions from the filter, and the spline.h - and PointPlotter were unnecessary and so removed. - - * I also added a bit of hardclipping in the output that seems to be - required to get Fred Gray's Break Thru. This might not occur so - strongly on all chips, so it should probably be added as a proper - tunable. For now, I just settled for a slight effect to collect - feedback. - -2008-07-15 Antti S. Lankila - - * This release is a bit slower than usual. The culprit is the changes in - voice.h where a new kinked-dac style calculation is used to simulate - the nonlinear shape of the waveform outputs. The cost of the new - calculation varies by song as I was lazy and only cached the result of - previous calculation, so speed depends on the pitch of the waveforms - and the precise waveform chosen. - - * exp() is back, but this time it is implemented as an integer - calculation according to Schraudolph's paper "A Fast, Compact - Approximation of the Exponential Function". Using near-proper exp() - simplified the distortion algorithm. I think it all sounds much better - now. - - * A new effect where I mix bp-hp and lp-bp together by their difference - to simulate a small resistor between them appears to improve SidRiders - and several other songs, largerly eliminating some types of hard - distortion sounds that do not occur on the chip. It also helped - Mechanicus. I am trying to understand where this term comes from... - -2008-07-09 Antti S. Lankila - - * I now have somewhat less arbitrary values for the distortion - tunables. They are now related to the relative signal levels in the - simulation. I'm still sorting out the particulars of the values I - ended up with ("why 128 instead of 256"). - -2008-03-02 Antti S. Lankila - - * Exposed the filter at sid.cc to callers through get_filter() - method, and fixed a few types. - -2008-02-19 Antti S. Lankila - - * For some reason ReSID code adjusted the external filter frequency - based on calculated passband, while in the real C64 the filter is - fixed to about 16 kHz. - -2008-02-06 Antti S. Lankila - - * I got interested to improve ReSID after chatting with Kevtris. He is - aiming to replicate the filter using analog hardware. He has the EE - experience that I have sorely lacked and made an infinitely valuable - contribution by telling me exactly how the distortion works. - -2004-06-11 Dag Lem - - * Version 0.16 released. (From this point forwards, read - ../resid/ChangeLog.) diff --git a/src - Cópia/sound/resid-fp/INSTALL b/src - Cópia/sound/resid-fp/INSTALL deleted file mode 100644 index 4573d6544..000000000 --- a/src - Cópia/sound/resid-fp/INSTALL +++ /dev/null @@ -1,14 +0,0 @@ -Unless you want to do anything fancy, just say: - -% ./configure -% make - -ReSID-FP is compiled with a C++ compiler, so if you wish to specify compiler -and compiler flags you must set CXX and CXXFLAGS, e.g.: -% CXX=g++ CXXFLAGS="-g -O" ./configure - -In addition to normal configure flags, you may specify ---disable-inline - Disable inlining of functions (for debugging/profiling) - -ReSID-FP makes no installable files. The libresid.a is linked to final -executable automatically. diff --git a/src - Cópia/sound/resid-fp/Makefile.am b/src - Cópia/sound/resid-fp/Makefile.am deleted file mode 100644 index 5af263229..000000000 --- a/src - Cópia/sound/resid-fp/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -## Process this file with automake to create Makefile.in - -AR = @AR@ - -noinst_LIBRARIES = libresidfp.a - -libresidfp_a_SOURCES = sid.cc voice.cc wave.cc envelope.cc filter.cc extfilt.cc pot.cc version.cc convolve.cc $(noinst_DATA:.dat=.cc) - -BUILT_SOURCES = $(noinst_DATA:.dat=.cc) - -noinst_HEADERS = sid.h voice.h wave.h envelope.h filter.h extfilt.h pot.h - -noinst_DATA = wave6581_PST.dat wave6581_PS_.dat wave6581_P_T.dat wave6581__ST.dat wave8580_PST.dat wave8580_PS_.dat wave8580_P_T.dat wave8580__ST.dat - -noinst_SCRIPTS = samp2src.pl - -EXTRA_DIST = $(noinst_HEADERS) $(noinst_DATA) $(noinst_SCRIPTS) README.VICE convolve-sse.cc - -SUFFIXES = .dat - -.dat.cc: - $(PERL) $(srcdir)/samp2src.pl $* $< $(srcdir)/$@ - -if USE_SSE -convolve-sse.o: convolve-sse.cc - $(CXXCOMPILE) -msse -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -libresidfp_a_LIBADD = convolve-sse.o -endif diff --git a/src - Cópia/sound/resid-fp/Makefile.in b/src - Cópia/sound/resid-fp/Makefile.in deleted file mode 100644 index 5045f99a1..000000000 --- a/src - Cópia/sound/resid-fp/Makefile.in +++ /dev/null @@ -1,557 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = . -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = README $(am__configure_deps) $(noinst_HEADERS) \ - $(srcdir)/../../depcomp $(srcdir)/../../install-sh \ - $(srcdir)/../../missing $(srcdir)/../../mkinstalldirs \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/siddefs-fp.h.in $(top_srcdir)/configure AUTHORS \ - COPYING ChangeLog INSTALL NEWS -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno configure.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs -CONFIG_CLEAN_FILES = siddefs-fp.h -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -libresidfp_a_AR = $(AR) $(ARFLAGS) -@USE_SSE_TRUE@libresidfp_a_DEPENDENCIES = convolve-sse.o -am__objects_1 = wave6581_PST.$(OBJEXT) wave6581_PS_.$(OBJEXT) \ - wave6581_P_T.$(OBJEXT) wave6581__ST.$(OBJEXT) \ - wave8580_PST.$(OBJEXT) wave8580_PS_.$(OBJEXT) \ - wave8580_P_T.$(OBJEXT) wave8580__ST.$(OBJEXT) -am_libresidfp_a_OBJECTS = sid.$(OBJEXT) voice.$(OBJEXT) wave.$(OBJEXT) \ - envelope.$(OBJEXT) filter.$(OBJEXT) extfilt.$(OBJEXT) \ - pot.$(OBJEXT) version.$(OBJEXT) convolve.$(OBJEXT) \ - $(am__objects_1) -libresidfp_a_OBJECTS = $(am_libresidfp_a_OBJECTS) -SCRIPTS = $(noinst_SCRIPTS) -DEFAULT_INCLUDES = -I. -I$(srcdir) -depcomp = $(SHELL) $(top_srcdir)/../../depcomp -am__depfiles_maybe = depfiles -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ - -o $@ -SOURCES = $(libresidfp_a_SOURCES) -DIST_SOURCES = $(libresidfp_a_SOURCES) -DATA = $(noinst_DATA) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -HAVE_EXPF_PROTOTYPE = @HAVE_EXPF_PROTOTYPE@ -HAVE_LOGF_PROTOTYPE = @HAVE_LOGF_PROTOTYPE@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -RANLIB = @RANLIB@ -RESID_HAVE_BOOL = @RESID_HAVE_BOOL@ -RESID_INLINE = @RESID_INLINE@ -RESID_USE_SSE = @RESID_USE_SSE@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_SSE_FALSE = @USE_SSE_FALSE@ -USE_SSE_TRUE = @USE_SSE_TRUE@ -VERSION = @VERSION@ -ac_ct_CXX = @ac_ct_CXX@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -noinst_LIBRARIES = libresidfp.a -libresidfp_a_SOURCES = sid.cc voice.cc wave.cc envelope.cc filter.cc extfilt.cc pot.cc version.cc convolve.cc $(noinst_DATA:.dat=.cc) -BUILT_SOURCES = $(noinst_DATA:.dat=.cc) -noinst_HEADERS = sid.h voice.h wave.h envelope.h filter.h extfilt.h pot.h -noinst_DATA = wave6581_PST.dat wave6581_PS_.dat wave6581_P_T.dat wave6581__ST.dat wave8580_PST.dat wave8580_PS_.dat wave8580_P_T.dat wave8580__ST.dat -noinst_SCRIPTS = samp2src.pl -EXTRA_DIST = $(noinst_HEADERS) $(noinst_DATA) $(noinst_SCRIPTS) README.VICE convolve-sse.cc -SUFFIXES = .dat -@USE_SSE_TRUE@libresidfp_a_LIBADD = convolve-sse.o -all: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .dat .cc .o .obj -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ - cd $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -siddefs-fp.h: $(top_builddir)/config.status $(srcdir)/siddefs-fp.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libresidfp.a: $(libresidfp_a_OBJECTS) $(libresidfp_a_DEPENDENCIES) - -rm -f libresidfp.a - $(libresidfp_a_AR) libresidfp.a $(libresidfp_a_OBJECTS) $(libresidfp_a_LIBADD) - $(RANLIB) libresidfp.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/envelope.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extfilt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pot.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/voice.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580__ST.Po@am__quote@ - -.cc.o: -@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ -@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< - -.cc.obj: -@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ -@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - mkdir $(distdir) - $(mkdir_p) $(distdir)/. $(distdir)/../.. - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r $(distdir) -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && cd $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' -distuninstallcheck: - @cd $(distuninstallcheck_dir) \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LIBRARIES) $(SCRIPTS) $(DATA) $(HEADERS) -installdirs: -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -clean: clean-am - -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am - -.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ - clean-generic clean-noinstLIBRARIES ctags dist dist-all \ - dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip distcheck \ - distclean distclean-compile distclean-generic distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-man install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-info-am - - -.dat.cc: - $(PERL) $(srcdir)/samp2src.pl $* $< $(srcdir)/$@ - -@USE_SSE_TRUE@convolve-sse.o: convolve-sse.cc -@USE_SSE_TRUE@ $(CXXCOMPILE) -msse -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src - Cópia/sound/resid-fp/NEWS b/src - Cópia/sound/resid-fp/NEWS deleted file mode 100644 index 70b2d4f8e..000000000 --- a/src - Cópia/sound/resid-fp/NEWS +++ /dev/null @@ -1 +0,0 @@ -See ChangeLog for information about new features. diff --git a/src - Cópia/sound/resid-fp/README b/src - Cópia/sound/resid-fp/README deleted file mode 100644 index ac4f4275e..000000000 --- a/src - Cópia/sound/resid-fp/README +++ /dev/null @@ -1,79 +0,0 @@ -Please refer to original ../resid/README file for general discussion what -ReSID is. - -This is ReSID-FP, a fork of ReSID that has been adapted to floating point -numbers. Some SSE assembly is used for vector convolutions when both the CPU -and compiler support it. In addition, some liberties have been taken in the -frequency region > 20 kHz which should be inaudible to humans. - -In the emulation front, several changes to the original ReSID (henceforth -classical ReSID) have been made. These changes are listed here: - -Waveforms: - -- Noise waveform control via test bit is now possible. - (Unknown: how long does it take for the noise bits to fade with test bit on?) - This is used in SounDemoN's Tamaking, Bojojoing, etc, and the patch to - implement it in ReSID is his. - -- Waveform 0, the frozen DAC, is emulated, which should make the new 8-bit - sample player routine work. - -- Envelope and waveform outputs contain approximation of the imperfect DACs - (Unknown: are there other significant effects that affect the analog waveform - before it goes into filter, which should be modelled?) - -- I changed voice DC offsets around for 6581 to better match my R4AR 3789. - -Envelope: - -- Performance work at envelope. Validation pending, should ensure that the new - code behaves 100% identically to the old one. - -Mixer: - -- Experimentally, a subtle negative offset is injected into the mixer through - ext-in pin. This part seems, however, physically incorrect and is likely - removed in the future. (The coupling capacitor external to the chip must - eliminate any DC offset, and the ext-in circuit inside the chip has nothing - that could generate offsets. In the meantime, this fix still helps 8580 - Netherworld to play more correctly.) - -- I removed the mixer_DC very subtle effect on 6581, as it already has 10x - more offsets elsewhere. - -Filter: - -- 6581 filter output contains approximation of the distortion effect -- 8580 filter output has bp flipped in phase with the other outputs -- 6581 resonance is slightly boosted. Potentially 8580 resonance needs to be - slightly stronger as well, as many songs show a bit more "punch" on the real - chip and one way to get more of that is increasing resonance. 10-20 % - increment is a practical maximum. - -The upshot of all this is that for i386/x86-64 hardware, ReSID-FP's more -complicated algorithms may not seem any more expensive than the original ReSID. -For high-quality modes, it is virtually certain that ReSID-FP is actually -faster. - -Meanwhile, emulation quality should be improved. If there are bugs, I'd like -to know about them. If the filter sounds wrong, I might be able to improve it, -too. - -Here are some problematic songs, to get a feel for what's left to do: - -- Markus Mueller: Mechanicus - * the distorted guitar effect is too distorted, but don't know how/why. - -- Galway: Wizball - * the initial lead punches through with too much distortion. The "toggle" - between the muffled and more intense sound is too hard, even if similar - things do occur on the chip. - -Undoubtedly, many more such examples will be found. However, samplings and such -are really valueable only if they can be made on a chip that I have modelled -for ReSID-FP. In practice I want to know about badly-playing chips, but might -conclude that it actually plays alright. At any event, information about sound -issues is welcome. - -alankila@bel.fi diff --git a/src - Cópia/sound/resid-fp/README.VICE b/src - Cópia/sound/resid-fp/README.VICE deleted file mode 100644 index 02072ce9e..000000000 --- a/src - Cópia/sound/resid-fp/README.VICE +++ /dev/null @@ -1,14 +0,0 @@ -This version of reSID has been modified for use with VICE. It is based on the -work contained in the resid/ directory, with duplicate files removed. All -classes have been renamed with suffix FP to avoid link-time clashes with the -other RESID implementation. - -These files reuse some define terms also defined by resid. You should not mix -resid/* and resid-fp/* files in one compile unit, or the results are probably -invalid. - -In particular, libtool is not used to build the library, and there -might be some workarounds for various substandard compilers. - -Please get the original version if you want to use reSID in your own -project. diff --git a/src - Cópia/sound/resid-fp/aclocal.m4 b/src - Cópia/sound/resid-fp/aclocal.m4 deleted file mode 100644 index aef181a6d..000000000 --- a/src - Cópia/sound/resid-fp/aclocal.m4 +++ /dev/null @@ -1,850 +0,0 @@ -# generated automatically by aclocal 1.9.6 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. -# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.6])]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 7 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE]) -AC_SUBST([$1_FALSE]) -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH]) -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -#serial 3 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 12 - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.58])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_PROG_INSTALL_SH -AM_PROG_INSTALL_STRIP -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -]) -]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $1 | $1:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"$am_aux_dir/install-sh"} -AC_SUBST(install_sh)]) - -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_MKDIR_P -# --------------- -# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. -# -# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories -# created by `make install' are always world readable, even if the -# installer happens to have an overly restrictive umask (e.g. 077). -# This was a mistake. There are at least two reasons why we must not -# use `-m 0755': -# - it causes special bits like SGID to be ignored, -# - it may be too restrictive (some setups expect 775 directories). -# -# Do not use -m 0755 and let people choose whatever they expect by -# setting umask. -# -# We cannot accept any implementation of `mkdir' that recognizes `-p'. -# Some implementations (such as Solaris 8's) are not thread-safe: if a -# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' -# concurrently, both version can detect that a/ is missing, but only -# one can create it and the other will error out. Consequently we -# restrict ourselves to GNU make (using the --version option ensures -# this.) -AC_DEFUN([AM_PROG_MKDIR_P], -[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi -AC_SUBST([mkdir_p])]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - diff --git a/src - Cópia/sound/resid-fp/configure b/src - Cópia/sound/resid-fp/configure deleted file mode 100644 index 35a9c8f7d..000000000 --- a/src - Cópia/sound/resid-fp/configure +++ /dev/null @@ -1,5955 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61. -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell autoconf@gnu.org about your system, - echo including any error possibly output before this - echo message -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="sid.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL -PATH_SEPARATOR -PACKAGE_NAME -PACKAGE_TARNAME -PACKAGE_VERSION -PACKAGE_STRING -PACKAGE_BUGREPORT -exec_prefix -prefix -program_transform_name -bindir -sbindir -libexecdir -datarootdir -datadir -sysconfdir -sharedstatedir -localstatedir -includedir -oldincludedir -docdir -infodir -htmldir -dvidir -pdfdir -psdir -libdir -localedir -mandir -DEFS -ECHO_C -ECHO_N -ECHO_T -LIBS -build_alias -host_alias -target_alias -INSTALL_PROGRAM -INSTALL_SCRIPT -INSTALL_DATA -CYGPATH_W -PACKAGE -VERSION -ACLOCAL -AUTOCONF -AUTOMAKE -AUTOHEADER -MAKEINFO -install_sh -STRIP -INSTALL_STRIP_PROGRAM -mkdir_p -AWK -SET_MAKE -am__leading_dot -AMTAR -am__tar -am__untar -RESID_INLINE -CXX -CXXFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CXX -EXEEXT -OBJEXT -DEPDIR -am__include -am__quote -AMDEP_TRUE -AMDEP_FALSE -AMDEPBACKSLASH -CXXDEPMODE -am__fastdepCXX_TRUE -am__fastdepCXX_FALSE -AR -RANLIB -PERL -CXXCPP -GREP -EGREP -USE_SSE_TRUE -USE_SSE_FALSE -RESID_HAVE_BOOL -RESID_USE_SSE -HAVE_LOGF_PROTOTYPE -HAVE_EXPF_PROTOTYPE -LIBOBJS -LTLIBOBJS' -ac_subst_files='' - ac_precious_vars='build_alias -host_alias -target_alias -CXX -CXXFLAGS -LDFLAGS -LIBS -CPPFLAGS -CCC -CXXCPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=\$ac_optarg ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute directory names. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { echo "$as_me: error: Working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$0" || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-inline enable inlining of functions default=yes - --enable-sse enable the use of SSE default=yes - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - -Some influential environment variables: - CXX C++ compiler command - CXXFLAGS C++ compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CXXCPP C++ preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -configure -generated by GNU Autoconf 2.61 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.61. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -n "$CONFIG_SITE"; then - set x "$CONFIG_SITE" -elif test "x$prefix" != xNONE; then - set x "$prefix/share/config.site" "$prefix/etc/config.site" -else - set x "$ac_default_prefix/share/config.site" \ - "$ac_default_prefix/etc/config.site" -fi -shift -for ac_site_file -do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -am__api_version="1.9" -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done -IFS=$as_save_IFS - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&5 -echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&2;} - { (exit 1); exit 1; }; } - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! -Check your system clock" >&5 -echo "$as_me: error: newly created file is older than distributed files! -Check your system clock" >&2;} - { (exit 1); exit 1; }; } -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. echo might interpret backslashes. -# By default was `s,x,x', remove it if useless. -cat <<\_ACEOF >conftest.sed -s/[\\$]/&&/g;s/;s,x,x,$// -_ACEOF -program_transform_name=`echo $program_transform_name | sed -f conftest.sed` -rm -f conftest.sed - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 -echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { echo "$as_me:$LINENO: result: $AWK" >&5 -echo "${ECHO_T}$AWK" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } -set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - SET_MAKE= -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 -echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} - { (exit 1); exit 1; }; } -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE=resid - VERSION=0.16vice - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -install_sh=${install_sh-"$am_aux_dir/install-sh"} - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - - -LTVERSION=5:0:0 - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -# Check whether --enable-inline was given. -if test "${enable_inline+set}" = set; then - enableval=$enable_inline; -fi - -# Check whether --enable-sse was given. -if test "${enable_sse+set}" = set; then - enableval=$enable_sse; -fi - - -if test "$enable_inline" != no; then - RESID_INLINE=inline -else - RESID_INLINE= -fi - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C++ compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 -echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi - -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } -if test -z "$ac_file"; then - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C++ compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 -echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C++ compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } - -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CXXFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi - - -{ echo "$as_me:$LINENO: result: $_am_result" >&5 -echo "${ECHO_T}$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - - -if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - - -depcc="$CXX" am_compiler_list= - -{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - - -if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - -if test x"$enable_sse" != "xno"; then - if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 -msse" - { echo "$as_me:$LINENO: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -echo $ECHO_N "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works... $ECHO_C" >&6; } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -int test; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - MSSE="-msse" - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - MSSE="" - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - fi -else - MSSE="" -fi - -if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 $MSSE -fno-exceptions" - { echo "$as_me:$LINENO: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -echo $ECHO_N "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -int test; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - NO_EXCEPTIONS="-fno-exceptions" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - NO_EXCEPTIONS="" - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi -fi - -if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 $MSSE -fno-exceptions $NO_EXCEPTIONS -fno-pic" - { echo "$as_me:$LINENO: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -echo $ECHO_N "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -int test; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - NO_PIC="-fno-pic" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - NO_PIC="" - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi -fi - -CXXFLAGS="-g -Wall -O2 $MSSE $NO_EXCEPTIONS $NO_PIC" -if test x"$MSSE" = "x-msse"; then - { echo "$as_me:$LINENO: checking if the xmmintrin.h include can be used" >&5 -echo $ECHO_N "checking if the xmmintrin.h include can be used... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int test; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - MSSE="" - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS="-g -Wall -O2 $NO_EXCEPTIONS $NO_PIC" -fi - -# Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -# Extract the first word of "perl", so it can be a program name with args. -set dummy perl; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_PERL+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PERL in - [\\/]* | ?:[\\/]*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - ;; -esac -fi -PERL=$ac_cv_path_PERL -if test -n "$PERL"; then - { echo "$as_me:$LINENO: result: $PERL" >&5 -echo "${ECHO_T}$PERL" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - - - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 -echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } -if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -{ echo "$as_me:$LINENO: result: $CXXCPP" >&5 -echo "${ECHO_T}$CXXCPP" >&6; } -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Extract the first word of "grep ggrep" to use in msg output -if test -z "$GREP"; then -set dummy grep ggrep; ac_prog_name=$2 -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_GREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue - # Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_GREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -GREP="$ac_cv_path_GREP" -if test -z "$GREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_GREP=$GREP -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -echo "${ECHO_T}$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - # Extract the first word of "egrep" to use in msg output -if test -z "$EGREP"; then -set dummy egrep; ac_prog_name=$2 -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_EGREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue - # Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_EGREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -EGREP="$ac_cv_path_EGREP" -if test -z "$EGREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_EGREP=$EGREP -fi - - - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -{ echo "$as_me:$LINENO: checking for int" >&5 -echo $ECHO_N "checking for int... $ECHO_C" >&6; } -if test "${ac_cv_type_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef int ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_int=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 -echo "${ECHO_T}$ac_cv_type_int" >&6; } - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ echo "$as_me:$LINENO: checking size of int" >&5 -echo $ECHO_N "checking size of int... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_int=$ac_lo;; -'') if test "$ac_cv_type_int" = yes; then - { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } - else - ac_cv_sizeof_int=0 - fi ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -if test "$ac_cv_type_int" = yes; then - { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } - else - ac_cv_sizeof_int=0 - fi -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - - -if test $ac_cv_sizeof_int -lt 4; then - { { echo "$as_me:$LINENO: error: only 32 bit or better CPUs are supported" >&5 -echo "$as_me: error: only 32 bit or better CPUs are supported" >&2;} - { (exit 1); exit 1; }; } -fi - -{ echo "$as_me:$LINENO: checking for working bool" >&5 -echo $ECHO_N "checking for working bool... $ECHO_C" >&6; } -if test "${ac_cv_cxx_bool+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - -bool flag; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_cxx_bool=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_cxx_bool=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_cxx_bool" >&5 -echo "${ECHO_T}$ac_cv_cxx_bool" >&6; } - -if test $ac_cv_cxx_bool = no; then - RESID_HAVE_BOOL=0 -else - RESID_HAVE_BOOL=1 -fi - -if test x"$MSSE" = "x-msse"; then - RESID_USE_SSE=1 - - -if true; then - USE_SSE_TRUE= - USE_SSE_FALSE='#' -else - USE_SSE_TRUE='#' - USE_SSE_FALSE= -fi - -else - RESID_USE_SSE=0 - - -if false; then - USE_SSE_TRUE= - USE_SSE_FALSE='#' -else - USE_SSE_TRUE='#' - USE_SSE_FALSE= -fi - -fi - - - - - - - -for ac_func in logf expf -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -{ echo "$as_me:$LINENO: checking if the logf prototype is present" >&5 -echo $ECHO_N "checking if the logf prototype is present... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - #include -int -main () -{ -printf("%d",logf); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - HAVE_LOGF_PROTOTYPE=1 - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - HAVE_LOGF_PROTOTYPE=0 - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -{ echo "$as_me:$LINENO: checking if the expf prototype is present" >&5 -echo $ECHO_N "checking if the expf prototype is present... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - #include -int -main () -{ -printf("%d",expf); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - HAVE_EXPF_PROTOTYPE=1 - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - HAVE_EXPF_PROTOTYPE=0 - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - - - -ac_config_files="$ac_config_files Makefile siddefs-fp.h" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { echo "$as_me:$LINENO: updating cache $cache_file" >&5 -echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${USE_SSE_TRUE}" && test -z "${USE_SSE_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"USE_SSE\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"USE_SSE\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${USE_SSE_TRUE}" && test -z "${USE_SSE_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"USE_SSE\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"USE_SSE\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.61. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -# Files that config.status was made for. -config_files="$ac_config_files" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.61, - with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2006 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=$SHELL - export CONFIG_SHELL - exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "siddefs-fp.h") CONFIG_FILES="$CONFIG_FILES siddefs-fp.h" ;; - - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - -_ACEOF - - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -SHELL!$SHELL$ac_delim -PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim -PACKAGE_NAME!$PACKAGE_NAME$ac_delim -PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim -PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim -PACKAGE_STRING!$PACKAGE_STRING$ac_delim -PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim -exec_prefix!$exec_prefix$ac_delim -prefix!$prefix$ac_delim -program_transform_name!$program_transform_name$ac_delim -bindir!$bindir$ac_delim -sbindir!$sbindir$ac_delim -libexecdir!$libexecdir$ac_delim -datarootdir!$datarootdir$ac_delim -datadir!$datadir$ac_delim -sysconfdir!$sysconfdir$ac_delim -sharedstatedir!$sharedstatedir$ac_delim -localstatedir!$localstatedir$ac_delim -includedir!$includedir$ac_delim -oldincludedir!$oldincludedir$ac_delim -docdir!$docdir$ac_delim -infodir!$infodir$ac_delim -htmldir!$htmldir$ac_delim -dvidir!$dvidir$ac_delim -pdfdir!$pdfdir$ac_delim -psdir!$psdir$ac_delim -libdir!$libdir$ac_delim -localedir!$localedir$ac_delim -mandir!$mandir$ac_delim -DEFS!$DEFS$ac_delim -ECHO_C!$ECHO_C$ac_delim -ECHO_N!$ECHO_N$ac_delim -ECHO_T!$ECHO_T$ac_delim -LIBS!$LIBS$ac_delim -build_alias!$build_alias$ac_delim -host_alias!$host_alias$ac_delim -target_alias!$target_alias$ac_delim -INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim -INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim -INSTALL_DATA!$INSTALL_DATA$ac_delim -CYGPATH_W!$CYGPATH_W$ac_delim -PACKAGE!$PACKAGE$ac_delim -VERSION!$VERSION$ac_delim -ACLOCAL!$ACLOCAL$ac_delim -AUTOCONF!$AUTOCONF$ac_delim -AUTOMAKE!$AUTOMAKE$ac_delim -AUTOHEADER!$AUTOHEADER$ac_delim -MAKEINFO!$MAKEINFO$ac_delim -install_sh!$install_sh$ac_delim -STRIP!$STRIP$ac_delim -INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim -mkdir_p!$mkdir_p$ac_delim -AWK!$AWK$ac_delim -SET_MAKE!$SET_MAKE$ac_delim -am__leading_dot!$am__leading_dot$ac_delim -AMTAR!$AMTAR$ac_delim -am__tar!$am__tar$ac_delim -am__untar!$am__untar$ac_delim -RESID_INLINE!$RESID_INLINE$ac_delim -CXX!$CXX$ac_delim -CXXFLAGS!$CXXFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CXX!$ac_ct_CXX$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -DEPDIR!$DEPDIR$ac_delim -am__include!$am__include$ac_delim -am__quote!$am__quote$ac_delim -AMDEP_TRUE!$AMDEP_TRUE$ac_delim -AMDEP_FALSE!$AMDEP_FALSE$ac_delim -AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim -CXXDEPMODE!$CXXDEPMODE$ac_delim -am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim -am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim -AR!$AR$ac_delim -RANLIB!$RANLIB$ac_delim -PERL!$PERL$ac_delim -CXXCPP!$CXXCPP$ac_delim -GREP!$GREP$ac_delim -EGREP!$EGREP$ac_delim -USE_SSE_TRUE!$USE_SSE_TRUE$ac_delim -USE_SSE_FALSE!$USE_SSE_FALSE$ac_delim -RESID_HAVE_BOOL!$RESID_HAVE_BOOL$ac_delim -RESID_USE_SSE!$RESID_USE_SSE$ac_delim -HAVE_LOGF_PROTOTYPE!$HAVE_LOGF_PROTOTYPE$ac_delim -HAVE_EXPF_PROTOTYPE!$HAVE_EXPF_PROTOTYPE$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g -CEOF$ac_eof -_ACEOF - - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF -fi # test -n "$CONFIG_FILES" - - -for ac_tag in :F $CONFIG_FILES :C $CONFIG_COMMANDS -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - ac_file_inputs="$ac_file_inputs $ac_f" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - fi - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -case `sed -n '/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' $ac_file_inputs` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac - ;; - - - :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 -echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir=$dirpart/$fdir - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - - esac -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/src - Cópia/sound/resid-fp/configure.in b/src - Cópia/sound/resid-fp/configure.in deleted file mode 100644 index f4b3b5731..000000000 --- a/src - Cópia/sound/resid-fp/configure.in +++ /dev/null @@ -1,166 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(sid.h) - -dnl Use Automake -AM_INIT_AUTOMAKE(resid, 0.16vice) -LTVERSION=5:0:0 - -dnl Use C++ for tests. -AC_LANG_CPLUSPLUS - -dnl Enable inlining. -AC_ARG_ENABLE(inline, -[ --enable-inline enable inlining of functions [default=yes]]) -AC_ARG_ENABLE(sse, -[ --enable-sse enable the use of SSE [default=yes]]) - -if test "$enable_inline" != no; then - RESID_INLINE=inline -else - RESID_INLINE= -fi - -AC_SUBST(RESID_INLINE) - -dnl Checks for programs. -AC_PROG_CXX - -dnl Set CXXFLAGS for g++. Use -msse if supported. -if test x"$enable_sse" != "xno"; then - if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 -msse" - AC_MSG_CHECKING([whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works]) - AC_TRY_COMPILE([], - [int test;], - [ AC_MSG_RESULT(yes) - MSSE="-msse" - ], - [ AC_MSG_RESULT(no) - MSSE="" - ]) - fi - fi -else - MSSE="" -fi - -dnl Set CXXFLAGS for g++. Use -fno-exceptions if supported. -if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 $MSSE -fno-exceptions" - AC_MSG_CHECKING([whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works]) - AC_TRY_COMPILE([], - [int test;], - [ AC_MSG_RESULT(yes) - NO_EXCEPTIONS="-fno-exceptions" ], - [ AC_MSG_RESULT(no) - NO_EXCEPTIONS="" - ]) - fi -fi - -dnl Set CXXFLAGS for g++. Use -fno-pic if supported. -if test "$GXX" = yes; then - if test "$ac_test_CXXFLAGS" != set; then - CXXFLAGS="-g -Wall -O2 $MSSE -fno-exceptions $NO_EXCEPTIONS -fno-pic" - AC_MSG_CHECKING([whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works]) - AC_TRY_COMPILE([], - [int test;], - [ AC_MSG_RESULT(yes) - NO_PIC="-fno-pic" ], - [ AC_MSG_RESULT(no) - NO_PIC="" - ]) - fi -fi - -CXXFLAGS="-g -Wall -O2 $MSSE $NO_EXCEPTIONS $NO_PIC" -if test x"$MSSE" = "x-msse"; then - AC_MSG_CHECKING([if the xmmintrin.h include can be used]) - AC_TRY_COMPILE([#include ], - [int test;], - [ AC_MSG_RESULT(yes) - ], - [ AC_MSG_RESULT(no) - MSSE="" - ]) - CXXFLAGS="-g -Wall -O2 $NO_EXCEPTIONS $NO_PIC" -fi - -AC_CHECK_PROG(AR, ar, ar, ar) -AC_PROG_RANLIB -AC_PATH_PROG(PERL, perl) - -dnl Libtool - -dnl AC_DISABLE_SHARED -dnl AM_PROG_LIBTOOL -dnl AC_SUBST(LIBTOOL_DEPS) -dnl AC_SUBST(LTVERSION) - -dnl Checks for libraries. - -dnl Checks for header files. - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_SIZEOF(int, 4) - -if test $ac_cv_sizeof_int -lt 4; then - AC_MSG_ERROR([only 32 bit or better CPUs are supported]) -fi - -AC_CACHE_CHECK([for working bool], ac_cv_cxx_bool, -[AC_TRY_COMPILE(, -[ -bool flag; -], -ac_cv_cxx_bool=yes, ac_cv_cxx_bool=no)]) - -if test $ac_cv_cxx_bool = no; then - RESID_HAVE_BOOL=0 -else - RESID_HAVE_BOOL=1 -fi - -if test x"$MSSE" = "x-msse"; then - RESID_USE_SSE=1 - AM_CONDITIONAL(USE_SSE, true) -else - RESID_USE_SSE=0 - AM_CONDITIONAL(USE_SSE, false) -fi - -AC_SUBST(RESID_HAVE_BOOL) -AC_SUBST(RESID_USE_SSE) - -dnl Checks for library functions. - -AC_CHECK_FUNCS(logf expf) - -AC_MSG_CHECKING([if the logf prototype is present]) -AC_TRY_COMPILE([#include - #include ], - [printf("%d",logf);], - [ AC_MSG_RESULT(yes) - HAVE_LOGF_PROTOTYPE=1 - ], - [ AC_MSG_RESULT(no) - HAVE_LOGF_PROTOTYPE=0 - ]) - -AC_MSG_CHECKING([if the expf prototype is present]) -AC_TRY_COMPILE([#include - #include ], - [printf("%d",expf);], - [ AC_MSG_RESULT(yes) - HAVE_EXPF_PROTOTYPE=1 - ], - [ AC_MSG_RESULT(no) - HAVE_EXPF_PROTOTYPE=0 - ]) - -AC_SUBST(HAVE_LOGF_PROTOTYPE) -AC_SUBST(HAVE_EXPF_PROTOTYPE) - -AC_OUTPUT(Makefile siddefs-fp.h) diff --git a/src - Cópia/sound/resid-fp/convolve-sse.cc b/src - Cópia/sound/resid-fp/convolve-sse.cc deleted file mode 100644 index daf3979f2..000000000 --- a/src - Cópia/sound/resid-fp/convolve-sse.cc +++ /dev/null @@ -1,76 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- -#include -#include "sid.h" - -#if (RESID_USE_SSE==1) - -#include - -float convolve_sse(const float *a, const float *b, int n) -{ - float out = 0.f; - __m128 out4 = { 0, 0, 0, 0 }; - - /* examine if we can use aligned loads on both pointers */ - int diff = (int) (a - b) & 0xf; - /* long cast is no-op for x86-32, but x86-64 gcc needs 64 bit intermediate - * to convince compiler we mean this. */ - unsigned int a_align = (unsigned int) (uintptr_t) a & 0xf; - - /* advance if necessary. We can't let n fall < 0, so no while (n --). */ - while (n > 0 && a_align != 0 && a_align != 16) { - out += (*(a ++)) * (*(b ++)); - --n; - a_align += 4; - } - - int n4 = n / 4; - if (diff == 0) { - for (int i = 0; i < n4; i ++) { - out4 = _mm_add_ps(out4, _mm_mul_ps(_mm_load_ps(a), _mm_load_ps(b))); - a += 4; - b += 4; - } - } else { - /* XXX loadu is 4x slower than load, at least. We could at 4x memory - * use prepare versions of b aligned for any a alignment. We could - * also issue aligned loads and shuffle the halves at each iteration. - * Initial results indicate only very small improvements. */ - for (int i = 0; i < n4; i ++) { - out4 = _mm_add_ps(out4, _mm_mul_ps(_mm_load_ps(a), _mm_loadu_ps(b))); - a += 4; - b += 4; - } - } - - out4 = _mm_add_ps(_mm_movehl_ps(out4, out4), out4); - out4 = _mm_add_ss(_mm_shuffle_ps(out4, out4, 1), out4); - float out_tmp; - _mm_store_ss(&out_tmp, out4); - out += out_tmp; - - n &= 3; - - while (n --) - out += (*(a ++)) * (*(b ++)); - - return out; -} -#endif diff --git a/src - Cópia/sound/resid-fp/convolve.cc b/src - Cópia/sound/resid-fp/convolve.cc deleted file mode 100644 index b028ace86..000000000 --- a/src - Cópia/sound/resid-fp/convolve.cc +++ /dev/null @@ -1,27 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -float convolve(const float *a, const float *b, int n) -{ - float out = 0.f; - while (n --) - out += (*(a ++)) * (*(b ++)); - return out; -} - diff --git a/src - Cópia/sound/resid-fp/envelope.cc b/src - Cópia/sound/resid-fp/envelope.cc deleted file mode 100644 index 5417adc43..000000000 --- a/src - Cópia/sound/resid-fp/envelope.cc +++ /dev/null @@ -1,254 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#define __ENVELOPE_CC__ -#include "envelope.h" - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -EnvelopeGeneratorFP::EnvelopeGeneratorFP() -{ - reset(); -} - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void EnvelopeGeneratorFP::reset() -{ - envelope_counter = 0; - - attack = 0; - decay = 0; - sustain = 0; - release = 0; - - gate = 0; - - rate_counter = 0; - exponential_counter = 0; - exponential_counter_period = 1; - - state = RELEASE; - rate_period = rate_counter_period[release]; - hold_zero = true; -} - - -// Rate counter periods are calculated from the Envelope Rates table in -// the Programmer's Reference Guide. The rate counter period is the number of -// cycles between each increment of the envelope counter. -// The rates have been verified by sampling ENV3. -// -// The rate counter is a 16 bit register which is incremented each cycle. -// When the counter reaches a specific comparison value, the envelope counter -// is incremented (attack) or decremented (decay/release) and the -// counter is zeroed. -// -// NB! Sampling ENV3 shows that the calculated values are not exact. -// It may seem like most calculated values have been rounded (.5 is rounded -// down) and 1 has beed added to the result. A possible explanation for this -// is that the SID designers have used the calculated values directly -// as rate counter comparison values, not considering a one cycle delay to -// zero the counter. This would yield an actual period of comparison value + 1. -// -// The time of the first envelope count can not be exactly controlled, except -// possibly by resetting the chip. Because of this we cannot do cycle exact -// sampling and must devise another method to calculate the rate counter -// periods. -// -// The exact rate counter periods can be determined e.g. by counting the number -// of cycles from envelope level 1 to envelope level 129, and dividing the -// number of cycles by 128. CIA1 timer A and B in linked mode can perform -// the cycle count. This is the method used to find the rates below. -// -// To avoid the ADSR delay bug, sampling of ENV3 should be done using -// sustain = release = 0. This ensures that the attack state will not lower -// the current rate counter period. -// -// The ENV3 sampling code below yields a maximum timing error of 14 cycles. -// lda #$01 -// l1: cmp $d41c -// bne l1 -// ... -// lda #$ff -// l2: cmp $d41c -// bne l2 -// -// This yields a maximum error for the calculated rate period of 14/128 cycles. -// The described method is thus sufficient for exact calculation of the rate -// periods. -// -reg16 EnvelopeGeneratorFP::rate_counter_period[] = { - 9, // 2ms*1.0MHz/256 = 7.81 - 32, // 8ms*1.0MHz/256 = 31.25 - 63, // 16ms*1.0MHz/256 = 62.50 - 95, // 24ms*1.0MHz/256 = 93.75 - 149, // 38ms*1.0MHz/256 = 148.44 - 220, // 56ms*1.0MHz/256 = 218.75 - 267, // 68ms*1.0MHz/256 = 265.63 - 313, // 80ms*1.0MHz/256 = 312.50 - 392, // 100ms*1.0MHz/256 = 390.63 - 977, // 250ms*1.0MHz/256 = 976.56 - 1954, // 500ms*1.0MHz/256 = 1953.13 - 3126, // 800ms*1.0MHz/256 = 3125.00 - 3907, // 1 s*1.0MHz/256 = 3906.25 - 11720, // 3 s*1.0MHz/256 = 11718.75 - 19532, // 5 s*1.0MHz/256 = 19531.25 - 31251 // 8 s*1.0MHz/256 = 31250.00 -}; - - -// For decay and release, the clock to the envelope counter is sequentially -// divided by 1, 2, 4, 8, 16, 30, 1 to create a piece-wise linear approximation -// of an exponential. The exponential counter period is loaded at the envelope -// counter values 255, 93, 54, 26, 14, 6, 0. The period can be different for the -// same envelope counter value, depending on whether the envelope has been -// rising (attack -> release) or sinking (decay/release). -// -// Since it is not possible to reset the rate counter (the test bit has no -// influence on the envelope generator whatsoever) a method must be devised to -// do cycle exact sampling of ENV3 to do the investigation. This is possible -// with knowledge of the rate period for A=0, found above. -// -// The CPU can be synchronized with ENV3 by first synchronizing with the rate -// counter by setting A=0 and wait in a carefully timed loop for the envelope -// counter _not_ to change for 9 cycles. We can then wait for a specific value -// of ENV3 with another timed loop to fully synchronize with ENV3. -// -// At the first period when an exponential counter period larger than one -// is used (decay or relase), one extra cycle is spent before the envelope is -// decremented. The envelope output is then delayed one cycle until the state -// is changed to attack. Now one cycle less will be spent before the envelope -// is incremented, and the situation is normalized. -// The delay is probably caused by the comparison with the exponential counter, -// and does not seem to affect the rate counter. This has been verified by -// timing 256 consecutive complete envelopes with A = D = R = 1, S = 0, using -// CIA1 timer A and B in linked mode. If the rate counter is not affected the -// period of each complete envelope is -// (255 + 162*1 + 39*2 + 28*4 + 12*8 + 8*16 + 6*30)*32 = 756*32 = 32352 -// which corresponds exactly to the timed value divided by the number of -// complete envelopes. -// NB! This one cycle delay is not modeled. - - -// From the sustain levels it follows that both the low and high 4 bits of the -// envelope counter are compared to the 4-bit sustain value. -// This has been verified by sampling ENV3. -// -reg8 EnvelopeGeneratorFP::sustain_level[] = { - 0x00, - 0x11, - 0x22, - 0x33, - 0x44, - 0x55, - 0x66, - 0x77, - 0x88, - 0x99, - 0xaa, - 0xbb, - 0xcc, - 0xdd, - 0xee, - 0xff, -}; - - -// ---------------------------------------------------------------------------- -// Register functions. -// ---------------------------------------------------------------------------- -void EnvelopeGeneratorFP::writeCONTROL_REG(reg8 control) -{ - reg8 gate_next = control & 0x01; - - // The rate counter is never reset, thus there will be a delay before the - // envelope counter starts counting up (attack) or down (release). - - // Gate bit on: Start attack, decay, sustain. - if (!gate && gate_next) { - state = ATTACK; - update_rate_period(rate_counter_period[attack]); - - // Switching to attack state unlocks the zero freeze. - hold_zero = false; - } - // Gate bit off: Start release. - else if (gate && !gate_next) { - state = RELEASE; - update_rate_period(rate_counter_period[release]); - } - - gate = gate_next; -} - -void EnvelopeGeneratorFP::writeATTACK_DECAY(reg8 attack_decay) -{ - attack = (attack_decay >> 4) & 0x0f; - decay = attack_decay & 0x0f; - if (state == ATTACK) { - update_rate_period(rate_counter_period[attack]); - } - else if (state == DECAY_SUSTAIN) { - update_rate_period(rate_counter_period[decay]); - } -} - -void EnvelopeGeneratorFP::writeSUSTAIN_RELEASE(reg8 sustain_release) -{ - sustain = (sustain_release >> 4) & 0x0f; - release = sustain_release & 0x0f; - if (state == RELEASE) { - update_rate_period(rate_counter_period[release]); - } -} - -reg8 EnvelopeGeneratorFP::readENV() -{ - return output(); -} - -void EnvelopeGeneratorFP::update_rate_period(reg16 newperiod) -{ - rate_period = newperiod; - - /* The ADSR counter is XOR shift register with 0x7fff unique values. - * If the rate_period is adjusted to a value already seen in this cycle, - * the register will wrap around. This is known as the ADSR delay bug. - * - * To simplify the hot path calculation, we simulate this through observing - * that we add the 0x7fff cycle delay by changing the rate_counter variable - * directly. This takes care of the 99 % common case. However, playroutine - * could make multiple consequtive rate_period adjustments, in which case we - * need to cancel the previous adjustment. */ - - /* if the new period exeecds 0x7fff, we need to wrap */ - if (rate_period - rate_counter > 0x7fff) - rate_counter += 0x7fff; - - /* simulate 0x7fff wraparound, if the period-to-be-written - * is less than the current value. */ - if (rate_period <= rate_counter) - rate_counter -= 0x7fff; - - /* at this point it should be impossible for - * rate_counter >= rate_period. If it is, there is a bug... */ -} diff --git a/src - Cópia/sound/resid-fp/envelope.h b/src - Cópia/sound/resid-fp/envelope.h deleted file mode 100644 index 556e71a47..000000000 --- a/src - Cópia/sound/resid-fp/envelope.h +++ /dev/null @@ -1,174 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __ENVELOPE_H__ -#define __ENVELOPE_H__ - -#include "siddefs-fp.h" - -// ---------------------------------------------------------------------------- -// A 15 bit counter is used to implement the envelope rates, in effect -// dividing the clock to the envelope counter by the currently selected rate -// period. -// In addition, another counter is used to implement the exponential envelope -// decay, in effect further dividing the clock to the envelope counter. -// The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope -// counter values 255, 93, 54, 26, 14, 6, respectively. -// ---------------------------------------------------------------------------- -class EnvelopeGeneratorFP -{ -public: - EnvelopeGeneratorFP(); - - enum State { ATTACK, DECAY_SUSTAIN, RELEASE }; - - RESID_INLINE void clock(); - void reset(); - - void writeCONTROL_REG(reg8); - void writeATTACK_DECAY(reg8); - void writeSUSTAIN_RELEASE(reg8); - reg8 readENV(); - - // 8-bit envelope output. - RESID_INLINE reg8 output(); - -protected: - void update_rate_period(reg16 period); - - int rate_counter; - int rate_period; - reg8 exponential_counter; - reg8 exponential_counter_period; - reg8 envelope_counter; - bool hold_zero; - - reg4 attack; - reg4 decay; - reg4 sustain; - reg4 release; - - reg8 gate; - - State state; - - // Lookup table to convert from attack, decay, or release value to rate - // counter period. - static reg16 rate_counter_period[]; - - // The 16 selectable sustain levels. - static reg8 sustain_level[]; - -friend class SIDFP; -}; - - -// ---------------------------------------------------------------------------- -// SID clocking - 1 cycle. -// ---------------------------------------------------------------------------- -RESID_INLINE -void EnvelopeGeneratorFP::clock() -{ - if (++ rate_counter != rate_period) - return; - - rate_counter = 0; - - // The first envelope step in the attack state also resets the exponential - // counter. This has been verified by sampling ENV3. - // - if (state == ATTACK || ++exponential_counter == exponential_counter_period) - { - exponential_counter = 0; - - // Check whether the envelope counter is frozen at zero. - if (hold_zero) { - return; - } - - switch (state) { - case ATTACK: - // The envelope counter can flip from 0xff to 0x00 by changing state to - // release, then to attack. The envelope counter is then frozen at - // zero; to unlock this situation the state must be changed to release, - // then to attack. This has been verified by sampling ENV3. - // - ++envelope_counter &= 0xff; - if (envelope_counter == 0xff) { - state = DECAY_SUSTAIN; - update_rate_period(rate_counter_period[decay]); - } - break; - case DECAY_SUSTAIN: - if (envelope_counter != sustain_level[sustain]) { - --envelope_counter; - } - break; - case RELEASE: - // The envelope counter can flip from 0x00 to 0xff by changing state to - // attack, then to release. The envelope counter will then continue - // counting down in the release state. - // This has been verified by sampling ENV3. - // NB! The operation below requires two's complement integer. - // - --envelope_counter &= 0xff; - break; - } - - // Check for change of exponential counter period. - switch (envelope_counter) { - case 0xff: - exponential_counter_period = 1; - break; - case 0x5d: - exponential_counter_period = 2; - break; - case 0x36: - exponential_counter_period = 4; - break; - case 0x1a: - exponential_counter_period = 8; - break; - case 0x0e: - exponential_counter_period = 16; - break; - case 0x06: - exponential_counter_period = 30; - break; - case 0x00: - exponential_counter_period = 1; - - // When the envelope counter is changed to zero, it is frozen at zero. - // This has been verified by sampling ENV3. - hold_zero = true; - break; - } - } -} - -// ---------------------------------------------------------------------------- -// Read the envelope generator output. -// ---------------------------------------------------------------------------- -RESID_INLINE -reg8 EnvelopeGeneratorFP::output() -{ - return envelope_counter; -} - -#endif // not __ENVELOPE_H__ diff --git a/src - Cópia/sound/resid-fp/extfilt.cc b/src - Cópia/sound/resid-fp/extfilt.cc deleted file mode 100644 index 777a23ee3..000000000 --- a/src - Cópia/sound/resid-fp/extfilt.cc +++ /dev/null @@ -1,94 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#define __EXTFILT_CC__ -#include "extfilt.h" - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -ExternalFilterFP::ExternalFilterFP() -{ - reset(); - enable_filter(true); - set_chip_model(MOS6581FP); - set_clock_frequency(1e6f); - set_sampling_parameter(15915.6f); -} - - -// ---------------------------------------------------------------------------- -// Enable filter. -// ---------------------------------------------------------------------------- -void ExternalFilterFP::enable_filter(bool enable) -{ - enabled = enable; -} - -// ---------------------------------------------------------------------------- -// Setup of the external filter sampling parameters. -// ---------------------------------------------------------------------------- -void ExternalFilterFP::set_clock_frequency(float clock) -{ - clock_frequency = clock; - _set_sampling_parameter(); -} - -void ExternalFilterFP::set_sampling_parameter(float freq) -{ - pass_frequency = freq; - _set_sampling_parameter(); -} - -void ExternalFilterFP::_set_sampling_parameter() -{ - // Low-pass: R = 10kOhm, C = 1000pF; w0l = 1/RC = 1/(1e4*1e-9) = 100000 - // High-pass: R = 1kOhm, C = 10uF; w0h = 1/RC = 1/(1e3*1e-5) = 100 - w0hp = 100.f / clock_frequency; - w0lp = pass_frequency * 2.f * M_PI_f / clock_frequency; -} - -// ---------------------------------------------------------------------------- -// Set chip model. -// ---------------------------------------------------------------------------- -void ExternalFilterFP::set_chip_model(chip_model model) -{ - if (model == MOS6581FP) { - // Approximate the DC output level to be removed if the external - // filter is turned off. (0x800 - wave_zero + voice DC) * maxenv * voices - // - extin offset... - mixer_DC = (-0x600 + 0x800) * 0xff * 3 - 0x20000; - } - else { - // No DC offsets in the MOS8580. - mixer_DC = 0; - } -} - - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void ExternalFilterFP::reset() -{ - // State of filter. - Vlp = 0; - Vhp = 0; - Vo = 0; -} diff --git a/src - Cópia/sound/resid-fp/extfilt.h b/src - Cópia/sound/resid-fp/extfilt.h deleted file mode 100644 index b0e04d3b8..000000000 --- a/src - Cópia/sound/resid-fp/extfilt.h +++ /dev/null @@ -1,120 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __EXTFILT_H__ -#define __EXTFILT_H__ - -#include - -#include "siddefs-fp.h" - -// ---------------------------------------------------------------------------- -// The audio output stage in a Commodore 64 consists of two STC networks, -// a low-pass filter with 3-dB frequency 16kHz followed by a high-pass -// filter with 3-dB frequency 16Hz (the latter provided an audio equipment -// input impedance of 1kOhm). -// The STC networks are connected with a BJT supposedly meant to act as -// a unity gain buffer, which is not really how it works. A more elaborate -// model would include the BJT, however DC circuit analysis yields BJT -// base-emitter and emitter-base impedances sufficiently low to produce -// additional low-pass and high-pass 3dB-frequencies in the order of hundreds -// of kHz. This calls for a sampling frequency of several MHz, which is far -// too high for practical use. -// ---------------------------------------------------------------------------- -class ExternalFilterFP -{ -public: - ExternalFilterFP(); - - void enable_filter(bool enable); - void set_sampling_parameter(float pass_freq); - void set_chip_model(chip_model model); - void set_clock_frequency(float); - - RESID_INLINE void clock(float Vi); - void reset(); - - // Audio output (20 bits). - RESID_INLINE float output(); - -private: - void _set_sampling_parameter(); - void nuke_denormals(); - - // Filter enabled. - bool enabled; - - // Maximum mixer DC offset. - float mixer_DC; - - // Relevant clocks - float clock_frequency, pass_frequency; - - // State of filters. - float Vlp; // lowpass - float Vhp; // highpass - float Vo; - - // Cutoff frequencies. - float w0lp; - float w0hp; - -friend class SIDFP; -}; - -// ---------------------------------------------------------------------------- -// SID clocking - 1 cycle. -// ---------------------------------------------------------------------------- -RESID_INLINE -void ExternalFilterFP::clock(float Vi) -{ - // This is handy for testing. - if (! enabled) { - // Remove maximum DC level since there is no filter to do it. - Vlp = Vhp = 0.f; - Vo = Vi - mixer_DC; - return; - } - - float dVlp = w0lp * (Vi - Vlp); - float dVhp = w0hp * (Vlp - Vhp); - Vo = Vlp - Vhp; - Vlp += dVlp; - Vhp += dVhp; -} - -// ---------------------------------------------------------------------------- -// Audio output (19.5 bits). -// ---------------------------------------------------------------------------- -RESID_INLINE -float ExternalFilterFP::output() -{ - return Vo; -} - -RESID_INLINE -void ExternalFilterFP::nuke_denormals() -{ - if (Vhp > -1e-12f && Vhp < 1e-12f) - Vhp = 0; - if (Vlp > -1e-12f && Vlp < 1e-12f) - Vlp = 0; -} - -#endif // not __EXTFILT_H__ diff --git a/src - Cópia/sound/resid-fp/filter.cc b/src - Cópia/sound/resid-fp/filter.cc deleted file mode 100644 index c327fadec..000000000 --- a/src - Cópia/sound/resid-fp/filter.cc +++ /dev/null @@ -1,194 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- -// Filter distortion code written by Antti S. Lankila 2007 - 2008. - -#define __FILTER_CC__ -#include "filter.h" -#include "sid.h" - -#ifndef HAVE_LOGF_PROTOTYPE -extern float logf(float val); -#endif - -#ifndef HAVE_EXPF_PROTOTYPE -extern float expf(float val); -#endif - -#ifndef HAVE_LOGF -float logf(float val) -{ - return (float)log((double)val); -} -#endif - -#ifndef HAVE_EXPF -float expf(float val) -{ - return (float)exp((double)val); -} -#endif - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -FilterFP::FilterFP() -{ - model = (chip_model) 0; // neither 6581/8580; init time only - enable_filter(true); - /* approximate; sid.cc calls us when set_sampling_parameters() occurs. */ - set_clock_frequency(1e6f); - /* these parameters are a work-in-progress. */ - set_distortion_properties(2.5e-3f, 1536.f, 1e-4f); - /* sound similar to alankila6581r4ar3789 */ - set_type3_properties(1.40e6f, 1.47e8f, 1.0059f, 1.55e4f); - /* sound similar to trurl8580r5_3691 */ - set_type4_properties(6.55f, 20.f); - reset(); - set_chip_model(MOS6581FP); -} - - -// ---------------------------------------------------------------------------- -// Enable filter. -// ---------------------------------------------------------------------------- -void FilterFP::enable_filter(bool enable) -{ - enabled = enable; -} - - -// ---------------------------------------------------------------------------- -// Set chip model. -// ---------------------------------------------------------------------------- -void FilterFP::set_chip_model(chip_model model) -{ - this->model = model; - set_Q(); - set_w0(); -} - -/* dist_CT eliminates 1/x at hot spot */ -void FilterFP::set_clock_frequency(float clock) { - clock_frequency = clock; - calculate_helpers(); -} - -void FilterFP::set_distortion_properties(float r, float p, float cft) -{ - distortion_rate = r; - distortion_point = p; - /* baseresistance is used to determine material resistivity later */ - distortion_cf_threshold = cft; - calculate_helpers(); -} - -void FilterFP::set_type4_properties(float k, float b) -{ - type4_k = k; - type4_b = b; -} - -void FilterFP::set_type3_properties(float br, float o, float s, float mfr) -{ - type3_baseresistance = br; - type3_offset = o; - type3_steepness = -logf(s); /* s^x to e^(x*ln(s)), 1/e^x == e^-x. */ - type3_minimumfetresistance = mfr; -} - -void FilterFP::calculate_helpers() -{ - if (clock_frequency != 0.f) - distortion_CT = 1.f / (sidcaps_6581 * clock_frequency); - set_w0(); -} - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void FilterFP::reset() -{ - fc = 0; - res = filt = voice3off = hp_bp_lp = 0; - vol = 0; - volf = Vhp = Vbp = Vlp = 0; - set_w0(); - set_Q(); -} - -// ---------------------------------------------------------------------------- -// Register functions. -// ---------------------------------------------------------------------------- -void FilterFP::writeFC_LO(reg8 fc_lo) -{ - fc = (fc & 0x7f8) | (fc_lo & 0x007); - set_w0(); -} - -void FilterFP::writeFC_HI(reg8 fc_hi) -{ - fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007); - set_w0(); -} - -void FilterFP::writeRES_FILT(reg8 res_filt) -{ - res = (res_filt >> 4) & 0x0f; - set_Q(); - - filt = res_filt & 0x0f; -} - -void FilterFP::writeMODE_VOL(reg8 mode_vol) -{ - voice3off = mode_vol & 0x80; - - hp_bp_lp = (mode_vol >> 4) & 0x07; - - vol = mode_vol & 0x0f; - volf = (float) vol / 15.f; -} - -// Set filter cutoff frequency. -void FilterFP::set_w0() -{ - if (model == MOS6581FP) { - /* div once by extra kinkiness because I fitted the type3 eq with that variant. */ - float type3_fc_kink = SIDFP::kinked_dac(fc, kinkiness, 11) / kinkiness; - type3_fc_kink_exp = type3_offset * expf(type3_fc_kink * type3_steepness); - if (distortion_rate != 0.f) { - type3_fc_distortion_offset_hp = (distortion_point - type3_fc_kink) * (0.5f) / distortion_rate; - type3_fc_distortion_offset_bp = type3_fc_distortion_offset_hp; - } - else { - type3_fc_distortion_offset_bp = 9e9f; - type3_fc_distortion_offset_hp = 9e9f; - } - } - if (model == MOS8580FP) { - type4_w0_cache = type4_w0(); - } -} - -// Set filter resonance. -void FilterFP::set_Q() -{ - float Q = res / 15.f; - _1_div_Q = 1.f / (0.707f + Q * 1.5f); -} diff --git a/src - Cópia/sound/resid-fp/filter.h b/src - Cópia/sound/resid-fp/filter.h deleted file mode 100644 index 13e6aa67e..000000000 --- a/src - Cópia/sound/resid-fp/filter.h +++ /dev/null @@ -1,383 +0,0 @@ -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- -// Filter distortion code written by Antti S. Lankila 2007 - 2008. - -#ifndef __FILTER_H__ -#define __FILTER_H__ - -#include -#include "siddefs-fp.h" - -// ---------------------------------------------------------------------------- -// The SID filter is modeled with a two-integrator-loop biquadratic filter, -// which has been confirmed by Bob Yannes to be the actual circuit used in -// the SID chip. -// -// Measurements show that excellent emulation of the SID filter is achieved, -// except when high resonance is combined with high sustain levels. -// In this case the SID op-amps are performing less than ideally and are -// causing some peculiar behavior of the SID filter. This however seems to -// have more effect on the overall amplitude than on the color of the sound. -// -// The theory for the filter circuit can be found in "Microelectric Circuits" -// by Adel S. Sedra and Kenneth C. Smith. -// The circuit is modeled based on the explanation found there except that -// an additional inverter is used in the feedback from the bandpass output, -// allowing the summer op-amp to operate in single-ended mode. This yields -// inverted filter outputs with levels independent of Q, which corresponds with -// the results obtained from a real SID. -// -// We have been able to model the summer and the two integrators of the circuit -// to form components of an IIR filter. -// Vhp is the output of the summer, Vbp is the output of the first integrator, -// and Vlp is the output of the second integrator in the filter circuit. -// -// According to Bob Yannes, the active stages of the SID filter are not really -// op-amps. Rather, simple NMOS inverters are used. By biasing an inverter -// into its region of quasi-linear operation using a feedback resistor from -// input to output, a MOS inverter can be made to act like an op-amp for -// small signals centered around the switching threshold. -// -// Qualified guesses at SID filter schematics are depicted below. -// -// SID filter -// ---------- -// -// ----------------------------------------------- -// | | -// | ---Rq-- | -// | | | | -// | --------------|--R-----[A>--|--R-----[A>--| -// | | | | -// vi -----R1-- | | | -// -// vhp vbp vlp -// -// -// vi - input voltage -// vhp - highpass output -// vbp - bandpass output -// vlp - lowpass output -// [A> - op-amp -// R1 - summer resistor -// Rq - resistor array controlling resonance (4 resistors) -// R - NMOS FET voltage controlled resistor controlling cutoff frequency -// Rs - shunt resitor -// C - capacitor -// -// -// -// SID integrator -// -------------- -// -// V+ -// -// | -// | -// -----| -// | | -// | ||-- -// -|| -// ---C--- ||-> -// | | | -// |---Rs-----------|---- vo -// | | -// | ||-- -// vi ---- -----|------------|| -// | ^ | ||-> -// |___| | | -// ----- | | -// | | | -// |---R2-- | -// | -// R1 V- -// | -// | -// -// Vw -// -// ---------------------------------------------------------------------------- -class FilterFP -{ -public: - FilterFP(); - - void enable_filter(bool enable); - void set_chip_model(chip_model model); - void set_distortion_properties(float, float, float); - void set_type3_properties(float, float, float, float); - void set_type4_properties(float, float); - void set_clock_frequency(float); - - RESID_INLINE - float clock(float voice1, float voice2, float voice3, - float ext_in); - void reset(); - - // Write registers. - void writeFC_LO(reg8); - void writeFC_HI(reg8); - void writeRES_FILT(reg8); - void writeMODE_VOL(reg8); - -private: - void set_Q(); - void set_w0(); - float type3_w0(const float source, const float offset); - float type4_w0(); - void calculate_helpers(); - void nuke_denormals(); - - // Filter enabled. - bool enabled; - - // 6581/8580 filter model (XXX: we should specialize in separate classes) - chip_model model; - - // Filter cutoff frequency. - reg12 fc; - - // Filter resonance. - reg8 res; - - // Selects which inputs to route through filter. - reg8 filt; - - // Switch voice 3 off. - reg8 voice3off; - - // Highpass, bandpass, and lowpass filter modes. - reg8 hp_bp_lp; - - // Output master volume. - reg4 vol; - float volf; /* avoid integer-to-float conversion at output */ - - // clock - float clock_frequency; - - /* Distortion params for Type3 */ - float distortion_rate, distortion_point, distortion_cf_threshold; - - /* Type3 params. */ - float type3_baseresistance, type3_offset, type3_steepness, type3_minimumfetresistance; - - /* Type4 params */ - float type4_k, type4_b; - - // State of filter. - float Vhp, Vbp, Vlp; - - /* Resonance/Distortion/Type3/Type4 helpers. */ - float type4_w0_cache, _1_div_Q, type3_fc_kink_exp, distortion_CT, - type3_fc_distortion_offset_bp, type3_fc_distortion_offset_hp; - -friend class SIDFP; -}; - -// ---------------------------------------------------------------------------- -// Inline functions. -// The following functions are defined inline because they are called every -// time a sample is calculated. -// ---------------------------------------------------------------------------- - -/* kinkiness of DAC: - * some chips have more, some less. We should make this tunable. */ -const float kinkiness = 0.966f; -const float sidcaps_6581 = 470e-12f; -const float outputleveldifference_lp_bp = 1.4f; -const float outputleveldifference_bp_hp = 1.2f; - -RESID_INLINE -static float fastexp(float val) { - typedef union { - int i; - float f; - } conv; - - conv tmp; - - /* single precision fp has 1 + 8 + 23 bits, exponent bias is 127. - * It therefore follows that we need to shift left by 23 bits, and to - * calculate exp(x) instead of pow(2, x) we divide the power by ln(2). */ - const float a = (1 << 23) / M_LN2_f; - /* The other factor corrects for the exponent bias so that 2^0 = 1. */ - const float b = (1 << 23) * 127; - /* According to "A Fast, Compact Approximation of the Exponential Function" - * by Nicol N. Schraudolph, 60801.48 yields the minimum RMS error for the - * piecewise-linear approximation when using doubles (20 bits residual). - * We have 23 bits, so we scale this value by 8. */ - const float c = 60801.48f * 8.f + 0.5f; - - /* Parenthesis are important: C standard disallows folding subtraction. - * Unfortunately GCC appears to generate a write to memory rather than - * handle this conversion entirely in registers. */ - tmp.i = (int)(a * val + (b - c)); - return tmp.f; -} - -RESID_INLINE -float FilterFP::type3_w0(const float source, const float distoffset) -{ - /* The distortion appears to be the result of MOSFET entering saturation - * mode. The conductance of a FET is proportional to: - * - * ohmic = 2 * (Vgs - Vt) * Vds - Vds^2 - * saturation = (Vgs - Vt)^2 - * - * The FET switches to saturation mode when Vgs - Vt < Vds. - * - * In the circuit, the Vgs is mixed with the Vds signal, which gives - * (Vgs + Vds) / 2 as the gate voltage. Doing the substitutions we get: - * - * ohmic = 2 * ((Vgs + Vds) / 2 - Vt) * Vds - Vds^2 = (Vgs - Vt) * Vds - * saturation = ((Vgs + Vds) / 2 - Vt)^2 - * - * Therefore: once the Vds crosses a threshold given by the gate and - * threshold FET conductance begins to increase faster. The exact shape - * for this effect is a parabola. - * - * The scaling term here tries to match the FC control level with - * the signal level in simulation. On the chip, the FC control is - * biased by forcing its highest DAC bit in the 1 position, thus - * limiting the electrical range to half. Therefore one can guess that - * the real FC range is half of the full voice range. - * - * On the simulation, FC goes to 2047 and the voices to 4095 * 255. - * If the FC control was intact, then the scaling factor would be - * 1/512. (Simulation voices are 512 times "louder" intrinsically.) - * As the real chip's FC has reduced range, the scaling required to - * match levels is 1/256. */ - - float fetresistance = type3_fc_kink_exp; - if (source > distoffset) { - const float dist = source - distoffset; - fetresistance *= fastexp(dist * type3_steepness * distortion_rate); - } - const float dynamic_resistance = type3_minimumfetresistance + fetresistance; - - /* 2 parallel resistors */ - const float _1_div_resistance = (type3_baseresistance + dynamic_resistance) / (type3_baseresistance * dynamic_resistance); - /* 1.f / (clock * caps * resistance) */ - return distortion_CT * _1_div_resistance; -} - -RESID_INLINE -float FilterFP::type4_w0() -{ - const float freq = type4_k * fc + type4_b; - return 2.f * M_PI_f * freq / clock_frequency; -} - -// ---------------------------------------------------------------------------- -// SID clocking - 1 cycle. -// ---------------------------------------------------------------------------- -RESID_INLINE -float FilterFP::clock(float voice1, - float voice2, - float voice3, - float ext_in) -{ - /* Avoid denormal numbers by using small offsets from 0 */ - float Vi = 0.f, Vnf = 0.f, Vf = 0.f; - - // Route voices into or around filter. - ((filt & 1) ? Vi : Vnf) += voice1; - ((filt & 2) ? Vi : Vnf) += voice2; - // NB! Voice 3 is not silenced by voice3off if it is routed through - // the filter. - if (filt & 4) - Vi += voice3; - else if (! voice3off) - Vnf += voice3; - ((filt & 8) ? Vi : Vnf) += ext_in; - - if (! enabled) - return (Vnf - Vi) * volf; - - if (hp_bp_lp & 1) - Vf += Vlp; - if (hp_bp_lp & 2) - Vf += Vbp; - if (hp_bp_lp & 4) - Vf += Vhp; - - if (model == MOS6581FP) { - float diff1, diff2; - - Vhp = Vbp * _1_div_Q * (1.f/outputleveldifference_bp_hp) - Vlp * (1.f/outputleveldifference_bp_hp) - Vi * 0.5f; - - /* the input summer mixing, or something like it... */ - diff1 = (Vlp - Vbp) * distortion_cf_threshold; - diff2 = (Vhp - Vbp) * distortion_cf_threshold; - Vlp -= diff1; - Vbp += diff1; - Vbp += diff2; - Vhp -= diff2; - - /* Model output strip mixing. Doing it now that HP state - * variable modifying still makes some difference. - * (Phase error, though.) */ - if (hp_bp_lp & 1) - Vlp += (Vf + Vnf - Vlp) * distortion_cf_threshold; - if (hp_bp_lp & 2) - Vbp += (Vf + Vnf - Vbp) * distortion_cf_threshold; - if (hp_bp_lp & 4) - Vhp += (Vf + Vnf - Vhp) * distortion_cf_threshold; - - /* Simulating the exponential VCR that the FET block is... */ - Vlp -= Vbp * type3_w0(Vbp, type3_fc_distortion_offset_bp); - Vbp -= Vhp * type3_w0(Vhp, type3_fc_distortion_offset_hp) * outputleveldifference_bp_hp; - - /* Tuned based on Fred Gray's Break Thru. It is probably not a hard - * discontinuity but a saturation effect... */ - if (Vnf > 3.2e6f) - Vnf = 3.2e6f; - - Vf += Vnf + Vlp * (outputleveldifference_lp_bp - 1.f); - } else { - /* On the 8580, BP appears mixed in phase with the rest. */ - Vhp = -Vbp * _1_div_Q - Vlp - Vi; - Vlp += Vbp * type4_w0_cache; - Vbp += Vhp * type4_w0_cache; - - Vf += Vnf; - } - - return Vf * volf; -} - -RESID_INLINE -void FilterFP::nuke_denormals() -{ - /* We could use the flush-to-zero flag or denormals-are-zero on systems - * where compiling with -msse and -mfpmath=sse is acceptable. Since this - * doesn't include general VICE builds, we do this instead. */ - if (Vbp > -1e-12f && Vbp < 1e-12f) - Vbp = 0; - if (Vlp > -1e-12f && Vlp < 1e-12f) - Vlp = 0; -} - -#endif // not __FILTER_H__ diff --git a/src - Cópia/sound/resid-fp/pot.cc b/src - Cópia/sound/resid-fp/pot.cc deleted file mode 100644 index 4cd85a5c3..000000000 --- a/src - Cópia/sound/resid-fp/pot.cc +++ /dev/null @@ -1,26 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "pot.h" - -reg8 PotentiometerFP::readPOT() -{ - // NB! Not modeled. - return 0xff; -} diff --git a/src - Cópia/sound/resid-fp/pot.h b/src - Cópia/sound/resid-fp/pot.h deleted file mode 100644 index e1deeabda..000000000 --- a/src - Cópia/sound/resid-fp/pot.h +++ /dev/null @@ -1,31 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __POT_H__ -#define __POT_H__ - -#include "siddefs-fp.h" - -class PotentiometerFP -{ -public: - reg8 readPOT(); -}; - -#endif diff --git a/src - Cópia/sound/resid-fp/samp2src.pl b/src - Cópia/sound/resid-fp/samp2src.pl deleted file mode 100644 index fc6398382..000000000 --- a/src - Cópia/sound/resid-fp/samp2src.pl +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/perl -w -# --------------------------------------------------------------------------- -# This file is part of reSID, a MOS6581 SID emulator engine. -# Copyright (C) 2004 Dag Lem -# -# 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 -# --------------------------------------------------------------------------- - -use strict; - -die("Usage: samp2src name data-in src-out\n") unless @ARGV == 3; -my ($name, $in, $out) = @ARGV; - -open(F, "<$in") or die($!); -local $/ = undef; -my $data = ; -close(F) or die($!); - -open(F, ">$out") or die($!); - -print F <<\EOF; -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -EOF - -print F "#include \"wave.h\"\n\nreg8 WaveformGeneratorFP::$name\[\] =\n{\n"; - -for (my $i = 0; $i < length($data); $i += 8) { - print F sprintf("/* 0x%03x: */ ", $i), map(sprintf(" 0x%02x,", $_), unpack("C*", substr($data, $i, 8))), "\n"; -} - -print F "};\n"; - -close(F) or die($!); - -exit(0); diff --git a/src - Cópia/sound/resid-fp/sid.cc b/src - Cópia/sound/resid-fp/sid.cc deleted file mode 100644 index eda01ab2f..000000000 --- a/src - Cópia/sound/resid-fp/sid.cc +++ /dev/null @@ -1,944 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "sid.h" -#include -#include - -extern float convolve(const float *a, const float *b, int n); -extern float convolve_sse(const float *a, const float *b, int n); - -enum host_cpu_feature { - HOST_CPU_MMX=1, HOST_CPU_SSE=2, HOST_CPU_SSE2=4, HOST_CPU_SSE3=8 -}; - -/* This code is appropriate for 32-bit and 64-bit x86 CPUs. */ -#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) - -struct cpu_x86_regs_s { - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; -}; -typedef struct cpu_x86_regs_s cpu_x86_regs_t; - -static cpu_x86_regs_t get_cpuid_regs(unsigned int index) -{ - cpu_x86_regs_t retval; - -#if defined(_MSC_VER) /* MSVC assembly */ - __asm { - mov eax, [index] - cpuid - mov [retval.eax], eax - mov [retval.ebx], ebx - mov [retval.ecx], ecx - mov [retval.edx], edx - } -#else /* GNU assembly */ - asm("movl %1, %%eax; cpuid; movl %%eax, %0;" - : "=m" (retval.eax) - : "r" (index) - : "eax", "ebx", "ecx", "edx"); - asm("movl %1, %%eax; cpuid; movl %%ebx, %0;" - : "=m" (retval.ebx) - : "r" (index) - : "eax", "ebx", "ecx", "edx"); - asm("movl %1, %%eax; cpuid; movl %%ecx, %0;" - : "=m" (retval.ecx) - : "r" (index) - : "eax", "ebx", "ecx", "edx"); - asm("movl %1, %%eax; cpuid; movl %%edx, %0;" - : "=m" (retval.edx) - : "r" (index) - : "eax", "ebx", "ecx", "edx"); -#endif - - return retval; -} - -static int host_cpu_features_by_cpuid(void) -{ - cpu_x86_regs_t regs = get_cpuid_regs(1); - - int features = 0; - if (regs.edx & (1 << 23)) - features |= HOST_CPU_MMX; - if (regs.edx & (1 << 25)) - features |= HOST_CPU_SSE; - if (regs.edx & (1 << 26)) - features |= HOST_CPU_SSE2; - if (regs.ecx & (1 << 0)) - features |= HOST_CPU_SSE3; - - return features; -} - -static int host_cpu_features(void) -{ - static int features = 0; - static int features_detected = 0; -/* 32-bit only */ -#if defined(__i386__) || (defined(_MSC_VER) && defined(_WIN32)) - unsigned long temp1, temp2; -#endif - - if (features_detected) - return features; - features_detected = 1; - -#if defined(_MSC_VER) && defined(_WIN32) /* MSVC compatible assembly appropriate for 32-bit Windows */ - /* see if we are dealing with a cpu that has the cpuid instruction */ - __asm { - pushf - pop eax - mov [temp1], eax - xor eax, 0x200000 - push eax - popf - pushf - pop eax - mov [temp2], eax - push [temp1] - popf - } -#endif -#if defined(__i386__) /* GNU assembly */ - asm("pushfl; popl %%eax; movl %%eax, %0; xorl $0x200000, %%eax; pushl %%eax; popfl; pushfl; popl %%eax; movl %%eax, %1; pushl %0; popfl " - : "=r" (temp1), - "=r" (temp2) - : - : "eax"); -#endif -#if defined(__i386__) || (defined(_MSC_VER) && defined(_WIN32)) - temp1 &= 0x200000; - temp2 &= 0x200000; - if (temp1 == temp2) { - /* no cpuid support, so we can't test for SSE availability -> false */ - return 0; - } -#endif - - /* find the highest supported cpuid function, returned in %eax */ - if (get_cpuid_regs(0).eax < 1) { - /* no cpuid 1 function, we can't test for features -> no features */ - return 0; - } - - features = host_cpu_features_by_cpuid(); - return features; -} - -#else /* !__x86_64__ && !__i386__ && !_MSC_VER */ -static int host_cpu_features(void) -{ - return 0; -} -#endif - -float SIDFP::kinked_dac(const int x, const float nonlinearity, const int max) -{ - float value = 0.f; - - int bit = 1; - float weight = 1.f; - const float dir = 2.0f * nonlinearity; - for (int i = 0; i < max; i ++) { - if (x & bit) - value += weight; - bit <<= 1; - weight *= dir; - } - - return value / (weight / nonlinearity) * (1 << max); -} - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -SIDFP::SIDFP() -{ -#if (RESID_USE_SSE==1) - can_use_sse = (host_cpu_features() & HOST_CPU_SSE) != 0; -#else - can_use_sse = false; -#endif - - // Initialize pointers. - sample = 0; - fir = 0; - - voice[0].set_sync_source(&voice[2]); - voice[1].set_sync_source(&voice[0]); - voice[2].set_sync_source(&voice[1]); - - set_sampling_parameters(985248, SAMPLE_INTERPOLATE, 44100); - - bus_value = 0; - bus_value_ttl = 0; - - input(0); -} - - -// ---------------------------------------------------------------------------- -// Destructor. -// ---------------------------------------------------------------------------- -SIDFP::~SIDFP() -{ - delete[] sample; - delete[] fir; -} - - -// ---------------------------------------------------------------------------- -// Set chip model. -// ---------------------------------------------------------------------------- -void SIDFP::set_chip_model(chip_model model) -{ - for (int i = 0; i < 3; i++) { - voice[i].set_chip_model(model); - } - - filter.set_chip_model(model); - extfilt.set_chip_model(model); -} - -/* nonlinear DAC support, set 1 for 8580 / no effect, about 0.96 otherwise */ -void SIDFP::set_voice_nonlinearity(float nl) -{ - for (int i = 0; i < 3; i++) { - voice[i].set_nonlinearity(nl); - } -} - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void SIDFP::reset() -{ - for (int i = 0; i < 3; i++) { - voice[i].reset(); - } - filter.reset(); - extfilt.reset(); - - bus_value = 0; - bus_value_ttl = 0; -} - - -// ---------------------------------------------------------------------------- -// Write 16-bit sample to audio input. -// NB! The caller is responsible for keeping the value within 16 bits. -// Note that to mix in an external audio signal, the signal should be -// resampled to 1MHz first to avoid sampling noise. -// ---------------------------------------------------------------------------- -void SIDFP::input(int sample) -{ - // Voice outputs are 20 bits. Scale up to match three voices in order - // to facilitate simulation of the MOS8580 "digi boost" hardware hack. - ext_in = (float) ( (sample << 4) * 3 ); -} - -float SIDFP::output() -{ - const float range = 1 << 15; - return extfilt.output() / (4095.f * 255.f * 3.f * 1.5f / range); -} - -// ---------------------------------------------------------------------------- -// Read registers. -// -// Reading a write only register returns the last byte written to any SID -// register. The individual bits in this value start to fade down towards -// zero after a few cycles. All bits reach zero within approximately -// $2000 - $4000 cycles. -// It has been claimed that this fading happens in an orderly fashion, however -// sampling of write only registers reveals that this is not the case. -// NB! This is not correctly modeled. -// The actual use of write only registers has largely been made in the belief -// that all SID registers are readable. To support this belief the read -// would have to be done immediately after a write to the same register -// (remember that an intermediate write to another register would yield that -// value instead). With this in mind we return the last value written to -// any SID register for $2000 cycles without modeling the bit fading. -// ---------------------------------------------------------------------------- -reg8 SIDFP::read(reg8 offset) -{ - switch (offset) { - case 0x19: - return potx.readPOT(); - case 0x1a: - return poty.readPOT(); - case 0x1b: - return voice[2].wave.readOSC(); - case 0x1c: - return voice[2].envelope.readENV(); - default: - return bus_value; - } -} - - -// ---------------------------------------------------------------------------- -// Write registers. -// ---------------------------------------------------------------------------- -void SIDFP::write(reg8 offset, reg8 value) -{ - bus_value = value; - bus_value_ttl = 0x4000; - - switch (offset) { - case 0x00: - voice[0].wave.writeFREQ_LO(value); - break; - case 0x01: - voice[0].wave.writeFREQ_HI(value); - break; - case 0x02: - voice[0].wave.writePW_LO(value); - break; - case 0x03: - voice[0].wave.writePW_HI(value); - break; - case 0x04: - voice[0].writeCONTROL_REG(value); - break; - case 0x05: - voice[0].envelope.writeATTACK_DECAY(value); - break; - case 0x06: - voice[0].envelope.writeSUSTAIN_RELEASE(value); - break; - case 0x07: - voice[1].wave.writeFREQ_LO(value); - break; - case 0x08: - voice[1].wave.writeFREQ_HI(value); - break; - case 0x09: - voice[1].wave.writePW_LO(value); - break; - case 0x0a: - voice[1].wave.writePW_HI(value); - break; - case 0x0b: - voice[1].writeCONTROL_REG(value); - break; - case 0x0c: - voice[1].envelope.writeATTACK_DECAY(value); - break; - case 0x0d: - voice[1].envelope.writeSUSTAIN_RELEASE(value); - break; - case 0x0e: - voice[2].wave.writeFREQ_LO(value); - break; - case 0x0f: - voice[2].wave.writeFREQ_HI(value); - break; - case 0x10: - voice[2].wave.writePW_LO(value); - break; - case 0x11: - voice[2].wave.writePW_HI(value); - break; - case 0x12: - voice[2].writeCONTROL_REG(value); - break; - case 0x13: - voice[2].envelope.writeATTACK_DECAY(value); - break; - case 0x14: - voice[2].envelope.writeSUSTAIN_RELEASE(value); - break; - case 0x15: - filter.writeFC_LO(value); - break; - case 0x16: - filter.writeFC_HI(value); - break; - case 0x17: - filter.writeRES_FILT(value); - break; - case 0x18: - filter.writeMODE_VOL(value); - break; - default: - break; - } -} - - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -SIDFP::State::State() -{ - int i; - - for (i = 0; i < 0x20; i++) { - sid_register[i] = 0; - } - - bus_value = 0; - bus_value_ttl = 0; - - for (i = 0; i < 3; i++) { - accumulator[i] = 0; - shift_register[i] = 0x7ffff8; - rate_counter[i] = 0; - rate_counter_period[i] = 9; - exponential_counter[i] = 0; - exponential_counter_period[i] = 1; - envelope_counter[i] = 0; - envelope_state[i] = EnvelopeGeneratorFP::RELEASE; - hold_zero[i] = true; - } -} - - -// ---------------------------------------------------------------------------- -// Read state. -// ---------------------------------------------------------------------------- -SIDFP::State SIDFP::read_state() -{ - State state; - int i, j; - - for (i = 0, j = 0; i < 3; i++, j += 7) { - WaveformGeneratorFP& wave = voice[i].wave; - EnvelopeGeneratorFP& envelope = voice[i].envelope; - state.sid_register[j + 0] = wave.freq & 0xff; - state.sid_register[j + 1] = wave.freq >> 8; - state.sid_register[j + 2] = wave.pw & 0xff; - state.sid_register[j + 3] = wave.pw >> 8; - state.sid_register[j + 4] = - (wave.waveform << 4) - | (wave.test ? 0x08 : 0) - | (wave.ring_mod ? 0x04 : 0) - | (wave.sync ? 0x02 : 0) - | (envelope.gate ? 0x01 : 0); - state.sid_register[j + 5] = (envelope.attack << 4) | envelope.decay; - state.sid_register[j + 6] = (envelope.sustain << 4) | envelope.release; - } - - state.sid_register[j++] = filter.fc & 0x007; - state.sid_register[j++] = filter.fc >> 3; - state.sid_register[j++] = (filter.res << 4) | filter.filt; - state.sid_register[j++] = - (filter.voice3off ? 0x80 : 0) - | (filter.hp_bp_lp << 4) - | filter.vol; - - // These registers are superfluous, but included for completeness. - for (; j < 0x1d; j++) { - state.sid_register[j] = read(j); - } - for (; j < 0x20; j++) { - state.sid_register[j] = 0; - } - - state.bus_value = bus_value; - state.bus_value_ttl = bus_value_ttl; - - for (i = 0; i < 3; i++) { - state.accumulator[i] = voice[i].wave.accumulator; - state.shift_register[i] = voice[i].wave.shift_register; - state.rate_counter[i] = voice[i].envelope.rate_counter; - state.rate_counter_period[i] = voice[i].envelope.rate_period; - state.exponential_counter[i] = voice[i].envelope.exponential_counter; - state.exponential_counter_period[i] = voice[i].envelope.exponential_counter_period; - state.envelope_counter[i] = voice[i].envelope.envelope_counter; - state.envelope_state[i] = voice[i].envelope.state; - state.hold_zero[i] = voice[i].envelope.hold_zero; - } - - return state; -} - - -// ---------------------------------------------------------------------------- -// Write state. -// ---------------------------------------------------------------------------- -void SIDFP::write_state(const State& state) -{ - int i; - - for (i = 0; i <= 0x18; i++) { - write(i, state.sid_register[i]); - } - - bus_value = state.bus_value; - bus_value_ttl = state.bus_value_ttl; - - for (i = 0; i < 3; i++) { - voice[i].wave.accumulator = state.accumulator[i]; - voice[i].wave.shift_register = state.shift_register[i]; - voice[i].envelope.rate_counter = state.rate_counter[i]; - voice[i].envelope.rate_period = state.rate_counter_period[i]; - voice[i].envelope.exponential_counter = state.exponential_counter[i]; - voice[i].envelope.exponential_counter_period = state.exponential_counter_period[i]; - voice[i].envelope.envelope_counter = state.envelope_counter[i]; - voice[i].envelope.state = state.envelope_state[i]; - voice[i].envelope.hold_zero = state.hold_zero[i]; - } -} - - -// ---------------------------------------------------------------------------- -// Enable filter. -// ---------------------------------------------------------------------------- -void SIDFP::enable_filter(bool enable) -{ - filter.enable_filter(enable); -} - - -// ---------------------------------------------------------------------------- -// Enable external filter. -// ---------------------------------------------------------------------------- -void SIDFP::enable_external_filter(bool enable) -{ - extfilt.enable_filter(enable); -} - - -// ---------------------------------------------------------------------------- -// I0() computes the 0th order modified Bessel function of the first kind. -// This function is originally from resample-1.5/filterkit.c by J. O. Smith. -// ---------------------------------------------------------------------------- -double SIDFP::I0(double x) -{ - // Max error acceptable in I0 could be 1e-6, which gives that 96 dB already. - // I'm overspecify these errors to get a beautiful FFT dump of the FIR. - const double I0e = 1e-10; - - double sum, u, halfx, temp; - int n; - - sum = u = n = 1; - halfx = x/2.0; - - do { - temp = halfx/n++; - u *= temp*temp; - sum += u; - } while (u >= I0e*sum); - - return sum; -} - - -// ---------------------------------------------------------------------------- -// Setting of SID sampling parameters. -// -// Use a clock freqency of 985248Hz for PAL C64, 1022730Hz for NTSC C64. -// The default end of passband frequency is pass_freq = 0.9*sample_freq/2 -// for sample frequencies up to ~ 44.1kHz, and 20kHz for higher sample -// frequencies. -// -// For resampling, the ratio between the clock frequency and the sample -// frequency is limited as follows: -// 125*clock_freq/sample_freq < 16384 -// E.g. provided a clock frequency of ~ 1MHz, the sample frequency can not -// be set lower than ~ 8kHz. A lower sample frequency would make the -// resampling code overfill its 16k sample ring buffer. -// -// The end of passband frequency is also limited: -// pass_freq <= 0.9*sample_freq/2 - -// E.g. for a 44.1kHz sampling rate the end of passband frequency is limited -// to slightly below 20kHz. This constraint ensures that the FIR table is -// not overfilled. -// ---------------------------------------------------------------------------- -bool SIDFP::set_sampling_parameters(float clock_freq, sampling_method method, - float sample_freq, float pass_freq) -{ - clock_frequency = clock_freq; - sampling = method; - - filter.set_clock_frequency(clock_freq); - extfilt.set_clock_frequency(clock_freq); - adjust_sampling_frequency(sample_freq); - - sample_offset = 0; - sample_prev = 0; - - // FIR initialization is only necessary for resampling. - if (method != SAMPLE_RESAMPLE_INTERPOLATE) - { - delete[] sample; - delete[] fir; - sample = 0; - fir = 0; - return true; - } - - const int bits = 16; - - if (pass_freq > 20000) - pass_freq = 20000; - if (2*pass_freq/sample_freq > 0.9) - pass_freq = 0.9f*sample_freq/2; - - // 16 bits -> -96dB stopband attenuation. - const double A = -20*log10(1.0/(1 << bits)); - - // For calculation of beta and N see the reference for the kaiserord - // function in the MATLAB Signal Processing Toolbox: - // http://www.mathworks.com/access/helpdesk/help/toolbox/signal/kaiserord.html - const double beta = 0.1102*(A - 8.7); - const double I0beta = I0(beta); - - double f_samples_per_cycle = sample_freq/clock_freq; - double f_cycles_per_sample = clock_freq/sample_freq; - - /* This code utilizes the fact that aliasing back to 20 kHz from - * sample_freq/2 is inaudible. This allows us to define a passband - * wider than normally. We might also consider aliasing back to pass_freq, - * but as this can be less than 20 kHz, it might become audible... */ - double aliasing_allowance = sample_freq / 2 - 20000; - if (aliasing_allowance < 0) - aliasing_allowance = 0; - - double transition_bandwidth = sample_freq/2 - pass_freq + aliasing_allowance; - { - /* Filter order according to Kaiser's paper. */ - - int N = (int) ((A - 7.95)/(2 * M_PI * 2.285 * transition_bandwidth/sample_freq) + 0.5); - N += N & 1; - - // The filter length is equal to the filter order + 1. - // The filter length must be an odd number (sinc is symmetric about x = 0). - fir_N = int(N*f_cycles_per_sample) + 1; - fir_N |= 1; - - // Check whether the sample ring buffer would overfill. - if (fir_N > RINGSIZE - 1) - return false; - - /* Error is bound by 1.234 / L^2 */ - fir_RES = (int) (sqrt(1.234 * (1 << bits)) / f_cycles_per_sample + 0.5); - } - - // Allocate memory for FIR tables. - delete[] fir; - fir = new float[fir_N*fir_RES]; - - // The cutoff frequency is midway through the transition band. - double wc = (pass_freq + transition_bandwidth/2) / sample_freq * M_PI * 2; - - // Calculate fir_RES FIR tables for linear interpolation. - for (int i = 0; i < fir_RES; i++) { - double j_offset = double(i)/fir_RES; - // Calculate FIR table. This is the sinc function, weighted by the - // Kaiser window. - for (int j = 0; j < fir_N; j ++) { - double jx = j - fir_N/2. - j_offset; - double wt = wc*jx/f_cycles_per_sample; - double temp = jx/(fir_N/2); - double Kaiser = - fabs(temp) <= 1 ? I0(beta*sqrt(1 - temp*temp))/I0beta : 0; - double sincwt = - fabs(wt) >= 1e-8 ? sin(wt)/wt : 1; - fir[i * fir_N + j] = (float) (f_samples_per_cycle*wc/M_PI*sincwt*Kaiser); - } - } - - // Allocate sample buffer. - if (!sample) { - sample = new float[RINGSIZE*2]; - } - // Clear sample buffer. - for (int j = 0; j < RINGSIZE*2; j++) { - sample[j] = 0; - } - sample_index = 0; - - return true; -} - -// ---------------------------------------------------------------------------- -// Adjustment of SID sampling frequency. -// -// In some applications, e.g. a C64 emulator, it can be desirable to -// synchronize sound with a timer source. This is supported by adjustment of -// the SID sampling frequency. -// -// NB! Adjustment of the sampling frequency may lead to noticeable shifts in -// frequency, and should only be used for interactive applications. Note also -// that any adjustment of the sampling frequency will change the -// characteristics of the resampling filter, since the filter is not rebuilt. -// ---------------------------------------------------------------------------- -void SIDFP::adjust_sampling_frequency(float sample_freq) -{ - cycles_per_sample = clock_frequency/sample_freq; -} - -void SIDFP::age_bus_value(cycle_count n) { - if (bus_value_ttl != 0) { - bus_value_ttl -= n; - if (bus_value_ttl <= 0) { - bus_value = 0; - bus_value_ttl = 0; - } - } -} - -// ---------------------------------------------------------------------------- -// SID clocking - 1 cycle. -// ---------------------------------------------------------------------------- -void SIDFP::clock() -{ - int i; - - // Clock amplitude modulators. - for (i = 0; i < 3; i++) { - voice[i].envelope.clock(); - } - - // Clock oscillators. - for (i = 0; i < 3; i++) { - voice[i].wave.clock(); - } - - // Synchronize oscillators. - for (i = 0; i < 3; i++) { - voice[i].wave.synchronize(); - } - - // Clock filter. - extfilt.clock(filter.clock(voice[0].output(), voice[1].output(), voice[2].output(), ext_in)); -} - -// ---------------------------------------------------------------------------- -// SID clocking with audio sampling. -// Fixpoint arithmetics is used. -// -// The example below shows how to clock the SID a specified amount of cycles -// while producing audio output: -// -// while (delta_t) { -// bufindex += sid.clock(delta_t, buf + bufindex, buflength - bufindex); -// write(dsp, buf, bufindex*2); -// bufindex = 0; -// } -// -// ---------------------------------------------------------------------------- -int SIDFP::clock(cycle_count& delta_t, short* buf, int n, int interleave) -{ - /* XXX I assume n is generally large enough for delta_t here... */ - age_bus_value(delta_t); - int res; - switch (sampling) { - default: - case SAMPLE_INTERPOLATE: - res = clock_interpolate(delta_t, buf, n, interleave); - break; - case SAMPLE_RESAMPLE_INTERPOLATE: - res = clock_resample_interpolate(delta_t, buf, n, interleave); - break; - } - - filter.nuke_denormals(); - extfilt.nuke_denormals(); - - return res; -} - -// ---------------------------------------------------------------------------- -// SID clocking with audio sampling - cycle based with linear sample -// interpolation. -// -// Here the chip is clocked every cycle. This yields higher quality -// sound since the samples are linearly interpolated, and since the -// external filter attenuates frequencies above 16kHz, thus reducing -// sampling noise. -// ---------------------------------------------------------------------------- -RESID_INLINE -int SIDFP::clock_interpolate(cycle_count& delta_t, short* buf, int n, - int interleave) -{ - int s = 0; - int i; - - for (;;) { - float next_sample_offset = sample_offset + cycles_per_sample; - int delta_t_sample = (int) next_sample_offset; - if (delta_t_sample > delta_t) { - break; - } - if (s >= n) { - return s; - } - for (i = 0; i < delta_t_sample - 1; i++) { - clock(); - } - if (i < delta_t_sample) { - sample_prev = output(); - clock(); - } - - delta_t -= delta_t_sample; - sample_offset = next_sample_offset - delta_t_sample; - - float sample_now = output(); - int v = (int)(sample_prev + (sample_offset * (sample_now - sample_prev))); - // Saturated arithmetics to guard against 16 bit sample overflow. - const int half = 1 << 15; - if (v >= half) { - v = half - 1; - } - else if (v < -half) { - v = -half; - } - buf[s++*interleave] = v; - sample_prev = sample_now; - } - - for (i = 0; i < delta_t - 1; i++) { - clock(); - } - if (i < delta_t) { - sample_prev = output(); - clock(); - } - sample_offset -= delta_t; - delta_t = 0; - return s; -} - -// ---------------------------------------------------------------------------- -// SID clocking with audio sampling - cycle based with audio resampling. -// -// This is the theoretically correct (and computationally intensive) audio -// sample generation. The samples are generated by resampling to the specified -// sampling frequency. The work rate is inversely proportional to the -// percentage of the bandwidth allocated to the filter transition band. -// -// This implementation is based on the paper "A Flexible Sampling-Rate -// Conversion Method", by J. O. Smith and P. Gosset, or rather on the -// expanded tutorial on the "Digital Audio Resampling Home Page": -// http://www-ccrma.stanford.edu/~jos/resample/ -// -// By building shifted FIR tables with samples according to the -// sampling frequency, this implementation dramatically reduces the -// computational effort in the filter convolutions, without any loss -// of accuracy. The filter convolutions are also vectorizable on -// current hardware. -// -// Further possible optimizations are: -// * An equiripple filter design could yield a lower filter order, see -// http://www.mwrf.com/Articles/ArticleID/7229/7229.html -// * The Convolution Theorem could be used to bring the complexity of -// convolution down from O(n*n) to O(n*log(n)) using the Fast Fourier -// Transform, see http://en.wikipedia.org/wiki/Convolution_theorem -// * Simply resampling in two steps can also yield computational -// savings, since the transition band will be wider in the first step -// and the required filter order is thus lower in this step. -// Laurent Ganier has found the optimal intermediate sampling frequency -// to be (via derivation of sum of two steps): -// 2 * pass_freq + sqrt [ 2 * pass_freq * orig_sample_freq -// * (dest_sample_freq - 2 * pass_freq) / dest_sample_freq ] -// -// NB! the result of right shifting negative numbers is really -// implementation dependent in the C++ standard. -// ---------------------------------------------------------------------------- -RESID_INLINE -int SIDFP::clock_resample_interpolate(cycle_count& delta_t, short* buf, int n, - int interleave) -{ - int s = 0; - - for (;;) { - float next_sample_offset = sample_offset + cycles_per_sample; - /* full clocks left to next sample */ - int delta_t_sample = (int) next_sample_offset; - if (delta_t_sample > delta_t || s >= n) - break; - - /* clock forward delta_t_sample samples */ - for (int i = 0; i < delta_t_sample; i++) { - clock(); - sample[sample_index] = sample[sample_index + RINGSIZE] = output(); - ++ sample_index; - sample_index &= RINGSIZE - 1; - } - delta_t -= delta_t_sample; - - /* Phase of the sample in terms of clock, [0 .. 1[. */ - sample_offset = next_sample_offset - (float) delta_t_sample; - - /* find the first of the nearest fir tables close to the phase */ - float fir_offset_rmd = sample_offset * fir_RES; - int fir_offset = (int) fir_offset_rmd; - /* [0 .. 1[ */ - fir_offset_rmd -= (float) fir_offset; - - /* find fir_N most recent samples, plus one extra in case the FIR wraps. */ - float* sample_start = sample + sample_index - fir_N + RINGSIZE - 1; - - float v1 = -#if (RESID_USE_SSE==1) - can_use_sse ? convolve_sse(sample_start, fir + fir_offset*fir_N, fir_N) : -#endif - convolve(sample_start, fir + fir_offset*fir_N, fir_N); - - // Use next FIR table, wrap around to first FIR table using - // previous sample. - if (++ fir_offset == fir_RES) { - fir_offset = 0; - ++ sample_start; - } - float v2 = -#if (RESID_USE_SSE==1) - can_use_sse ? convolve_sse(sample_start, fir + fir_offset*fir_N, fir_N) : -#endif - convolve(sample_start, fir + fir_offset*fir_N, fir_N); - - // Linear interpolation between the sinc tables yields good approximation - // for the exact value. - int v = (int) (v1 + fir_offset_rmd * (v2 - v1)); - - // Saturated arithmetics to guard against 16 bit sample overflow. - const int half = 1 << 15; - if (v >= half) { - v = half - 1; - } - else if (v < -half) { - v = -half; - } - - buf[s ++ * interleave] = v; - } - - /* clock forward delta_t samples */ - for (int i = 0; i < delta_t; i++) { - clock(); - sample[sample_index] = sample[sample_index + RINGSIZE] = output(); - ++ sample_index; - sample_index &= RINGSIZE - 1; - } - sample_offset -= (float) delta_t; - delta_t = 0; - return s; -} diff --git a/src - Cópia/sound/resid-fp/sid.h b/src - Cópia/sound/resid-fp/sid.h deleted file mode 100644 index 6dad2e0c4..000000000 --- a/src - Cópia/sound/resid-fp/sid.h +++ /dev/null @@ -1,130 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __SID_FP_H__ -#define __SID_FP_H__ - -#include "siddefs-fp.h" -#include "voice.h" -#include "filter.h" -#include "extfilt.h" -#include "pot.h" - -class SIDFP -{ -public: - SIDFP(); - ~SIDFP(); - - static float kinked_dac(const int x, const float nonlinearity, const int bits); - bool sse_enabled() { return can_use_sse; } - - void set_chip_model(chip_model model); - FilterFP& get_filter() { return filter; } - void enable_filter(bool enable); - void enable_external_filter(bool enable); - bool set_sampling_parameters(float clock_freq, sampling_method method, - float sample_freq, float pass_freq = -1); - void adjust_sampling_frequency(float sample_freq); - void set_voice_nonlinearity(float nonlinearity); - - void clock(); - int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1); - void reset(); - - // Read/write registers. - reg8 read(reg8 offset); - void write(reg8 offset, reg8 value); - - // Read/write state. - class State - { - public: - State(); - - char sid_register[0x20]; - - reg8 bus_value; - cycle_count bus_value_ttl; - - reg24 accumulator[3]; - reg24 shift_register[3]; - reg16 rate_counter[3]; - reg16 rate_counter_period[3]; - reg16 exponential_counter[3]; - reg16 exponential_counter_period[3]; - reg8 envelope_counter[3]; - EnvelopeGeneratorFP::State envelope_state[3]; - bool hold_zero[3]; - }; - - State read_state(); - void write_state(const State& state); - - // 16-bit input (EXT IN). - void input(int sample); - - // output in range -32768 .. 32767, not clipped (AUDIO OUT) - float output(); - -protected: - static double I0(double x); - RESID_INLINE int clock_interpolate(cycle_count& delta_t, short* buf, int n, - int interleave); - RESID_INLINE int clock_resample_interpolate(cycle_count& delta_t, short* buf, - int n, int interleave); - RESID_INLINE void age_bus_value(cycle_count); - - VoiceFP voice[3]; - FilterFP filter; - ExternalFilterFP extfilt; - PotentiometerFP potx; - PotentiometerFP poty; - - reg8 bus_value; - cycle_count bus_value_ttl; - - float clock_frequency; - - // External audio input. - float ext_in; - - enum { RINGSIZE = 16384 }; - - // Sampling variables. - sampling_method sampling; - float cycles_per_sample; - float sample_offset; - int sample_index; - int fir_N; - int fir_RES; - - // Linear interpolation helper - float sample_prev; - - // Ring buffer with overflow for contiguous storage of RINGSIZE samples. - float* sample; - - // FIR_RES filter tables (FIR_N*FIR_RES). - float* fir; - - bool can_use_sse; -}; - -#endif // not __SID_H__ diff --git a/src - Cópia/sound/resid-fp/siddefs-fp.h b/src - Cópia/sound/resid-fp/siddefs-fp.h deleted file mode 100644 index 1f3f72715..000000000 --- a/src - Cópia/sound/resid-fp/siddefs-fp.h +++ /dev/null @@ -1,88 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 1999 Dag Lem -// -// 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 __SIDDEFS_FP_H__ -#define __SIDDEFS_FP_H__ - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#define M_PI_f 3.14159265358979323846f -#else -#define M_PI_f ((float) M_PI) -#endif - -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 -#define M_LN2_f 0.69314718055994530942f -#else -#define M_LN2_f ((float) M_LN2) -#endif - -// Define bool, true, and false for C++ compilers that lack these keywords. -#define RESID_HAVE_BOOL 1 - -#if !RESID_HAVE_BOOL -typedef int bool; -const bool true = 1; -const bool false = 0; -#endif - -// We could have used the smallest possible data type for each SID register, -// however this would give a slower engine because of data type conversions. -// An int is assumed to be at least 32 bits (necessary in the types reg24, -// cycle_count, and sound_sample). GNU does not support 16-bit machines -// (GNU Coding Standards: Portability between CPUs), so this should be -// a valid assumption. - -typedef unsigned int reg4; -typedef unsigned int reg8; -typedef unsigned int reg12; -typedef unsigned int reg16; -typedef unsigned int reg24; - -typedef int cycle_count; - -enum chip_model { MOS6581FP=1, MOS8580FP }; - -enum sampling_method { SAMPLE_INTERPOLATE=1, SAMPLE_RESAMPLE_INTERPOLATE }; - -extern "C" -{ -#ifndef __VERSION_CC__ -extern const char* resid_version_string; -#else -const char* resid_version_string = VERSION; -#endif -} - -// Inlining on/off. -#define RESID_INLINE inline - -#if defined(__SSE__) || (defined(_MSC_VER) && (_MSC_VER >= 1300)) -#define RESID_USE_SSE 1 -#else -#define RESID_USE_SSE 0 -#endif - -#define HAVE_LOGF -#define HAVE_EXPF -#define HAVE_LOGF_PROTOTYPE -#define HAVE_EXPF_PROTOTYPE - -#endif // not __SIDDEFS_H__ diff --git a/src - Cópia/sound/resid-fp/siddefs-fp.h.in b/src - Cópia/sound/resid-fp/siddefs-fp.h.in deleted file mode 100644 index ec44b3619..000000000 --- a/src - Cópia/sound/resid-fp/siddefs-fp.h.in +++ /dev/null @@ -1,87 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 1999 Dag Lem -// -// 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 __SIDDEFS_FP_H__ -#define __SIDDEFS_FP_H__ - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#define M_PI_f 3.14159265358979323846f -#else -#define M_PI_f ((float) M_PI) -#endif - -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 -#define M_LN2_f 0.69314718055994530942f -#else -#define M_LN2_f ((float) M_LN2) -#endif - -// Define bool, true, and false for C++ compilers that lack these keywords. -#define RESID_HAVE_BOOL @RESID_HAVE_BOOL@ - -#if !RESID_HAVE_BOOL -typedef int bool; -const bool true = 1; -const bool false = 0; -#endif - -// We could have used the smallest possible data type for each SID register, -// however this would give a slower engine because of data type conversions. -// An int is assumed to be at least 32 bits (necessary in the types reg24, -// cycle_count, and sound_sample). GNU does not support 16-bit machines -// (GNU Coding Standards: Portability between CPUs), so this should be -// a valid assumption. - -typedef unsigned int reg4; -typedef unsigned int reg8; -typedef unsigned int reg12; -typedef unsigned int reg16; -typedef unsigned int reg24; - -typedef int cycle_count; - -enum chip_model { MOS6581FP=1, MOS8580FP }; - -enum sampling_method { SAMPLE_INTERPOLATE=1, SAMPLE_RESAMPLE_INTERPOLATE }; - -extern "C" -{ -#ifndef __VERSION_CC__ -extern const char* resid_version_string; -#else -const char* resid_version_string = VERSION; -#endif -} - -// Inlining on/off. -#define RESID_INLINE @RESID_INLINE@ - -#define RESID_USE_SSE @RESID_USE_SSE@ - -#if @HAVE_LOGF_PROTOTYPE@ -#define HAVE_LOGF_PROTOTYPE -#endif - -#if @HAVE_EXPF_PROTOTYPE@ -#define HAVE_EXPF_PROTOTYPE -#endif - -#endif // not __SIDDEFS_H__ diff --git a/src - Cópia/sound/resid-fp/version.cc b/src - Cópia/sound/resid-fp/version.cc deleted file mode 100644 index fe9d4595f..000000000 --- a/src - Cópia/sound/resid-fp/version.cc +++ /dev/null @@ -1,21 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#define __VERSION_CC__ -#include "siddefs-fp.h" diff --git a/src - Cópia/sound/resid-fp/voice.cc b/src - Cópia/sound/resid-fp/voice.cc deleted file mode 100644 index 18c36cc71..000000000 --- a/src - Cópia/sound/resid-fp/voice.cc +++ /dev/null @@ -1,102 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#define __VOICE_CC__ -#include "voice.h" -#include "sid.h" - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -VoiceFP::VoiceFP() -{ - nonlinearity = 1.f; - set_chip_model(MOS6581FP); -} - -/* Keep this at 1.f for 8580, there are no 6581-only codepaths in this file! */ -void VoiceFP::set_nonlinearity(float nl) -{ - nonlinearity = nl; - calculate_dac_tables(); -} - -// ---------------------------------------------------------------------------- -// Set chip model. -// ---------------------------------------------------------------------------- -void VoiceFP::set_chip_model(chip_model model) -{ - wave.set_chip_model(model); - - if (model == MOS6581FP) { - /* there is some level from each voice even if the env is down and osc - * is stopped. You can hear this by routing a voice into filter (filter - * should be kept disabled for this) as the master level changes. This - * tunable affects the volume of digis. */ - voice_DC = 0x800 * 0xff; - /* In 8580 the waveforms seem well centered, but on the 6581 there is some - * offset change as envelope grows, indicating that the waveforms are not - * perfectly centered. I estimate the value ~ 0x600 for my R4AR, and ReSID - * has used another measurement technique and got 0x380. */ - wave_zero = 0x600; - calculate_dac_tables(); - } - else { - /* 8580 is thought to be perfect, apart from small negative offset due to - * ext-in mixing, I think. */ - voice_DC = 0; - wave_zero = 0x800; - calculate_dac_tables(); - } -} - -void VoiceFP::calculate_dac_tables() -{ - int i; - for (i = 0; i < 256; i ++) - env_dac[i] = SIDFP::kinked_dac(i, nonlinearity, 8); - for (i = 0; i < 4096; i ++) - voice_dac[i] = SIDFP::kinked_dac(i, nonlinearity, 12) - wave_zero; -} - -// ---------------------------------------------------------------------------- -// Set sync source. -// ---------------------------------------------------------------------------- -void VoiceFP::set_sync_source(VoiceFP* source) -{ - wave.set_sync_source(&source->wave); -} - -// ---------------------------------------------------------------------------- -// Register functions. -// ---------------------------------------------------------------------------- -void VoiceFP::writeCONTROL_REG(reg8 control) -{ - wave.writeCONTROL_REG(control); - envelope.writeCONTROL_REG(control); -} - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void VoiceFP::reset() -{ - wave.reset(); - envelope.reset(); -} diff --git a/src - Cópia/sound/resid-fp/voice.h b/src - Cópia/sound/resid-fp/voice.h deleted file mode 100644 index 3a9e3fc95..000000000 --- a/src - Cópia/sound/resid-fp/voice.h +++ /dev/null @@ -1,73 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __VOICE_H__ -#define __VOICE_H__ - -#include "siddefs-fp.h" -#include "wave.h" -#include "envelope.h" - -class VoiceFP -{ -public: - VoiceFP(); - - void set_chip_model(chip_model model); - void set_sync_source(VoiceFP*); - void reset(); - - void writeCONTROL_REG(reg8); - - // Amplitude modulated waveform output. - // Range [-2048*255, 2047*255]. - RESID_INLINE float output(); - - void set_nonlinearity(float nl); -protected: - void calculate_dac_tables(); - - WaveformGeneratorFP wave; - EnvelopeGeneratorFP envelope; - - // Multiplying D/A DC offset. - float voice_DC, wave_zero, nonlinearity; - - float env_dac[256]; - float voice_dac[4096]; -friend class SIDFP; -}; - -// ---------------------------------------------------------------------------- -// Amplitude modulated waveform output. -// Ideal range [-2048*255, 2047*255]. -// ---------------------------------------------------------------------------- - -RESID_INLINE -float VoiceFP::output() -{ - unsigned int w = wave.output(); - unsigned int e = envelope.output(); - float _w = voice_dac[w]; - float _e = env_dac[e]; - - return _w * _e + voice_DC; -} - -#endif // not __VOICE_H__ diff --git a/src - Cópia/sound/resid-fp/wave.cc b/src - Cópia/sound/resid-fp/wave.cc deleted file mode 100644 index 018c4e2be..000000000 --- a/src - Cópia/sound/resid-fp/wave.cc +++ /dev/null @@ -1,151 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#define __WAVE_CC__ -#include "wave.h" - -// ---------------------------------------------------------------------------- -// Constructor. -// ---------------------------------------------------------------------------- -WaveformGeneratorFP::WaveformGeneratorFP() -{ - sync_source = this; - - set_chip_model(MOS6581FP); - - reset(); -} - - -// ---------------------------------------------------------------------------- -// Set sync source. -// ---------------------------------------------------------------------------- -void WaveformGeneratorFP::set_sync_source(WaveformGeneratorFP* source) -{ - sync_source = source; - source->sync_dest = this; -} - - -// ---------------------------------------------------------------------------- -// Set chip model. -// ---------------------------------------------------------------------------- -void WaveformGeneratorFP::set_chip_model(chip_model model) -{ - if (model == MOS6581FP) { - wave__ST = wave6581__ST; - wave_P_T = wave6581_P_T; - wave_PS_ = wave6581_PS_; - wave_PST = wave6581_PST; - } - else { - wave__ST = wave8580__ST; - wave_P_T = wave8580_P_T; - wave_PS_ = wave8580_PS_; - wave_PST = wave8580_PST; - } -} - - -// ---------------------------------------------------------------------------- -// Register functions. -// ---------------------------------------------------------------------------- -void WaveformGeneratorFP::writeFREQ_LO(reg8 freq_lo) -{ - freq = (freq & 0xff00) | (freq_lo & 0x00ff); -} - -void WaveformGeneratorFP::writeFREQ_HI(reg8 freq_hi) -{ - freq = ((freq_hi << 8) & 0xff00) | (freq & 0x00ff); -} - -/* The original form was (acc >> 12) >= pw, where truth value is not affected - * by the contents of the low 12 bits. Therefore the lowest bits must be zero - * in the new formulation acc >= (pw << 12). */ -void WaveformGeneratorFP::writePW_LO(reg8 pw_lo) -{ - pw = (pw & 0xf00) | (pw_lo & 0x0ff); - pw_acc_scale = pw << 12; -} - -void WaveformGeneratorFP::writePW_HI(reg8 pw_hi) -{ - pw = ((pw_hi << 8) & 0xf00) | (pw & 0x0ff); - pw_acc_scale = pw << 12; -} - -void WaveformGeneratorFP::writeCONTROL_REG(reg8 control) -{ - waveform = (control >> 4) & 0x0f; - ring_mod = control & 0x04; - sync = control & 0x02; - - reg8 test_next = control & 0x08; - - /* SounDemoN found out that test bit can be used to control the noise - * register. Hear the result in Bojojoing.sid. */ - - // testbit set. invert bit 19 and write it to bit 1 - if (test_next && !test) { - accumulator = 0; - reg24 bit19 = (shift_register >> 19) & 1; - shift_register = (shift_register & 0x7ffffd) | ((bit19^1) << 1); - noise_overwrite_delay = 200000; /* 200 ms, probably too generous? */ - } - // Test bit cleared. - // The accumulator starts counting, and the shift register is reset to - // the value 0x7ffff8. - else if (!test_next && test) { - reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1; - shift_register <<= 1; - shift_register |= bit0; - } - // clear output bits of shift register if noise and other waveforms - // are selected simultaneously - if (waveform > 8) { - shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2); - } - - test = test_next; - - /* update noise anyway, just in case the above paths triggered */ - noise_output_cached = outputN___(); -} - -reg8 WaveformGeneratorFP::readOSC() -{ - return output() >> 4; -} - -// ---------------------------------------------------------------------------- -// SID reset. -// ---------------------------------------------------------------------------- -void WaveformGeneratorFP::reset() -{ - accumulator = 0; - previous = 0; - shift_register = 0x7ffffc; - freq = 0; - pw = 0; - pw_acc_scale = 0; - test = 0; - writeCONTROL_REG(0); - msb_rising = false; -} diff --git a/src - Cópia/sound/resid-fp/wave.h b/src - Cópia/sound/resid-fp/wave.h deleted file mode 100644 index 07d229ba0..000000000 --- a/src - Cópia/sound/resid-fp/wave.h +++ /dev/null @@ -1,457 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 __WAVE_H__ -#define __WAVE_H__ - -#include "siddefs-fp.h" - -// ---------------------------------------------------------------------------- -// A 24 bit accumulator is the basis for waveform generation. FREQ is added to -// the lower 16 bits of the accumulator each cycle. -// The accumulator is set to zero when TEST is set, and starts counting -// when TEST is cleared. -// The noise waveform is taken from intermediate bits of a 23 bit shift -// register. This register is clocked by bit 19 of the accumulator. -// ---------------------------------------------------------------------------- -class WaveformGeneratorFP -{ -public: - WaveformGeneratorFP(); - - void set_sync_source(WaveformGeneratorFP*); - void set_chip_model(chip_model model); - - RESID_INLINE void clock(); - RESID_INLINE void synchronize(); - void reset(); - - void writeFREQ_LO(reg8); - void writeFREQ_HI(reg8); - void writePW_LO(reg8); - void writePW_HI(reg8); - void writeCONTROL_REG(reg8); - reg8 readOSC(); - - // 12-bit waveform output. - RESID_INLINE reg12 output(); - -protected: - const WaveformGeneratorFP* sync_source; - WaveformGeneratorFP* sync_dest; - - // Tell whether the accumulator MSB was set high on this cycle. - bool msb_rising; - - reg24 accumulator; - reg24 shift_register; - reg12 previous, noise_output_cached; - int noise_overwrite_delay; - - // Fout = (Fn*Fclk/16777216)Hz - reg16 freq; - // PWout = (PWn/40.95)%, also the same << 12 for direct comparison against acc - reg12 pw; reg24 pw_acc_scale; - - // The control register right-shifted 4 bits; used for output function - // table lookup. - reg8 waveform; - - // The remaining control register bits. - reg8 test; - reg8 ring_mod; - reg8 sync; - // The gate bit is handled by the EnvelopeGenerator. - - // 16 possible combinations of waveforms. - RESID_INLINE reg12 output___T(); - RESID_INLINE reg12 output__S_(); - RESID_INLINE reg12 output__ST(); - RESID_INLINE reg12 output_P__(); - RESID_INLINE reg12 output_P_T(); - RESID_INLINE reg12 output_PS_(); - RESID_INLINE reg12 output_PST(); - RESID_INLINE reg12 outputN___(); - RESID_INLINE reg12 outputN__T(); - RESID_INLINE reg12 outputN_S_(); - RESID_INLINE reg12 outputN_ST(); - RESID_INLINE reg12 outputNP__(); - RESID_INLINE reg12 outputNP_T(); - RESID_INLINE reg12 outputNPS_(); - RESID_INLINE reg12 outputNPST(); - - // Sample data for combinations of waveforms. - static reg8 wave6581__ST[]; - static reg8 wave6581_P_T[]; - static reg8 wave6581_PS_[]; - static reg8 wave6581_PST[]; - - static reg8 wave8580__ST[]; - static reg8 wave8580_P_T[]; - static reg8 wave8580_PS_[]; - static reg8 wave8580_PST[]; - - reg8* wave__ST; - reg8* wave_P_T; - reg8* wave_PS_; - reg8* wave_PST; - -friend class VoiceFP; -friend class SIDFP; -}; - -// ---------------------------------------------------------------------------- -// SID clocking - 1 cycle. -// ---------------------------------------------------------------------------- -RESID_INLINE -void WaveformGeneratorFP::clock() -{ - /* no digital operation if test bit is set. Only emulate analog fade. */ - if (test) { - if (noise_overwrite_delay != 0) { - if (-- noise_overwrite_delay == 0) { - shift_register |= 0x7ffffc; - noise_output_cached = outputN___(); - } - } - return; - } - - reg24 accumulator_prev = accumulator; - - // Calculate new accumulator value; - accumulator += freq; - accumulator &= 0xffffff; - - // Check whether the MSB became set high. This is used for synchronization. - msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000); - - // Shift noise register once for each time accumulator bit 19 is set high. - if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) { - reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1; - shift_register <<= 1; - // optimization: fall into the bit bucket - //shift_register &= 0x7fffff; - shift_register |= bit0; - - /* since noise changes relatively infrequently, we'll avoid the relatively - * expensive bit shuffling at output time. */ - noise_output_cached = outputN___(); - } - - // clear output bits of shift register if noise and other waveforms - // are selected simultaneously - if (waveform > 8) { - shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2); - noise_output_cached = outputN___(); - } -} - -// ---------------------------------------------------------------------------- -// Synchronize oscillators. -// This must be done after all the oscillators have been clock()'ed since the -// oscillators operate in parallel. -// Note that the oscillators must be clocked exactly on the cycle when the -// MSB is set high for hard sync to operate correctly. See SID::clock(). -// ---------------------------------------------------------------------------- -RESID_INLINE -void WaveformGeneratorFP::synchronize() -{ - // A special case occurs when a sync source is synced itself on the same - // cycle as when its MSB is set high. In this case the destination will - // not be synced. This has been verified by sampling OSC3. - if (msb_rising && sync_dest->sync && !(sync && sync_source->msb_rising)) { - sync_dest->accumulator = 0; - } -} - - -// ---------------------------------------------------------------------------- -// Output functions. -// NB! The output from SID 8580 is delayed one cycle compared to SID 6581, -// this is not modeled. -// ---------------------------------------------------------------------------- - -// Triangle: -// The upper 12 bits of the accumulator are used. -// The MSB is used to create the falling edge of the triangle by inverting -// the lower 11 bits. The MSB is thrown away and the lower 11 bits are -// left-shifted (half the resolution, full amplitude). -// Ring modulation substitutes the MSB with MSB EOR sync_source MSB. -// -RESID_INLINE -reg12 WaveformGeneratorFP::output___T() -{ - reg24 msb = (ring_mod ? accumulator ^ sync_source->accumulator : accumulator) - & 0x800000; - return ((msb ? ~accumulator : accumulator) >> 11) & 0xfff; -} - -// Sawtooth: -// The output is identical to the upper 12 bits of the accumulator. -// -RESID_INLINE -reg12 WaveformGeneratorFP::output__S_() -{ - return accumulator >> 12; -} - -// Pulse: -// The upper 12 bits of the accumulator are used. -// These bits are compared to the pulse width register by a 12 bit digital -// comparator; output is either all one or all zero bits. -// NB! The output is actually delayed one cycle after the compare. -// This is not modeled. -// -// The test bit, when set to one, holds the pulse waveform output at 0xfff -// regardless of the pulse width setting. -// -RESID_INLINE -reg12 WaveformGeneratorFP::output_P__() -{ - return (test || accumulator >= pw_acc_scale) ? 0xfff : 0x000; -} - -// Noise: -// The noise output is taken from intermediate bits of a 23-bit shift register -// which is clocked by bit 19 of the accumulator. -// NB! The output is actually delayed 2 cycles after bit 19 is set high. -// This is not modeled. -// -// Operation: Calculate EOR result, shift register, set bit 0 = result. -// -// ----------------------->--------------------- -// | | -// ----EOR---- | -// | | | -// 2 2 2 1 1 1 1 1 1 1 1 1 1 | -// Register bits: 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 <--- -// | | | | | | | | -// OSC3 bits : 7 6 5 4 3 2 1 0 -// -// Since waveform output is 12 bits the output is left-shifted 4 times. -// -RESID_INLINE -reg12 WaveformGeneratorFP::outputN___() -{ - return - ((shift_register & 0x400000) >> 11) | - ((shift_register & 0x100000) >> 10) | - ((shift_register & 0x010000) >> 7) | - ((shift_register & 0x002000) >> 5) | - ((shift_register & 0x000800) >> 4) | - ((shift_register & 0x000080) >> 1) | - ((shift_register & 0x000010) << 1) | - ((shift_register & 0x000004) << 2); -} - -// Combined waveforms: -// By combining waveforms, the bits of each waveform are effectively short -// circuited. A zero bit in one waveform will result in a zero output bit -// (thus the infamous claim that the waveforms are AND'ed). -// However, a zero bit in one waveform will also affect the neighboring bits -// in the output. The reason for this has not been determined. -// -// Example: -// -// 1 1 -// Bit # 1 0 9 8 7 6 5 4 3 2 1 0 -// ----------------------- -// Sawtooth 0 0 0 1 1 1 1 1 1 0 0 0 -// -// Triangle 0 0 1 1 1 1 1 1 0 0 0 0 -// -// AND 0 0 0 1 1 1 1 1 0 0 0 0 -// -// Output 0 0 0 0 1 1 1 0 0 0 0 0 -// -// -// This behavior would be quite difficult to model exactly, since the SID -// in this case does not act as a digital state machine. Tests show that minor -// (1 bit) differences can actually occur in the output from otherwise -// identical samples from OSC3 when waveforms are combined. To further -// complicate the situation the output changes slightly with time (more -// neighboring bits are successively set) when the 12-bit waveform -// registers are kept unchanged. -// -// It is probably possible to come up with a valid model for the -// behavior, however this would be far too slow for practical use since it -// would have to be based on the mutual influence of individual bits. -// -// The output is instead approximated by using the upper bits of the -// accumulator as an index to look up the combined output in a table -// containing actual combined waveform samples from OSC3. -// These samples are 8 bit, so 4 bits of waveform resolution is lost. -// All OSC3 samples are taken with FREQ=0x1000, adding a 1 to the upper 12 -// bits of the accumulator each cycle for a sample period of 4096 cycles. -// -// Sawtooth+Triangle: -// The sawtooth output is used to look up an OSC3 sample. -// -// Pulse+Triangle: -// The triangle output is right-shifted and used to look up an OSC3 sample. -// The sample is output if the pulse output is on. -// The reason for using the triangle output as the index is to handle ring -// modulation. Only the first half of the sample is used, which should be OK -// since the triangle waveform has half the resolution of the accumulator. -// -// Pulse+Sawtooth: -// The sawtooth output is used to look up an OSC3 sample. -// The sample is output if the pulse output is on. -// -// Pulse+Sawtooth+Triangle: -// The sawtooth output is used to look up an OSC3 sample. -// The sample is output if the pulse output is on. -// -RESID_INLINE -reg12 WaveformGeneratorFP::output__ST() -{ - return wave__ST[output__S_()] << 4; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::output_P_T() -{ - /* ring modulation does something odd with this waveform. But I don't know - * how to emulate it. */ - return (wave_P_T[output___T() >> 1] << 4) & output_P__(); -} - -RESID_INLINE -reg12 WaveformGeneratorFP::output_PS_() -{ - return (wave_PS_[output__S_()] << 4) & output_P__(); -} - -RESID_INLINE -reg12 WaveformGeneratorFP::output_PST() -{ - return (wave_PST[output__S_()] << 4) & output_P__(); -} - -// Combined waveforms including noise: -// All waveform combinations including noise output zero after a few cycles. -// NB! The effects of such combinations are not fully explored. It is claimed -// that the shift register may be filled with zeroes and locked up, which -// seems to be true. -// We have not attempted to model this behavior, suffice to say that -// there is very little audible output from waveform combinations including -// noise. We hope that nobody is actually using it. -// -RESID_INLINE -reg12 WaveformGeneratorFP::outputN__T() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputN_S_() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputN_ST() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputNP__() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputNP_T() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputNPS_() -{ - return 0; -} - -RESID_INLINE -reg12 WaveformGeneratorFP::outputNPST() -{ - return 0; -} - -// ---------------------------------------------------------------------------- -// Select one of 16 possible combinations of waveforms. -// ---------------------------------------------------------------------------- -RESID_INLINE -reg12 WaveformGeneratorFP::output() -{ - switch (waveform) { - case 0x1: - previous = output___T(); - break; - case 0x2: - previous = output__S_(); - break; - case 0x3: - previous = output__ST(); - break; - case 0x4: - previous = output_P__(); - break; - case 0x5: - previous = output_P_T(); - break; - case 0x6: - previous = output_PS_(); - break; - case 0x7: - previous = output_PST(); - break; - case 0x8: - previous = noise_output_cached; - break; - case 0x9: - previous = outputN__T(); - break; - case 0xa: - previous = outputN_S_(); - break; - case 0xb: - previous = outputN_ST(); - break; - case 0xc: - previous = outputNP__(); - break; - case 0xd: - previous = outputNP_T(); - break; - case 0xe: - previous = outputNPS_(); - break; - case 0xf: - previous = outputNPST(); - break; - default: - break; - } - return previous; -} - -#endif // not __WAVE_H__ diff --git a/src - Cópia/sound/resid-fp/wave6581_PST.cc b/src - Cópia/sound/resid-fp/wave6581_PST.cc deleted file mode 100644 index 19d2126ef..000000000 --- a/src - Cópia/sound/resid-fp/wave6581_PST.cc +++ /dev/null @@ -1,536 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave6581_PST[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -/* 0x7f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, -/* 0x7f8: */ 0x00, 0x00, 0x00, 0x78, 0x78, 0x7e, 0x7f, 0x7f, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -/* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, -/* 0xff8: */ 0x00, 0x00, 0x00, 0x78, 0x78, 0x7e, 0x7f, 0x7f, -}; diff --git a/src - Cópia/sound/resid-fp/wave6581_PST.dat b/src - Cópia/sound/resid-fp/wave6581_PST.dat deleted file mode 100644 index 5afe75e22e10a8f0ea80f90eade17858e9123946..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz7zLvtFd70QGz9ENsJ}$^&>G5M*Tb*0;3@S4uR47 Te>5SChQP=P0R^a6;q^ZN_wxn! diff --git a/src - Cópia/sound/resid-fp/wave6581_PS_.cc b/src - Cópia/sound/resid-fp/wave6581_PS_.cc deleted file mode 100644 index bf133e542..000000000 --- a/src - Cópia/sound/resid-fp/wave6581_PS_.cc +++ /dev/null @@ -1,536 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave6581_PS_[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, -/* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3f, -/* 0x3f8: */ 0x00, 0x30, 0x38, 0x3f, 0x3e, 0x3f, 0x3f, 0x3f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5f, -/* 0x5f8: */ 0x00, 0x40, 0x40, 0x5f, 0x5c, 0x5f, 0x5f, 0x5f, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6b, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x6d, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x6e, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x6f, -/* 0x6f8: */ 0x00, 0x60, 0x60, 0x6f, 0x60, 0x6f, 0x6f, 0x6f, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x738: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x60, 0x73, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x758: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x75, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x768: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x76, -/* 0x770: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x77, -/* 0x778: */ 0x00, 0x70, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x798: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x79, -/* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x7a8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x70, 0x70, 0x7a, -/* 0x7b0: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7b, -/* 0x7b8: */ 0x40, 0x70, 0x70, 0x7b, 0x78, 0x7b, 0x7b, 0x7b, -/* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, -/* 0x7c8: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7c, -/* 0x7d0: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7d, -/* 0x7d8: */ 0x40, 0x70, 0x78, 0x7d, 0x78, 0x7d, 0x7d, 0x7d, -/* 0x7e0: */ 0x00, 0x40, 0x40, 0x78, 0x60, 0x78, 0x78, 0x7e, -/* 0x7e8: */ 0x60, 0x78, 0x78, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, -/* 0x7f0: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7e, 0x7f, 0x7f, 0x7f, -/* 0x7f8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, -/* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, -/* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3f, -/* 0xbf8: */ 0x00, 0x30, 0x38, 0x3f, 0x3e, 0x3f, 0x3f, 0x3f, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, -/* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5f, -/* 0xdf8: */ 0x00, 0x40, 0x40, 0x5f, 0x5c, 0x5f, 0x5f, 0x5f, -/* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, -/* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6b, -/* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6d, -/* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xee8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x6e, -/* 0xef0: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x6f, -/* 0xef8: */ 0x00, 0x60, 0x60, 0x6f, 0x60, 0x6f, 0x6f, 0x6f, -/* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xf38: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x60, 0x73, -/* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0xf58: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x75, -/* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0xf68: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x76, -/* 0xf70: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x77, -/* 0xf78: */ 0x00, 0x70, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, -/* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0xf98: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x79, -/* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0xfa8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x70, 0x70, 0x7a, -/* 0xfb0: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7b, -/* 0xfb8: */ 0x40, 0x70, 0x70, 0x7b, 0x78, 0x7b, 0x7b, 0x7b, -/* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, -/* 0xfc8: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7c, -/* 0xfd0: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7d, -/* 0xfd8: */ 0x40, 0x70, 0x78, 0x7d, 0x78, 0x7d, 0x7d, 0x7d, -/* 0xfe0: */ 0x00, 0x40, 0x40, 0x78, 0x60, 0x78, 0x78, 0x7e, -/* 0xfe8: */ 0x60, 0x78, 0x78, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, -/* 0xff0: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7c, 0x7f, 0x7f, 0x7f, -/* 0xff8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, -}; diff --git a/src - Cópia/sound/resid-fp/wave6581_PS_.dat b/src - Cópia/sound/resid-fp/wave6581_PS_.dat deleted file mode 100644 index ea2fb9c5397c69f7cfcb23df61182876a599071f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHIyG{c!5HwKm8GHiiKtja(2b2^6yd4FCTM2trK=1x~R_Qp6{%=H}+c z>xbkq=BS_Z1F!x}*;tvNUY;2xZFmA-HKtZN7_O+Ub^=)efP=C>6h4u%Vd zVG#X4fJ)f#f;=9+H+94h(UB3k=ck}IM4r6&qHh4@rC|C0>lY_lGAH(qz!k=E6rJRI zEXY~{3Mr(Nc+CMr$faV=nPQysG_8tZ692J6&;P@oy!QU@`QJXjp8xIr>G|K@pIxiF P&41JL|F8UyKl1+@yytY^ diff --git a/src - Cópia/sound/resid-fp/wave6581_P_T.cc b/src - Cópia/sound/resid-fp/wave6581_P_T.cc deleted file mode 100644 index 30736169e..000000000 --- a/src - Cópia/sound/resid-fp/wave6581_P_T.cc +++ /dev/null @@ -1,536 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave6581_P_T[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, 0x3f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x5f, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x378: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x6f, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x70, 0x77, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7b, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, -/* 0x3e8: */ 0x00, 0x40, 0x40, 0x70, 0x60, 0x70, 0x78, 0x7d, -/* 0x3f0: */ 0x00, 0x40, 0x60, 0x78, 0x60, 0x78, 0x78, 0x7e, -/* 0x3f8: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7e, 0x7f, 0x7f, 0x7f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x9f, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x578: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0xa0, 0xa0, 0xaf, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, -/* 0x5b8: */ 0x00, 0x80, 0x80, 0xa0, 0x80, 0xa0, 0xb0, 0xb7, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, -/* 0x5d8: */ 0x00, 0x80, 0x80, 0xa0, 0x80, 0xb0, 0xb0, 0xbb, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xb0, -/* 0x5e8: */ 0x80, 0x80, 0x80, 0xb0, 0x80, 0xb0, 0xb8, 0xbd, -/* 0x5f0: */ 0x80, 0x80, 0x80, 0xb8, 0xa0, 0xb8, 0xb8, 0xbe, -/* 0x5f8: */ 0xa0, 0xb8, 0xbc, 0xbf, 0xbe, 0xbf, 0xbf, 0xbf, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, -/* 0x670: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, -/* 0x678: */ 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x698: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0xc0, 0xc0, -/* 0x6b8: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd7, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, -/* 0x6d0: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, -/* 0x6d8: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd0, 0xdb, -/* 0x6e0: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xd0, -/* 0x6e8: */ 0x80, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd8, 0xdd, -/* 0x6f0: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd8, 0xd8, 0xde, -/* 0x6f8: */ 0xc0, 0xd8, 0xdc, 0xdf, 0xdc, 0xdf, 0xdf, 0xdf, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x718: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xe0, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x728: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, -/* 0x730: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, -/* 0x738: */ 0x80, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe7, -/* 0x740: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, -/* 0x748: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, -/* 0x750: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, -/* 0x758: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xeb, -/* 0x760: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0x768: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xed, -/* 0x770: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, 0xe8, 0xee, -/* 0x778: */ 0xe0, 0xe8, 0xec, 0xef, 0xec, 0xef, 0xef, 0xef, -/* 0x780: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0x788: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, -/* 0x790: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, -/* 0x798: */ 0xc0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf3, -/* 0x7a0: */ 0x80, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xf0, -/* 0x7a8: */ 0xc0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf5, -/* 0x7b0: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf6, -/* 0x7b8: */ 0xf0, 0xf0, 0xf4, 0xf7, 0xf4, 0xf7, 0xf7, 0xf7, -/* 0x7c0: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, -/* 0x7c8: */ 0xe0, 0xe0, 0xe0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf9, -/* 0x7d0: */ 0xe0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xfa, -/* 0x7d8: */ 0xf0, 0xf8, 0xf8, 0xfb, 0xf8, 0xfb, 0xfb, 0xfb, -/* 0x7e0: */ 0xe0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xfc, 0xfc, -/* 0x7e8: */ 0xf8, 0xfc, 0xfc, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, -/* 0x7f0: */ 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, -/* 0x7f8: */ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -/* 0x800: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, -/* 0x808: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, -/* 0x810: */ 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfc, 0xfc, 0xf8, -/* 0x818: */ 0xfc, 0xfc, 0xfc, 0xf0, 0xf8, 0xf0, 0xf0, 0xe0, -/* 0x820: */ 0xfb, 0xfb, 0xfb, 0xf8, 0xfb, 0xf8, 0xf8, 0xf0, -/* 0x828: */ 0xfa, 0xf8, 0xf8, 0xf0, 0xf8, 0xf0, 0xf0, 0xe0, -/* 0x830: */ 0xf9, 0xf8, 0xf8, 0xf0, 0xf8, 0xf0, 0xe0, 0xe0, -/* 0x838: */ 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, -/* 0x840: */ 0xf7, 0xf7, 0xf7, 0xf4, 0xf7, 0xf4, 0xf0, 0xf0, -/* 0x848: */ 0xf6, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, -/* 0x850: */ 0xf5, 0xf0, 0xf0, 0xe0, 0xf0, 0xe0, 0xe0, 0xc0, -/* 0x858: */ 0xf0, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xc0, 0x80, -/* 0x860: */ 0xf3, 0xf0, 0xf0, 0xe0, 0xf0, 0xe0, 0xe0, 0xc0, -/* 0x868: */ 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, -/* 0x870: */ 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, -/* 0x878: */ 0xc0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0x880: */ 0xef, 0xef, 0xef, 0xec, 0xef, 0xec, 0xe8, 0xe0, -/* 0x888: */ 0xee, 0xe8, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, -/* 0x890: */ 0xed, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, -/* 0x898: */ 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, -/* 0x8a0: */ 0xeb, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, -/* 0x8a8: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x8b0: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x8b8: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x8c0: */ 0xe7, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xc0, 0x80, -/* 0x8c8: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x8d0: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x8d8: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0xe0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x900: */ 0xdf, 0xdf, 0xdf, 0xdc, 0xdf, 0xdc, 0xd8, 0xc0, -/* 0x908: */ 0xde, 0xd8, 0xd8, 0xc0, 0xd8, 0xc0, 0xc0, 0xc0, -/* 0x910: */ 0xdd, 0xd8, 0xd0, 0xc0, 0xd0, 0xc0, 0xc0, 0x80, -/* 0x918: */ 0xd0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x920: */ 0xdb, 0xd0, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, -/* 0x928: */ 0xc0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, -/* 0x930: */ 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0x938: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x940: */ 0xd7, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, -/* 0x948: */ 0xc0, 0xc0, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x950: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x958: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x968: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x980: */ 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, -/* 0x988: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x990: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c0: */ 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa00: */ 0xbf, 0xbf, 0xbf, 0xbe, 0xbf, 0xbc, 0xbc, 0xa0, -/* 0xa08: */ 0xbe, 0xbc, 0xb8, 0xa0, 0xb8, 0xa0, 0x80, 0x80, -/* 0xa10: */ 0xbd, 0xb8, 0xb0, 0x80, 0xb0, 0x80, 0x80, 0x80, -/* 0xa18: */ 0xb0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0xa20: */ 0xbb, 0xb0, 0xb0, 0x80, 0xa0, 0x80, 0x80, 0x00, -/* 0xa28: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xa30: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0xb7, 0xb0, 0xa0, 0x80, 0xa0, 0x80, 0x80, 0x00, -/* 0xa48: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa80: */ 0xaf, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x00, -/* 0xa88: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb00: */ 0x9f, 0x90, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb80: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc00: */ 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7c, 0x7c, 0x70, -/* 0xc08: */ 0x7e, 0x7c, 0x78, 0x60, 0x78, 0x60, 0x60, 0x00, -/* 0xc10: */ 0x7d, 0x78, 0x78, 0x60, 0x70, 0x40, 0x40, 0x00, -/* 0xc18: */ 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x7b, 0x78, 0x70, 0x40, 0x70, 0x40, 0x00, 0x00, -/* 0xc28: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x77, 0x70, 0x70, 0x00, 0x60, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc80: */ 0x6f, 0x60, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd00: */ 0x5f, 0x58, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe00: */ 0x3f, 0x3c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xff8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; diff --git a/src - Cópia/sound/resid-fp/wave6581_P_T.dat b/src - Cópia/sound/resid-fp/wave6581_P_T.dat deleted file mode 100644 index 1cc8874da796bf210ffddb17d0382a86763bcc81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHJ%TC)s6!oX{6T0l868?j z)Ey^E*a2`IlPj8=y5rJpkD|jr>ctkk>m6$ujXnyPg7G`U$c%mmv@Lg8g|1Wj1ANJ&R~|^ z>+E)PI~tA59?q`nasyiDsLOSpKY+8>@h6QK_9M?9$B*Ojn6sIK7kN=ULnXezC&gqk zsd!lyWjQUU(`ixutnAmE*<@Lu1cfXwF(}sYts^%Jf@ zMTagQY8>SoioXeZ=gL&mhD7_Xt4 zE)mzQLF -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave6581__ST[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, -/* 0x3f8: */ 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x3f, 0x3f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0x7e8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0x7f0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, -/* 0x7f8: */ 0x3e, 0x3e, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, -/* 0xbf8: */ 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x3f, 0x3f, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, -/* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0xfe8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0xff0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, -/* 0xff8: */ 0x3e, 0x3e, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, -}; diff --git a/src - Cópia/sound/resid-fp/wave6581__ST.dat b/src - Cópia/sound/resid-fp/wave6581__ST.dat deleted file mode 100644 index 2e5d9872c4c49b4edaa126cdad13263d54bd916b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH}F%Ezr3`H>xZh8SD*I+R8XkOhKnMeqR7sEi`X!0rTkNr5;lX-^KC!${zqE{`d z?_9tBS7lRR|4`nq|L5W(`oAX*#d{HGAe5W`aDdJGC;k5()`xQQ9}ckUf5 -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave8580_PST[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, -/* 0x7f0: */ 0x60, 0x20, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, -/* 0x7f8: */ 0x78, 0x78, 0x7c, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x3f, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xdf8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8c, 0x9f, -/* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe80: */ 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, -/* 0xe88: */ 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xea0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xea8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xeb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xeb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xec0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xec8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xed0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xed8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xee0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xee8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, -/* 0xef0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xef8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, -/* 0xf00: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf08: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf10: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf18: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf20: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf28: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf30: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf38: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf40: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf48: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf50: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf58: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf68: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0xf70: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, -/* 0xf80: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf88: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf90: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf98: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xfa0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xfa8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xfb0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, -/* 0xfb8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfc0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfc8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfd0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfd8: */ 0xf0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfe0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfe8: */ 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0xff0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, -/* 0xff8: */ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; diff --git a/src - Cópia/sound/resid-fp/wave8580_PST.dat b/src - Cópia/sound/resid-fp/wave8580_PST.dat deleted file mode 100644 index 22706cf250b5c0e602bdd8db33b83aed623b1c82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz7zLvtFd70QGz8>FsJ}h diff --git a/src - Cópia/sound/resid-fp/wave8580_PS_.cc b/src - Cópia/sound/resid-fp/wave8580_PS_.cc deleted file mode 100644 index e33a2cee5..000000000 --- a/src - Cópia/sound/resid-fp/wave8580_PS_.cc +++ /dev/null @@ -1,536 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave8580_PS_[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x1f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, -/* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, -/* 0x3f8: */ 0x00, 0x0c, 0x1c, 0x3f, 0x1e, 0x3f, 0x3f, 0x3f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, -/* 0x5f8: */ 0x00, 0x00, 0x00, 0x5f, 0x0c, 0x5f, 0x5f, 0x5f, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, -/* 0x6f8: */ 0x00, 0x40, 0x40, 0x6f, 0x40, 0x6f, 0x6f, 0x6f, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x768: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x70, -/* 0x770: */ 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, -/* 0x778: */ 0x40, 0x60, 0x60, 0x77, 0x60, 0x77, 0x77, 0x77, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, -/* 0x798: */ 0x00, 0x40, 0x40, 0x60, 0x40, 0x60, 0x60, 0x79, -/* 0x7a0: */ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, -/* 0x7a8: */ 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x78, -/* 0x7b0: */ 0x40, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, -/* 0x7b8: */ 0x60, 0x70, 0x70, 0x78, 0x70, 0x79, 0x7b, 0x7b, -/* 0x7c0: */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, -/* 0x7c8: */ 0x60, 0x60, 0x60, 0x70, 0x60, 0x70, 0x70, 0x7c, -/* 0x7d0: */ 0x60, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x7c, -/* 0x7d8: */ 0x70, 0x78, 0x78, 0x7c, 0x78, 0x7c, 0x7c, 0x7d, -/* 0x7e0: */ 0x70, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x7c, -/* 0x7e8: */ 0x78, 0x7c, 0x7c, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, -/* 0x7f0: */ 0x7c, 0x7c, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, -/* 0x7f8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8d, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x8e, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x8f, -/* 0x9f8: */ 0x80, 0x80, 0x80, 0x9f, 0x80, 0x9f, 0x9f, 0x9f, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x87, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x83, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, -/* 0xad8: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, -/* 0xae0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xae8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x84, -/* 0xaf0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x87, -/* 0xaf8: */ 0x80, 0x80, 0x80, 0x87, 0x80, 0x8f, 0xaf, 0xaf, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, -/* 0xb28: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83, -/* 0xb40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, -/* 0xb60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, -/* 0xb70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, -/* 0xb78: */ 0x80, 0x80, 0x80, 0xa0, 0x80, 0xa3, 0xb7, 0xb7, -/* 0xb80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb1, -/* 0xba0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xba8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb0, -/* 0xbb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb0, -/* 0xbb8: */ 0x80, 0xa0, 0xa0, 0xb0, 0xa0, 0xb8, 0xb9, 0xbb, -/* 0xbc0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, -/* 0xbc8: */ 0x80, 0x80, 0x80, 0xa0, 0x80, 0xa0, 0xa0, 0xb8, -/* 0xbd0: */ 0x80, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xb8, -/* 0xbd8: */ 0xa0, 0xb0, 0xb0, 0xb8, 0xb0, 0xbc, 0xbc, 0xbd, -/* 0xbe0: */ 0xa0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb8, 0xb8, 0xbc, -/* 0xbe8: */ 0xb0, 0xb8, 0xb8, 0xbc, 0xb8, 0xbc, 0xbe, 0xbe, -/* 0xbf0: */ 0xb8, 0xbc, 0xbc, 0xbe, 0xbc, 0xbe, 0xbe, 0xbf, -/* 0xbf8: */ 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, -/* 0xc10: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc18: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc28: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, -/* 0xc40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc7, -/* 0xc80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xc98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xca0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xca8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xcb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xcb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc3, -/* 0xcc0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xcc8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xcd0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xcd8: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc1, -/* 0xce0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xce8: */ 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xcf0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc7, -/* 0xcf8: */ 0xc0, 0xc0, 0xc0, 0xc7, 0xc0, 0xcf, 0xcf, 0xcf, -/* 0xd00: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xd08: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xd10: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xd18: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xd20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xd28: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xd30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, -/* 0xd38: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc3, -/* 0xd40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0xd48: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, -/* 0xd50: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd58: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, -/* 0xd60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd68: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd70: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd78: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, 0xc7, 0xd7, -/* 0xd80: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd88: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd90: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xd98: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xda0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xda8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, -/* 0xdb0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, -/* 0xdb8: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd8, 0xdb, -/* 0xdc0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xdc8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, -/* 0xdd0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, -/* 0xdd8: */ 0xc0, 0xc0, 0xc0, 0xd8, 0xd0, 0xd8, 0xd8, 0xdd, -/* 0xde0: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd0, 0xdc, -/* 0xde8: */ 0xd0, 0xd8, 0xd8, 0xdc, 0xd8, 0xdc, 0xdc, 0xde, -/* 0xdf0: */ 0xd8, 0xdc, 0xdc, 0xde, 0xdc, 0xde, 0xde, 0xdf, -/* 0xdf8: */ 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, -/* 0xe00: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe08: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe10: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe18: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe20: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe28: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe30: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe38: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe3, -/* 0xe40: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe48: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xe50: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0xe58: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe1, -/* 0xe60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0xe68: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xe70: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xe78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe3, 0xe7, -/* 0xe80: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0xe88: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, -/* 0xe90: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, -/* 0xe98: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xea0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xea8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xeb0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xeb8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xeb, -/* 0xec0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xec8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xed0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xed8: */ 0xe0, 0xe0, 0xe0, 0xe8, 0xe0, 0xe8, 0xe8, 0xed, -/* 0xee0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xec, -/* 0xee8: */ 0xe0, 0xe0, 0xe0, 0xec, 0xe8, 0xec, 0xec, 0xee, -/* 0xef0: */ 0xe8, 0xe8, 0xe8, 0xec, 0xec, 0xee, 0xee, 0xef, -/* 0xef8: */ 0xec, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, -/* 0xf00: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf08: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf10: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf18: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, -/* 0xf20: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, -/* 0xf28: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0, -/* 0xf30: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf38: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, -/* 0xf40: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf48: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf50: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf58: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf5, -/* 0xf60: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf68: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, 0xf4, 0xf6, -/* 0xf70: */ 0xf0, 0xf0, 0xf0, 0xf4, 0xf0, 0xf4, 0xf6, 0xf7, -/* 0xf78: */ 0xf4, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, -/* 0xf80: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, -/* 0xf88: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0xf8, 0xf8, -/* 0xf90: */ 0xf0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf8, -/* 0xf98: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, -/* 0xfa0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfa8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfa, -/* 0xfb0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, -/* 0xfb8: */ 0xf8, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, -/* 0xfc0: */ 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, 0xfc, 0xfc, 0xfc, -/* 0xfc8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0xfd0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, -/* 0xfd8: */ 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, -/* 0xfe0: */ 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, -/* 0xfe8: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, -/* 0xff0: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -/* 0xff8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; diff --git a/src - Cópia/sound/resid-fp/wave8580_PS_.dat b/src - Cópia/sound/resid-fp/wave8580_PS_.dat deleted file mode 100644 index 9a20a9eee6211222f5b21d98b9223e5aa1b3891c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmc&zO>fgc5Ou{N5>(>I1;GzN5KA2R7sLp0CB7w9O|qy+IYE9xEb#+sPBp@$jyU9) z+^|GQUG;z^LTibTnlz=%tS3#f#5Q3i@}%82Z{Ey)IZ>3g;)>+%8;xHn02tUzfbO?C-xOx&Kaj zKYK|&17-?iuaE(C7!B5FG|2x~TJ`>nHbTbpWZi#SPi@c>0~xNs#QS5OJKSaLITp>~ z1;sVs8msT_^7`4tC`9I^$QZ_or{<@fd9frG_cy5q*<`Qx_DCnu8^N$hTg)^q(|-Go zvqIb3aCWKmM+8PheVb$|RFWykAmXQofyJ z{9WGtAk?{}kzMAxt$FRv(1x(>b~+vMlgJee(k`xznC_2xo?|?HIkhgMWkIX`aalSg z*Ch|R>vp|QLaj#{+3R}V=eVxhgShAQdVL(de*d6<5JTu+RURcY_>lKq-#;XuYaal) z84i!W%=_qpUaXl_FN?k|OHwZIgWwy*1K>e07#s%y&c`Q%lNc%eXoch>hkh7x2AbkK z=2P%v!5a=opoigbbUGZ3P7&lsoTCUi3V{hfrvdSp_$(Ta&k&#|(c}-DL*^VYnfzM7 Gg@E4#k=_;n diff --git a/src - Cópia/sound/resid-fp/wave8580_P_T.cc b/src - Cópia/sound/resid-fp/wave8580_P_T.cc deleted file mode 100644 index 206a91728..000000000 --- a/src - Cópia/sound/resid-fp/wave8580_P_T.cc +++ /dev/null @@ -1,536 +0,0 @@ -// --------------------------------------------------------------------------- -// This file is part of reSID, a MOS6581 SID emulator engine. -// Copyright (C) 2004 Dag Lem -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave8580_P_T[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x3c, 0x3f, 0x3f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5e, 0x5f, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x378: */ 0x00, 0x00, 0x00, 0x40, 0x40, 0x60, 0x60, 0x6f, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x60, -/* 0x3b8: */ 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x70, 0x77, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, -/* 0x3c8: */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, -/* 0x3d0: */ 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x70, -/* 0x3d8: */ 0x60, 0x60, 0x60, 0x70, 0x70, 0x70, 0x78, 0x7b, -/* 0x3e0: */ 0x60, 0x60, 0x60, 0x70, 0x60, 0x70, 0x70, 0x70, -/* 0x3e8: */ 0x70, 0x70, 0x70, 0x78, 0x78, 0x78, 0x78, 0x7c, -/* 0x3f0: */ 0x78, 0x78, 0x78, 0x7c, 0x78, 0x7c, 0x7c, 0x7e, -/* 0x3f8: */ 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x4d8: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x4e8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x4f0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x4f8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8e, 0x9f, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, -/* 0x530: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x538: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x540: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, -/* 0x548: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x550: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x558: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x560: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x568: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x570: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x578: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xaf, -/* 0x580: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x588: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x590: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x598: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x5a0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x5a8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x5b0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x5b8: */ 0x80, 0x80, 0x80, 0xa0, 0xa0, 0xa0, 0xa0, 0xb7, -/* 0x5c0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x5c8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, -/* 0x5d0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, 0xa0, -/* 0x5d8: */ 0xa0, 0xa0, 0xa0, 0xb0, 0xa0, 0xb0, 0xb0, 0xbb, -/* 0x5e0: */ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xb0, 0xb0, -/* 0x5e8: */ 0xa0, 0xb0, 0xb0, 0xb8, 0xb0, 0xb8, 0xb8, 0xbc, -/* 0x5f0: */ 0xb0, 0xb8, 0xb8, 0xb8, 0xb8, 0xbc, 0xbc, 0xbe, -/* 0x5f8: */ 0xbc, 0xbc, 0xbe, 0xbf, 0xbe, 0xbf, 0xbf, 0xbf, -/* 0x600: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x608: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x610: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x618: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x620: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x628: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x630: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x638: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, -/* 0x640: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x648: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x650: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, -/* 0x658: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x660: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, -/* 0x668: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x670: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x678: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, -/* 0x680: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, -/* 0x688: */ 0xc0, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x690: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x698: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6a0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6a8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6b0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6b8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd7, -/* 0x6c0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6c8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6d0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x6d8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd0, 0xd9, -/* 0x6e0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, -/* 0x6e8: */ 0xc0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd8, 0xd8, 0xdc, -/* 0x6f0: */ 0xd0, 0xd0, 0xd8, 0xd8, 0xd8, 0xdc, 0xdc, 0xde, -/* 0x6f8: */ 0xdc, 0xdc, 0xde, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, -/* 0x700: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x708: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x710: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x718: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, -/* 0x720: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, -/* 0x728: */ 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x730: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x738: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe7, -/* 0x740: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x748: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x750: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x758: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, -/* 0x760: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x768: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, 0xec, -/* 0x770: */ 0xe0, 0xe0, 0xe0, 0xe8, 0xe8, 0xe8, 0xec, 0xee, -/* 0x778: */ 0xec, 0xec, 0xec, 0xee, 0xee, 0xef, 0xef, 0xef, -/* 0x780: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x788: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, -/* 0x790: */ 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x798: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x7a0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x7a8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, -/* 0x7b0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, -/* 0x7b8: */ 0xf0, 0xf4, 0xf4, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, -/* 0x7c0: */ 0xf0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf8, -/* 0x7c8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0x7d0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0x7d8: */ 0xf8, 0xf8, 0xf8, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, -/* 0x7e0: */ 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0x7e8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, -/* 0x7f0: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, -/* 0x7f8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -/* 0x800: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -/* 0x808: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, -/* 0x810: */ 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0x818: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf8, -/* 0x820: */ 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xf8, 0xf8, 0xf8, -/* 0x828: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0x830: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0x838: */ 0xf8, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x840: */ 0xf7, 0xf7, 0xf7, 0xf6, 0xf6, 0xf4, 0xf4, 0xf0, -/* 0x848: */ 0xf4, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x850: */ 0xf4, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x858: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x860: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0x868: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, -/* 0x870: */ 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x878: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x880: */ 0xef, 0xef, 0xef, 0xee, 0xee, 0xec, 0xec, 0xe8, -/* 0x888: */ 0xee, 0xec, 0xe8, 0xe8, 0xe8, 0xe0, 0xe0, 0xe0, -/* 0x890: */ 0xec, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x898: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8a0: */ 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8a8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8b0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8b8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8c0: */ 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8c8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0x8d0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, -/* 0x8d8: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x8e0: */ 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x8e8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x8f0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x8f8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x900: */ 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xde, 0xdc, 0xdc, -/* 0x908: */ 0xde, 0xdc, 0xdc, 0xd8, 0xd8, 0xd8, 0xd0, 0xd0, -/* 0x910: */ 0xdc, 0xd8, 0xd8, 0xd0, 0xd0, 0xd0, 0xd0, 0xc0, -/* 0x918: */ 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x920: */ 0xd9, 0xd0, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x928: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x930: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x938: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x940: */ 0xd7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x948: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x950: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x958: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x960: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x968: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x970: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, -/* 0x978: */ 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x980: */ 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x988: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x990: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0x998: */ 0xc0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x80, -/* 0x9a0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, -/* 0x9a8: */ 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9b0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9b8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9c0: */ 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9c8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9d0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9d8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9e0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9e8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9f0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0x9f8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa00: */ 0xbf, 0xbf, 0xbf, 0xbe, 0xbf, 0xbe, 0xbc, 0xbc, -/* 0xa08: */ 0xbe, 0xbc, 0xbc, 0xb8, 0xb8, 0xb8, 0xb8, 0xb0, -/* 0xa10: */ 0xbc, 0xb8, 0xb8, 0xb0, 0xb8, 0xb0, 0xb0, 0xb0, -/* 0xa18: */ 0xb0, 0xb0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, -/* 0xa20: */ 0xbb, 0xb0, 0xb0, 0xa0, 0xb0, 0xa0, 0xa0, 0xa0, -/* 0xa28: */ 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa30: */ 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa40: */ 0xb7, 0xb0, 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, -/* 0xa48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa80: */ 0xaf, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xa98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xaa0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xaa8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xab0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xab8: */ 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xac0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xac8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, -/* 0xad0: */ 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb00: */ 0x9f, 0x9e, 0x88, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb08: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb10: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xb18: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb80: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc00: */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7c, -/* 0xc08: */ 0x7e, 0x7c, 0x7c, 0x78, 0x7c, 0x78, 0x78, 0x78, -/* 0xc10: */ 0x7c, 0x78, 0x78, 0x78, 0x78, 0x70, 0x70, 0x70, -/* 0xc18: */ 0x78, 0x70, 0x70, 0x60, 0x70, 0x60, 0x60, 0x60, -/* 0xc20: */ 0x7b, 0x78, 0x70, 0x70, 0x70, 0x60, 0x60, 0x60, -/* 0xc28: */ 0x70, 0x60, 0x60, 0x60, 0x60, 0x40, 0x40, 0x40, -/* 0xc30: */ 0x60, 0x60, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, -/* 0xc38: */ 0x40, 0x40, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x77, 0x70, 0x60, 0x60, 0x60, 0x60, 0x40, 0x40, -/* 0xc48: */ 0x60, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc80: */ 0x6f, 0x64, 0x60, 0x40, 0x40, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd00: */ 0x5f, 0x5e, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe00: */ 0x3f, 0x3f, 0x3e, 0x00, 0x1c, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf00: */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xff8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; diff --git a/src - Cópia/sound/resid-fp/wave8580_P_T.dat b/src - Cópia/sound/resid-fp/wave8580_P_T.dat deleted file mode 100644 index 5423dd9ac0a80527813e1c85b3b5b60fd0ffe753..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmd^CO-_SA6lUkfBlIZ7asbbuEZmn}O-d?DR~|vRf$VJ3#&QGM*(Qx;CksMZke2jE z{oXKCW+>Q3V@>)6-pu!Y=8x&itD+nKPYnt9^KlS^4DSk)lI3)qlI}ETpyqhXS`JBc>S>Ysx2<$~*GI8A@SGkT03} z&-isb9?Ky)?m3?4agG+Gh_|9j(D(xL`~ckd{U8j2APgsyiC~YS$nzk|5pz=<#qo4H zo6W$JDA|ble6d(0%N$m#)jP+B1g>7fB^R(vFvNVmarlHS1xuJtV=QOAFy7hNu-yq; z#u0=#3_lETEU*Ofi3#3CviSqxYh@p9{Rz23YH$T`5!i*m#c87$_5k -// -// 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 -// --------------------------------------------------------------------------- - -#include "wave.h" - -reg8 WaveformGeneratorFP::wave8580__ST[] = -{ -/* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x1f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, -/* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x3f0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, -/* 0x3f8: */ 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, -/* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x5f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, -/* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x7e0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0x7e8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, -/* 0x7f0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3e, -/* 0x7f8: */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, -/* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x9f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, -/* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xbf0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, -/* 0xbf8: */ 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x3f, -/* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, -/* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, -/* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -/* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xdf8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x1f, 0x1f, -/* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x83, 0x83, -/* 0xe80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xe98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xea0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xea8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xeb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xeb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xec0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xec8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xed0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xed8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xee0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xee8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xef0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* 0xef8: */ 0x80, 0x80, 0x80, 0x80, 0x87, 0x87, 0x87, 0x8f, -/* 0xf00: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, -/* 0xf08: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf10: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf18: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, -/* 0xf20: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, -/* 0xf28: */ 0xe0, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, -/* 0xf30: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf38: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf40: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf48: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf50: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf58: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf60: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf68: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf70: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, -/* 0xf78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, -/* 0xf80: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf88: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf90: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xf98: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfa0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfa8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfb0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -/* 0xfb8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, -/* 0xfc0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfc8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfd0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfd8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, -/* 0xfe0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0xfe8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -/* 0xff0: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, -/* 0xff8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; diff --git a/src - Cópia/sound/resid-fp/wave8580__ST.dat b/src - Cópia/sound/resid-fp/wave8580__ST.dat deleted file mode 100644 index f30002ceb01ae93d2da7b9e91431a0616a25861a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz7)Zd(Jdn1t1HnMr&%iKn{^tV%ejpgB{s;Mc7{os#sqrTR1#)uoU_h#V>Z%{O z^bhjKFo=J$qXU}%<;gaHDjG-QpTb}ynEx%%fDHuL)k6V=_EV^RH2x_JK(e)u*8jtz z{3n?I(Gv)2{cmrNE>B@IZFTl diff --git a/src - Cópia/sound/snd_ad1848.c b/src - Cópia/sound/snd_ad1848.c deleted file mode 100644 index a35646dc9..000000000 --- a/src - Cópia/sound/snd_ad1848.c +++ /dev/null @@ -1,223 +0,0 @@ -/*PCem v0.8 by Tom Walker - - AD1848 CODEC emulation (Windows Sound System compatible)*/ - -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "sound.h" -#include "snd_ad1848.h" - - -static int ad1848_vols[64]; - - -void ad1848_setirq(ad1848_t *ad1848, int irq) -{ - ad1848->irq = irq; -} - -void ad1848_setdma(ad1848_t *ad1848, int dma) -{ - ad1848->dma = dma; -} - -uint8_t ad1848_read(uint16_t addr, void *p) -{ - ad1848_t *ad1848 = (ad1848_t *)p; - uint8_t temp = 0xff; - switch (addr & 3) - { - case 0: /*Index*/ - temp = ad1848->index | ad1848->trd | ad1848->mce; - break; - case 1: - temp = ad1848->regs[ad1848->index]; - break; - case 2: - temp = ad1848->status; - break; - } - return temp; -} - -void ad1848_write(uint16_t addr, uint8_t val, void *p) -{ - ad1848_t *ad1848 = (ad1848_t *)p; - double freq; - switch (addr & 3) - { - case 0: /*Index*/ - ad1848->index = val & 0xf; - ad1848->trd = val & 0x20; - ad1848->mce = val & 0x40; - break; - case 1: - switch (ad1848->index) - { - case 8: - freq = (val & 1) ? 16934400LL : 24576000LL; - switch ((val >> 1) & 7) - { - case 0: freq /= 3072; break; - case 1: freq /= 1536; break; - case 2: freq /= 896; break; - case 3: freq /= 768; break; - case 4: freq /= 448; break; - case 5: freq /= 384; break; - case 6: freq /= 512; break; - case 7: freq /= 2560; break; - } - ad1848->freq = freq; - ad1848->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); - break; - - case 9: - ad1848->enable = ((val & 0x41) == 0x01); - if (!ad1848->enable) - ad1848->out_l = ad1848->out_r = 0; - break; - - case 12: - return; - - case 14: - ad1848->count = ad1848->regs[15] | (val << 8); - break; - } - ad1848->regs[ad1848->index] = val; - break; - case 2: - ad1848->status &= 0xfe; - break; - } -} - -void ad1848_speed_changed(ad1848_t *ad1848) -{ - ad1848->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); -} - -void ad1848_update(ad1848_t *ad1848) -{ - for (; ad1848->pos < sound_pos_global; ad1848->pos++) - { - ad1848->buffer[ad1848->pos*2] = ad1848->out_l; - ad1848->buffer[ad1848->pos*2 + 1] = ad1848->out_r; - } -} - -static void ad1848_poll(void *p) -{ - ad1848_t *ad1848 = (ad1848_t *)p; - - if (ad1848->timer_latch) - ad1848->timer_count += ad1848->timer_latch; - else - ad1848->timer_count = TIMER_USEC; - - ad1848_update(ad1848); - - if (ad1848->enable) - { - int32_t temp; - - switch (ad1848->regs[8] & 0x70) - { - case 0x00: /*Mono, 8-bit PCM*/ - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - break; - case 0x10: /*Stereo, 8-bit PCM*/ - ad1848->out_l = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - break; - - case 0x40: /*Mono, 16-bit PCM*/ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; - break; - case 0x50: /*Stereo, 16-bit PCM*/ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = (dma_channel_read(ad1848->dma) << 8) | temp; - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; - break; - } - - if (ad1848->regs[6] & 0x80) - ad1848->out_l = 0; - else - ad1848->out_l = (ad1848->out_l * ad1848_vols[ad1848->regs[6] & 0x3f]) >> 16; - - if (ad1848->regs[7] & 0x80) - ad1848->out_r = 0; - else - ad1848->out_r = (ad1848->out_r * ad1848_vols[ad1848->regs[7] & 0x3f]) >> 16; - - if (ad1848->count < 0) - { - ad1848->count = ad1848->regs[15] | (ad1848->regs[14] << 8); - if (!(ad1848->status & 0x01)) - { - ad1848->status |= 0x01; - if (ad1848->regs[0xa] & 2) - picint(1 << ad1848->irq); - } - } - - ad1848->count--; - } - else - { - ad1848->out_l = ad1848->out_r = 0; - } -} - -void ad1848_init(ad1848_t *ad1848) -{ - int c; - double attenuation; - - ad1848->enable = 0; - - ad1848->status = 0xcc; - ad1848->index = ad1848->trd = 0; - ad1848->mce = 0x40; - - ad1848->regs[0] = ad1848->regs[1] = 0; - ad1848->regs[2] = ad1848->regs[3] = 0x80; - ad1848->regs[4] = ad1848->regs[5] = 0x80; - ad1848->regs[6] = ad1848->regs[7] = 0x80; - ad1848->regs[8] = 0; - ad1848->regs[9] = 0x08; - ad1848->regs[10] = ad1848->regs[11] = 0; - ad1848->regs[12] = 0xa; - ad1848->regs[13] = 0; - ad1848->regs[14] = ad1848->regs[15] = 0; - - ad1848->out_l = 0; - ad1848->out_r = 0; - - for (c = 0; c < 64; c++) - { - attenuation = 0.0; - if (c & 0x01) attenuation -= 1.5; - if (c & 0x02) attenuation -= 3.0; - if (c & 0x04) attenuation -= 6.0; - if (c & 0x08) attenuation -= 12.0; - if (c & 0x10) attenuation -= 24.0; - if (c & 0x20) attenuation -= 48.0; - - attenuation = pow(10, attenuation / 10); - - ad1848_vols[c] = (int)(attenuation * 65536); - } - - timer_add(ad1848_poll, &ad1848->timer_count, &ad1848->enable, ad1848); -} diff --git a/src - Cópia/sound/snd_ad1848.h b/src - Cópia/sound/snd_ad1848.h deleted file mode 100644 index 39dc60a5e..000000000 --- a/src - Cópia/sound/snd_ad1848.h +++ /dev/null @@ -1,35 +0,0 @@ -typedef struct ad1848_t -{ - int index; - uint8_t regs[16]; - uint8_t status; - - int trd; - int mce; - - int count; - - int16_t out_l, out_r; - - int64_t enable; - - int irq, dma; - - int64_t freq; - - int64_t timer_count, timer_latch; - - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; -} ad1848_t; - -void ad1848_setirq(ad1848_t *ad1848, int irq); -void ad1848_setdma(ad1848_t *ad1848, int dma); - -uint8_t ad1848_read(uint16_t addr, void *p); -void ad1848_write(uint16_t addr, uint8_t val, void *p); - -void ad1848_update(ad1848_t *ad1848); -void ad1848_speed_changed(ad1848_t *ad1848); - -void ad1848_init(ad1848_t *ad1848); diff --git a/src - Cópia/sound/snd_adlib.c b/src - Cópia/sound/snd_adlib.c deleted file mode 100644 index 0628ec932..000000000 --- a/src - Cópia/sound/snd_adlib.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mca.h" -#include "../device.h" -#include "sound.h" -#include "snd_adlib.h" -#include "snd_opl.h" - - -#ifdef ENABLE_ADLIB_LOG -int adlib_do_log = ENABLE_ADLIB_LOG; -#endif - - -static void -adlib_log(const char *fmt, ...) -{ -#ifdef ENABLE_ADLIB_LOG - va_list ap; - - if (adlib_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -typedef struct adlib_t -{ - opl_t opl; - - uint8_t pos_regs[8]; -} adlib_t; - - -static void adlib_get_buffer(int32_t *buffer, int len, void *p) -{ - adlib_t *adlib = (adlib_t *)p; - int c; - - opl2_update2(&adlib->opl); - - for (c = 0; c < len * 2; c++) - buffer[c] += (int32_t)adlib->opl.buffer[c]; - - adlib->opl.pos = 0; -} - -uint8_t adlib_mca_read(int port, void *p) -{ - adlib_t *adlib = (adlib_t *)p; - - adlib_log("adlib_mca_read: port=%04x\n", port); - - return adlib->pos_regs[port & 7]; -} - -void adlib_mca_write(int port, uint8_t val, void *p) -{ - adlib_t *adlib = (adlib_t *)p; - - if (port < 0x102) - return; - - adlib_log("adlib_mca_write: port=%04x val=%02x\n", port, val); - - switch (port) - { - case 0x102: - if ((adlib->pos_regs[2] & 1) && !(val & 1)) - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - if (!(adlib->pos_regs[2] & 1) && (val & 1)) - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - break; - } - adlib->pos_regs[port & 7] = val; -} - -void *adlib_init(const device_t *info) -{ - adlib_t *adlib = malloc(sizeof(adlib_t)); - memset(adlib, 0, sizeof(adlib_t)); - - adlib_log("adlib_init\n"); - opl2_init(&adlib->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - sound_add_handler(adlib_get_buffer, adlib); - return adlib; -} - -void *adlib_mca_init(const device_t *info) -{ - adlib_t *adlib = adlib_init(info); - - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - mca_add(adlib_mca_read, adlib_mca_write, adlib); - adlib->pos_regs[0] = 0xd7; - adlib->pos_regs[1] = 0x70; - - return adlib; -} - -void adlib_close(void *p) -{ - adlib_t *adlib = (adlib_t *)p; - - free(adlib); -} - -const device_t adlib_device = -{ - "AdLib", - DEVICE_ISA, - 0, - adlib_init, adlib_close, NULL, - NULL, NULL, NULL, - NULL -}; - -const device_t adlib_mca_device = -{ - "AdLib (MCA)", - DEVICE_MCA, - 0, - adlib_init, adlib_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_adlib.h b/src - Cópia/sound/snd_adlib.h deleted file mode 100644 index 4a6a161ca..000000000 --- a/src - Cópia/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 - Cópia/sound/snd_adlibgold.c b/src - Cópia/sound/snd_adlibgold.c deleted file mode 100644 index 178095702..000000000 --- a/src - Cópia/sound/snd_adlibgold.c +++ /dev/null @@ -1,851 +0,0 @@ -#include -#include -#include -#include -#include -#include "../86box.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 "../timer.h" -#include "sound.h" -#include "filters.h" -#include "snd_opl.h" -#include "snd_ym7128.h" - - -typedef struct adgold_t -{ - int adgold_irq_status; - - uint8_t adgold_eeprom[0x19]; - - uint8_t adgold_status; - int adgold_38x_state, adgold_38x_addr; - uint8_t adgold_38x_regs[0x19]; - - int adgold_mma_addr; - uint8_t adgold_mma_regs[2][0xe]; - - int adgold_mma_enable[2]; - uint8_t adgold_mma_fifo[2][256]; - int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2]; - uint8_t adgold_mma_status; - - int16_t adgold_mma_out[2]; - int adgold_mma_intpos[2]; - - int64_t adgold_mma_timer_count; - - struct - { - int timer0_latch, timer0_count; - int timerbase_latch, timerbase_count; - int timer1_latch, timer1_count; - int timer2_latch, timer2_count, timer2_read; - - int voice_count[2], voice_latch[2]; - } adgold_mma; - - opl_t opl; - ym7128_t ym7128; - - int fm_vol_l, fm_vol_r; - int samp_vol_l, samp_vol_r; - int vol_l, vol_r; - int treble, bass; - - int16_t opl_buffer[SOUNDBUFLEN * 2]; - int16_t mma_buffer[2][SOUNDBUFLEN]; - - int pos; - - int surround_enabled; -} adgold_t; - -static int attenuation[0x40]; -static int bass_attenuation[0x10] = -{ - (int)(1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.413 * 16384), /*9 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(0 * 16384), /*0 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(1.413 * 16384), /*9 dB*/ - (int)(1.995 * 16384), /*12 dB*/ - (int)(2.819 * 16384), /*15 dB*/ - (int)(2.819 * 16384), - (int)(2.819 * 16384), - (int)(2.819 * 16384), - (int)(2.819 * 16384) -}; - -static int bass_cut[6] = -{ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.178 * 16384), /*-9 dB*/ - (int)(0.251 * 16384), /*-6 dB*/ - (int)(0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ -}; - -static int treble_attenuation[0x10] = -{ - (int)(1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.413 * 16384), /*9 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(0 * 16384), /*0 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(1.413 * 16384), /*9 dB*/ - (int)(1.995 * 16384), /*12 dB*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384) -}; - -static int treble_cut[6] = -{ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.178 * 16384), /*-9 dB*/ - (int)(0.251 * 16384), /*-6 dB*/ - (int)(0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ -}; - -void adgold_timer_poll(); -void adgold_update(adgold_t *adgold); - -void adgold_update_irq_status(adgold_t *adgold) -{ - uint8_t temp = 0xf; - - if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/ - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/ - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/ - temp &= ~2; - - if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2)) - temp &= ~2; - if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2)) - temp &= ~2; - adgold->adgold_status = temp; - - if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) - { - picint(0x80); - } - - adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; -} - -void adgold_getsamp_dma(adgold_t *adgold, int channel) -{ - int temp; - - if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) - return; - - temp = dma_channel_read(1); - if (temp == DMA_NODATA) return; - adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; - if (adgold->adgold_mma_regs[channel][0xc] & 0x60) - { - temp = dma_channel_read(1); - adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; - } - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) - { - adgold->adgold_mma_status &= ~(0x01 << channel); - adgold_update_irq_status(adgold); - } -} - -void adgold_write(uint16_t addr, uint8_t val, void *p) -{ - adgold_t *adgold = (adgold_t *)p; - switch (addr & 7) - { - case 0: case 1: - opl3_write(addr, val, &adgold->opl); - break; - - case 2: - if (val == 0xff) - { - adgold->adgold_38x_state = 1; - return; - } - if (val == 0xfe) - { - adgold->adgold_38x_state = 0; - return; - } - if (adgold->adgold_38x_state) /*Write to control chip*/ - adgold->adgold_38x_addr = val; - else - opl3_write(addr, val, &adgold->opl); - break; - case 3: - if (adgold->adgold_38x_state) - { - if (adgold->adgold_38x_addr >= 0x19) break; - switch (adgold->adgold_38x_addr) - { - case 0x00: /*Control/ID*/ - if (val & 1) - memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); - if (val & 2) - memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x19); - break; - - case 0x04: /*Final output volume left*/ - adgold->adgold_38x_regs[0x04] = val; - adgold->vol_l = attenuation[val & 0x3f]; - break; - case 0x05: /*Final output volume right*/ - adgold->adgold_38x_regs[0x05] = val; - adgold->vol_r = attenuation[val & 0x3f]; - break; - case 0x06: /*Bass*/ - adgold->adgold_38x_regs[0x06] = val; - adgold->bass = val & 0xf; - break; - case 0x07: /*Treble*/ - adgold->adgold_38x_regs[0x07] = val; - adgold->treble = val & 0xf; - break; - - case 0x09: /*FM volume left*/ - adgold->adgold_38x_regs[0x09] = val; - adgold->fm_vol_l = (int)(int8_t)(val - 128); - break; - case 0x0a: /*FM volume right*/ - adgold->adgold_38x_regs[0x0a] = val; - adgold->fm_vol_r = (int)(int8_t)(val - 128); - break; - case 0x0b: /*Sample volume left*/ - adgold->adgold_38x_regs[0x0b] = val; - adgold->samp_vol_l = (int)(int8_t)(val - 128); - break; - case 0x0c: /*Sample volume right*/ - adgold->adgold_38x_regs[0x0c] = val; - adgold->samp_vol_r = (int)(int8_t)(val - 128); - break; - - case 0x18: /*Surround*/ - adgold->adgold_38x_regs[0x18] = val; - ym7128_write(&adgold->ym7128, val); - break; - - default: - adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val; - break; - } - } - else - opl3_write(addr, val, &adgold->opl); - break; - case 4: case 6: - adgold->adgold_mma_addr = val; - break; - case 5: - if (adgold->adgold_mma_addr >= 0xf) break; - switch (adgold->adgold_mma_addr) - { - case 0x2: - adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff00) | val; - break; - case 0x3: - adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff) | (val << 8); - break; - case 0x4: - adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xf00) | val; - break; - case 0x5: - adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xff) | ((val & 0xf) << 8); - adgold->adgold_mma.timer1_latch = val >> 4; - break; - case 0x6: - adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff00) | val; - break; - case 0x7: - adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8); - break; - - case 0x8: - if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/ - adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - - if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/ - adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; - - if ((val & 4) && !(adgold->adgold_mma_regs[0][8] & 4)) /*Reload timer 2*/ - adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; - - if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/ - adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; - break; - - case 0x9: - switch (val & 0x18) - { - case 0x00: adgold->adgold_mma.voice_latch[0] = 12; break; /*44100 Hz*/ - case 0x08: adgold->adgold_mma.voice_latch[0] = 24; break; /*22050 Hz*/ - case 0x10: adgold->adgold_mma.voice_latch[0] = 48; break; /*11025 Hz*/ - case 0x18: adgold->adgold_mma.voice_latch[0] = 72; break; /* 7350 Hz*/ - } - if (val & 0x80) - { - adgold->adgold_mma_enable[0] = 0; - adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0; - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - if ((val & 0x01)) /*Start playback*/ - { - if (!(adgold->adgold_mma_regs[0][0x9] & 1)) - adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; - - if (adgold->adgold_mma_regs[0][0xc] & 1) - { - if (adgold->adgold_mma_regs[0][0xc] & 0x80) - { - adgold->adgold_mma_enable[1] = 1; - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - - while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 0); - adgold_getsamp_dma(adgold, 1); - } - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) - { - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - } - else - { - while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 0); - } - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - } - } - } - adgold->adgold_mma_enable[0] = val & 0x01; - break; - - case 0xb: - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val; - adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - } - break; - - case 0xc: - adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8; - break; - } - adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val; - break; - case 7: - if (adgold->adgold_mma_addr >= 0xf) break; - switch (adgold->adgold_mma_addr) - { - case 0x9: - adgold_update(adgold); - switch (val & 0x18) - { - case 0x00: adgold->adgold_mma.voice_latch[1] = 12; break; /*44100 Hz*/ - case 0x08: adgold->adgold_mma.voice_latch[1] = 24; break; /*22050 Hz*/ - case 0x10: adgold->adgold_mma.voice_latch[1] = 48; break; /*11025 Hz*/ - case 0x18: adgold->adgold_mma.voice_latch[1] = 72; break; /* 7350 Hz*/ - } - if (val & 0x80) - { - adgold->adgold_mma_enable[1] = 0; - adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0; - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - if ((val & 0x01)) /*Start playback*/ - { - if (!(adgold->adgold_mma_regs[1][0x9] & 1)) - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - - if (adgold->adgold_mma_regs[1][0xc] & 1) - { - while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 1); - } - } - } - adgold->adgold_mma_enable[1] = val & 0x01; - break; - - case 0xb: - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) - { - adgold->adgold_mma_fifo[1][adgold->adgold_mma_fifo_end[1]] = val; - adgold->adgold_mma_fifo_end[1] = (adgold->adgold_mma_fifo_end[1] + 1) & 255; - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) - { - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - } - break; - - case 0xc: - adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8; - break; - } - adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val; - break; - } -} - -uint8_t adgold_read(uint16_t addr, void *p) -{ - adgold_t *adgold = (adgold_t *)p; - uint8_t temp = 0; - - switch (addr & 7) - { - case 0: case 1: - temp = opl3_read(addr, &adgold->opl); - break; - - case 2: - if (adgold->adgold_38x_state) /*Read from control chip*/ - temp = adgold->adgold_status; - else - temp = opl3_read(addr, &adgold->opl); - break; - - case 3: - if (adgold->adgold_38x_state) - { - if (adgold->adgold_38x_addr >= 0x19) temp = 0xff; - switch (adgold->adgold_38x_addr) - { - case 0x00: /*Control/ID*/ - if (adgold->surround_enabled) - temp = 0x50; /*16-bit ISA, surround module, no telephone/CDROM*/ - else - temp = 0x70; /*16-bit ISA, no telephone/surround/CD-ROM*/ - break; - - default: - temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; - } - } - else - temp = opl3_read(addr, &adgold->opl); - break; - - case 4: case 6: - temp = adgold->adgold_mma_status; - adgold->adgold_mma_status = 0; /*JUKEGOLD expects timer status flags to auto-clear*/ - adgold_update_irq_status(adgold); - break; - case 5: - if (adgold->adgold_mma_addr >= 0xf) temp = 0xff; - switch (adgold->adgold_mma_addr) - { - case 6: /*Timer 2 low*/ - adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count; - temp = adgold->adgold_mma.timer2_read & 0xff; - break; - case 7: /*Timer 2 high*/ - temp = adgold->adgold_mma.timer2_read >> 8; - break; - - default: - temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr]; - break; - } - break; - case 7: - if (adgold->adgold_mma_addr >= 0xf) temp = 0xff; - temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; - break; - } - return temp; -} - -void adgold_update(adgold_t *adgold) -{ - for (; adgold->pos < sound_pos_global; adgold->pos++) - { - adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0; - - if (adgold->adgold_mma_regs[0][9] & 0x20) - adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2; - if (adgold->adgold_mma_regs[0][9] & 0x40) - adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[0] / 2; - - if (adgold->adgold_mma_regs[1][9] & 0x20) - adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[1] / 2; - if (adgold->adgold_mma_regs[1][9] & 0x40) - adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[1] / 2; - } -} - -void adgold_mma_poll(adgold_t *adgold, int channel) -{ - int16_t dat; - - adgold_update(adgold); - - if (adgold->adgold_mma_fifo_start[channel] != adgold->adgold_mma_fifo_end[channel]) - { - switch (adgold->adgold_mma_regs[channel][0xc] & 0x60) - { - case 0x00: /*8-bit*/ - dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] * 256; - adgold->adgold_mma_out[channel] = dat; - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - break; - - case 0x40: /*12-bit sensible format*/ - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2) - return; - - dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0; - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8); - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - adgold->adgold_mma_out[channel] = dat; - break; - } - - if (adgold->adgold_mma_regs[channel][0xc] & 1) - { - adgold_getsamp_dma(adgold, channel); - } - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) - { - adgold->adgold_mma_status |= 1 << channel; - adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_fifo_start[channel] == adgold->adgold_mma_fifo_end[channel]) - { - adgold->adgold_mma_enable[channel] = 0; - } -} - -void adgold_timer_poll(void *p) -{ - adgold_t *adgold = (adgold_t *)p; - - while (adgold->adgold_mma_timer_count <= 0LL) - { - adgold->adgold_mma_timer_count += (int64_t)((double)TIMER_USEC * 1.88964); - if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/ - { - adgold->adgold_mma.timer0_count--; - if (!adgold->adgold_mma.timer0_count) - { - adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - adgold->adgold_mma_status |= 0x10; - adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_regs[0][8] & 0x08) /*Base timer*/ - { - adgold->adgold_mma.timerbase_count--; - if (!adgold->adgold_mma.timerbase_count) - { - adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; - if (adgold->adgold_mma_regs[0][8] & 0x02) /*Timer 1*/ - { - adgold->adgold_mma.timer1_count--; - if (!adgold->adgold_mma.timer1_count) - { - adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; - adgold->adgold_mma_status |= 0x20; - adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_regs[0][8] & 0x04) /*Timer 2*/ - { - adgold->adgold_mma.timer2_count--; - if (!adgold->adgold_mma.timer2_count) - { - adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; - adgold->adgold_mma_status |= 0x40; - adgold_update_irq_status(adgold); - } - } - } - } - - if (adgold->adgold_mma_enable[0]) - { - adgold->adgold_mma.voice_count[0]--; - if (!adgold->adgold_mma.voice_count[0]) - { - adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; - adgold_mma_poll(adgold, 0); - } - } - if (adgold->adgold_mma_enable[1]) - { - adgold->adgold_mma.voice_count[1]--; - if (!adgold->adgold_mma.voice_count[1]) - { - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - adgold_mma_poll(adgold, 1); - } - } - } -} - -static void adgold_get_buffer(int32_t *buffer, int len, void *p) -{ - adgold_t *adgold = (adgold_t *)p; - int16_t adgold_buffer[len*2]; - - int c; - - opl3_update2(&adgold->opl); - adgold_update(adgold); - - for (c = 0; c < len * 2; c += 2) - { - adgold_buffer[c] = ((adgold->opl.buffer[c] * adgold->fm_vol_l) >> 7) / 2; - adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold_buffer[c+1] = ((adgold->opl.buffer[c+1] * adgold->fm_vol_r) >> 7) / 2; - adgold_buffer[c+1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; - } - - if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold_buffer, len); - - switch (adgold->adgold_38x_regs[0x8] & 6) - { - case 0: - for (c = 0; c < len * 2; c++) - adgold_buffer[c] = 0; - break; - case 2: /*Left channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c+1] = adgold_buffer[c]; - break; - case 4: /*Right channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] = adgold_buffer[c+1]; - break; - case 6: /*Left and right channels*/ - break; - } - - switch (adgold->adgold_38x_regs[0x8] & 0x18) - { - case 0x00: /*Forced mono*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] = adgold_buffer[c+1] = ((int32_t)adgold_buffer[c] + (int32_t)adgold_buffer[c+1]) / 2; - break; - case 0x08: /*Linear stereo*/ - break; - case 0x10: /*Pseudo stereo*/ - /*Filter left channel, leave right channel unchanged*/ - /*Filter cutoff is largely a guess*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); - break; - case 0x18: /*Spatial stereo*/ - /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet - and a very vague understanding of how op-amps work to go on*/ - for (c = 0; c < len * 2; c += 2) - { - int16_t l = adgold_buffer[c]; - int16_t r = adgold_buffer[c+1]; - - adgold_buffer[c] += (r / 3) + ((l * 2) / 3); - adgold_buffer[c+1] += (l / 3) + ((r * 2) / 3); - } - break; - } - - for (c = 0; c < len * 2; c += 2) - { - int32_t temp, lowpass, highpass; - - /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t)adgold_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(0, temp); - highpass = adgold_highpass_iir(0, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c] += temp; - - temp = ((int32_t)adgold_buffer[c+1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(1, temp); - highpass = adgold_highpass_iir(1, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c+1] += temp; - } - - adgold->opl.pos = 0; - adgold->pos = 0; -} - - -void *adgold_init(const device_t *info) -{ - FILE *f; - int c; - double out; - adgold_t *adgold = malloc(sizeof(adgold_t)); - memset(adgold, 0, sizeof(adgold_t)); - - adgold->surround_enabled = device_get_config_int("surround"); - - opl3_init(&adgold->opl); - if (adgold->surround_enabled) - ym7128_init(&adgold->ym7128); - - out = 65536.0; /*Main volume control ranges from +6 dB to -64 dB in 2 dB steps, then remaining settings are -80 dB (effectively 0)*/ - for (c = 0x3f; c >= 0x1c; c--) - { - attenuation[c] = (int)out; - out /= 1.25963; /*2 dB steps*/ - } - for (; c >= 0; c--) - attenuation[c] = 0; - - f = nvr_fopen(L"adgold.bin", L"rb"); - if (f) - { - fread(adgold->adgold_eeprom, 0x18, 1, f); - fclose(f); - } - - adgold->adgold_status = 0xf; - adgold->adgold_38x_addr = 0; - adgold->adgold_eeprom[0x13] = 3 | (1 << 4); /*IRQ 7, DMA 1*/ - adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3*/ - adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ - memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); - adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; - adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; - adgold->bass = adgold->adgold_eeprom[0x06] & 0xf; - adgold->treble = adgold->adgold_eeprom[0x07] & 0xf; - adgold->fm_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x09] - 128); - adgold->fm_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0a] - 128); - adgold->samp_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0b] - 128); - adgold->samp_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0c] - 128); - - adgold->adgold_mma_enable[0] = 0; - adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; - - /*388/389 are handled by adlib_init*/ - io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); - - timer_add(adgold_timer_poll, &adgold->adgold_mma_timer_count, TIMER_ALWAYS_ENABLED, adgold); - - sound_add_handler(adgold_get_buffer, adgold); - - return adgold; -} - -void adgold_close(void *p) -{ - FILE *f; - adgold_t *adgold = (adgold_t *)p; - - f = nvr_fopen(L"adgold.bin", L"wb"); - if (f) - { - fwrite(adgold->adgold_eeprom, 0x18, 1, f); - fclose(f); - } - - free(adgold); -} - -static const device_config_t adgold_config[] = -{ - { - "surround", "Surround module", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -const device_t adgold_device = -{ - "AdLib Gold", - DEVICE_ISA, 0, - adgold_init, - adgold_close, - NULL, - NULL, - NULL, - NULL, - adgold_config -}; diff --git a/src - Cópia/sound/snd_adlibgold.h b/src - Cópia/sound/snd_adlibgold.h deleted file mode 100644 index daea1b490..000000000 --- a/src - Cópia/sound/snd_adlibgold.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t adgold_device; diff --git a/src - Cópia/sound/snd_audiopci.c b/src - Cópia/sound/snd_audiopci.c deleted file mode 100644 index 999c91d4e..000000000 --- a/src - Cópia/sound/snd_audiopci.c +++ /dev/null @@ -1,1309 +0,0 @@ -#include -#include -#include -#include -#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 "sound.h" -#include "snd_audiopci.h" - - -#define N 16 - -#define ES1371_NCoef 91 - -static float low_fir_es1371_coef[ES1371_NCoef]; - -typedef struct { - uint8_t pci_command, pci_serr; - - uint32_t base_addr; - - uint8_t int_line; - - uint16_t pmcsr; - - uint32_t int_ctrl; - uint32_t int_status; - - uint32_t legacy_ctrl; - - int mem_page; - - uint32_t si_cr; - - uint32_t sr_cir; - uint16_t sr_ram[128]; - - uint8_t uart_ctrl; - uint8_t uart_status; - - uint16_t codec_regs[64]; - uint32_t codec_ctrl; - - struct { - uint32_t addr, addr_latch; - uint16_t count, size; - - uint16_t samp_ct, curr_samp_ct; - - int64_t time, latch; - - uint32_t vf, ac; - - int16_t buffer_l[64], buffer_r[64]; - int buffer_pos, buffer_pos_end; - - int filtered_l[32], filtered_r[32]; - int f_pos; - - int16_t out_l, out_r; - - int32_t vol_l, vol_r; - } dac[2], adc; - - int64_t dac_latch, dac_time; - - int master_vol_l, master_vol_r; - - int card; - - int pos; - int16_t buffer[SOUNDBUFLEN * 2]; -} es1371_t; - - -#define LEGACY_SB_ADDR (1<<29) -#define LEGACY_SSCAPE_ADDR_SHIFT 27 -#define LEGACY_CODEC_ADDR_SHIFT 25 -#define LEGACY_FORCE_IRQ (1<<24) -#define LEGACY_CAPTURE_SLAVE_DMA (1<<23) -#define LEGACY_CAPTURE_SLAVE_PIC (1<<22) -#define LEGACY_CAPTURE_MASTER_DMA (1<<21) -#define LEGACY_CAPTURE_MASTER_PIC (1<<20) -#define LEGACY_CAPTURE_ADLIB (1<<19) -#define LEGACY_CAPTURE_SB (1<<18) -#define LEGACY_CAPTURE_CODEC (1<<17) -#define LEGACY_CAPTURE_SSCAPE (1<<16) -#define LEGACY_EVENT_SSCAPE (0<<8) -#define LEGACY_EVENT_CODEC (1<<8) -#define LEGACY_EVENT_SB (2<<8) -#define LEGACY_EVENT_ADLIB (3<<8) -#define LEGACY_EVENT_MASTER_PIC (4<<8) -#define LEGACY_EVENT_MASTER_DMA (5<<8) -#define LEGACY_EVENT_SLAVE_PIC (6<<8) -#define LEGACY_EVENT_SLAVE_DMA (7<<8) -#define LEGACY_EVENT_MASK (7<<8) -#define LEGACY_EVENT_ADDR_SHIFT 3 -#define LEGACY_EVENT_ADDR_MASK (0x1f<<3) -#define LEGACY_EVENT_TYPE_RW (1<<2) -#define LEGACY_INT (1<<0) - -#define SRC_RAM_WE (1<<24) - -#define CODEC_READ (1<<23) -#define CODEC_READY (1<<31) - -#define INT_DAC1_EN (1<<6) -#define INT_DAC2_EN (1<<5) - -#define SI_P2_INTR_EN (1<<9) -#define SI_P1_INTR_EN (1<<8) - -#define INT_STATUS_INTR (1<<31) -#define INT_STATUS_DAC1 (1<<2) -#define INT_STATUS_DAC2 (1<<1) - -#define FORMAT_MONO_8 0 -#define FORMAT_STEREO_8 1 -#define FORMAT_MONO_16 2 -#define FORMAT_STEREO_16 3 - -const int32_t codec_attn[]= { - 25,32,41,51,65,82,103,130,164,206,260,327,412,519,653, - 822,1036,1304,1641,2067,2602,3276,4125,5192,6537,8230,10362,13044, - 16422,20674,26027,32767 -}; - -static void es1371_fetch(es1371_t *es1371, int dac_nr); -static void update_legacy(es1371_t *es1371); - -#ifdef ENABLE_AUDIOPCI_LOG -int audiopci_do_log = ENABLE_AUDIOPCI_LOG; -#endif - - -static void -audiopci_log(const char *fmt, ...) -{ -#ifdef ENABLE_AUDIOPCI_LOG - va_list ap; - - if (audiopci_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void es1371_update_irqs(es1371_t *es1371) -{ - int irq = 0; - - if ((es1371->int_status & INT_STATUS_DAC1) && (es1371->si_cr & SI_P1_INTR_EN)) - irq = 1; - if ((es1371->int_status & INT_STATUS_DAC2) && (es1371->si_cr & SI_P2_INTR_EN)) - irq = 1; - - if (irq) - es1371->int_status |= INT_STATUS_INTR; - else - es1371->int_status &= ~INT_STATUS_INTR; - - if (es1371->legacy_ctrl & LEGACY_FORCE_IRQ) - irq = 1; - - if (irq) - { - pci_set_irq(es1371->card, PCI_INTA); -// audiopci_log("Raise IRQ\n"); - } - else - { - pci_clear_irq(es1371->card, PCI_INTA); -// audiopci_log("Drop IRQ\n"); - } -} - -static uint8_t es1371_inb(uint16_t port, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - uint8_t ret = 0; - - switch (port & 0x3f) - { - case 0x00: - ret = es1371->int_ctrl & 0xff; - break; - case 0x01: - ret = (es1371->int_ctrl >> 8) & 0xff; - break; - case 0x02: - ret = (es1371->int_ctrl >> 16) & 0xff; - break; - case 0x03: - ret = (es1371->int_ctrl >> 24) & 0xff; - break; - - case 0x04: - ret = es1371->int_status & 0xff; - break; - case 0x05: - ret = (es1371->int_status >> 8) & 0xff; - break; - case 0x06: - ret = (es1371->int_status >> 16) & 0xff; - break; - case 0x07: - ret = (es1371->int_status >> 24) & 0xff; - break; - - - case 0x09: - ret = es1371->uart_status; - break; - - case 0x0c: - ret = es1371->mem_page; - break; - - case 0x1a: - ret = es1371->legacy_ctrl >> 16; - break; - case 0x1b: - ret = es1371->legacy_ctrl >> 24; - break; - - case 0x20: - ret = es1371->si_cr & 0xff; - break; - case 0x21: - ret = es1371->si_cr >> 8; - break; - case 0x22: - ret = (es1371->si_cr >> 16) | 0x80; - break; - case 0x23: - ret = 0xff; - break; - - default: - audiopci_log("Bad es1371_inb: port=%04x\n", port); - } - -// audiopci_log("es1371_inb: port=%04x ret=%02x\n", port, ret); -// output = 3; - return ret; -} -static uint16_t es1371_inw(uint16_t port, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - uint16_t ret = 0; - - switch (port & 0x3e) - { - case 0x00: - ret = es1371->int_ctrl & 0xffff; - break; - case 0x02: - ret = (es1371->int_ctrl >> 16) & 0xffff; - break; - - case 0x18: - ret = es1371->legacy_ctrl & 0xffff; -// audiopci_log("Read legacy ctrl %04x\n", ret); - break; - - case 0x26: - ret = es1371->dac[0].curr_samp_ct; - break; - - case 0x2a: - ret = es1371->dac[1].curr_samp_ct; - break; - - case 0x36: - switch (es1371->mem_page) - { - case 0xc: - ret = es1371->dac[0].count; - break; - - default: - audiopci_log("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; - - case 0x3e: - switch (es1371->mem_page) - { - case 0xc: - ret = es1371->dac[1].count; - break; - - default: - audiopci_log("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; - - default: - audiopci_log("Bad es1371_inw: port=%04x\n", port); - } - -// audiopci_log("es1371_inw: port=%04x ret=%04x %04x:%08x\n", port, ret, CS,cpu_state.pc); - return ret; -} -static uint32_t es1371_inl(uint16_t port, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - uint32_t ret = 0; - - switch (port & 0x3c) - { - case 0x00: - ret = es1371->int_ctrl; - break; - case 0x04: - ret = es1371->int_status; - break; - - case 0x10: - ret = es1371->sr_cir & ~0xffff; - ret |= es1371->sr_ram[es1371->sr_cir >> 25]; - break; - - case 0x14: - ret = es1371->codec_ctrl & 0x00ff0000; - ret |= es1371->codec_regs[(es1371->codec_ctrl >> 16) & 0x3f]; - ret |= CODEC_READY; - break; - - case 0x34: - switch (es1371->mem_page) - { - - case 0xc: - ret = es1371->dac[0].size | (es1371->dac[0].count << 16); - break; - - case 0xd: - - ret = es1371->adc.size | (es1371->adc.count << 16); - break; - - default: - audiopci_log("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; - - case 0x3c: - switch (es1371->mem_page) - { - case 0xc: - ret = es1371->dac[1].size | (es1371->dac[1].count << 16); - break; - - default: - audiopci_log("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; - - default: - audiopci_log("Bad es1371_inl: port=%04x\n", port); - } - -// audiopci_log("es1371_inl: port=%04x ret=%08x %08x\n", port, ret, cpu_state.pc); - return ret; -} - -static void es1371_outb(uint16_t port, uint8_t val, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - -// audiopci_log("es1371_outb: port=%04x val=%02x %04x:%08x\n", port, val, cs, cpu_state.pc); - switch (port & 0x3f) - { - case 0x00: - if (!(es1371->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) - { - es1371->dac[0].addr = es1371->dac[0].addr_latch; - es1371->dac[0].buffer_pos = 0; - es1371->dac[0].buffer_pos_end = 0; - es1371_fetch(es1371, 0); - } - if (!(es1371->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) - { - es1371->dac[1].addr = es1371->dac[1].addr_latch; - es1371->dac[1].buffer_pos = 0; - es1371->dac[1].buffer_pos_end = 0; - es1371_fetch(es1371, 1); - } - es1371->int_ctrl = (es1371->int_ctrl & 0xffffff00) | val; - break; - case 0x01: - es1371->int_ctrl = (es1371->int_ctrl & 0xffff00ff) | (val << 8); - break; - case 0x02: - es1371->int_ctrl = (es1371->int_ctrl & 0xff00ffff) | (val << 16); - break; - case 0x03: - es1371->int_ctrl = (es1371->int_ctrl & 0x00ffffff) | (val << 24); - break; - - case 0x09: - es1371->uart_ctrl = val; - break; - - case 0x0c: - es1371->mem_page = val & 0xf; - break; - - case 0x18: - es1371->legacy_ctrl |= LEGACY_INT; - nmi = 0; - break; - case 0x1a: - es1371->legacy_ctrl = (es1371->legacy_ctrl & 0xff00ffff) | (val << 16); - update_legacy(es1371); - break; - case 0x1b: - es1371->legacy_ctrl = (es1371->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(es1371); -// output = 3; - update_legacy(es1371); - break; - - case 0x20: - es1371->si_cr = (es1371->si_cr & 0xffff00) | val; - break; - case 0x21: - es1371->si_cr = (es1371->si_cr & 0xff00ff) | (val << 8); - if (!(es1371->si_cr & SI_P1_INTR_EN)) - es1371->int_status &= ~INT_STATUS_DAC1; - if (!(es1371->si_cr & SI_P2_INTR_EN)) - es1371->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(es1371); - break; - case 0x22: - es1371->si_cr = (es1371->si_cr & 0x00ffff) | (val << 16); - break; - - default: - audiopci_log("Bad es1371_outb: port=%04x val=%02x\n", port, val); - } -} -static void es1371_outw(uint16_t port, uint16_t val, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - -// audiopci_log("es1371_outw: port=%04x val=%04x\n", port, val); - switch (port & 0x3f) - { - case 0x0c: - es1371->mem_page = val & 0xf; - break; - - case 0x24: - es1371->dac[0].samp_ct = val; - break; - - case 0x28: - es1371->dac[1].samp_ct = val; - break; - - default: - audiopci_log("Bad es1371_outw: port=%04x val=%04x\n", port, val); - } -} -static void es1371_outl(uint16_t port, uint32_t val, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - -// audiopci_log("es1371_outl: port=%04x val=%08x %04x:%08x\n", port, val, CS, cpu_state.pc); - switch (port & 0x3f) - { - case 0x04: - break; - - case 0x0c: - es1371->mem_page = val & 0xf; - break; - - case 0x10: - es1371->sr_cir = val; - if (es1371->sr_cir & SRC_RAM_WE) - { -// audiopci_log("Write SR RAM %02x %04x\n", es1371->sr_cir >> 25, val & 0xffff); - es1371->sr_ram[es1371->sr_cir >> 25] = val & 0xffff; - switch (es1371->sr_cir >> 25) - { - case 0x71: - es1371->dac[0].vf = (es1371->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); - es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); - es1371->dac[0].f_pos = 0; - break; - case 0x72: - es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7fff) | (val & 0x7fff); - break; - case 0x73: - es1371->dac[0].vf = (es1371->dac[0].vf & ~0x7fff) | (val & 0x7fff); - break; - - case 0x75: - es1371->dac[1].vf = (es1371->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); - es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); - es1371->dac[1].f_pos = 0; - break; - case 0x76: - es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7fff) | (val & 0x7fff); - break; - case 0x77: - es1371->dac[1].vf = (es1371->dac[1].vf & ~0x7fff) | (val & 0x7fff); - break; - - case 0x7c: - es1371->dac[0].vol_l = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7d: - es1371->dac[0].vol_r = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7e: - es1371->dac[1].vol_l = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7f: - es1371->dac[1].vol_r = (int32_t)(int16_t)(val & 0xffff); - break; - } - } - break; - - case 0x14: - es1371->codec_ctrl = val; - if (!(val & CODEC_READ)) - { -// audiopci_log("Write codec %02x %04x\n", (val >> 16) & 0x3f, val & 0xffff); - es1371->codec_regs[(val >> 16) & 0x3f] = val & 0xffff; - switch ((val >> 16) & 0x3f) - { - case 0x02: /*Master volume*/ - if (val & 0x8000) - es1371->master_vol_l = es1371->master_vol_r = 0; - else - { - if (val & 0x2000) - es1371->master_vol_l = codec_attn[0]; - else - es1371->master_vol_l = codec_attn[0x1f - ((val >> 8) & 0x1f)]; - if (val & 0x20) - es1371->master_vol_r = codec_attn[0]; - else - es1371->master_vol_r = codec_attn[0x1f - (val & 0x1f)]; - } - break; - case 0x12: /*CD volume*/ - if (val & 0x8000) - sound_set_cd_volume(0, 0); - else - sound_set_cd_volume(codec_attn[0x1f - ((val >> 8) & 0x1f)] * 2, codec_attn[0x1f - (val & 0x1f)] * 2); - break; - } - } - break; - - case 0x24: - es1371->dac[0].samp_ct = val & 0xffff; - break; - - case 0x28: - es1371->dac[1].samp_ct = val & 0xffff; - break; - - case 0x30: - switch (es1371->mem_page) - { - case 0x0: case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - case 0x8: case 0x9: case 0xa: case 0xb: - break; - - case 0xc: - es1371->dac[0].addr_latch = val; -// audiopci_log("DAC1 addr %08x\n", val); - break; - - default: - audiopci_log("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); - } - break; - case 0x34: - switch (es1371->mem_page) - { - case 0x0: case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - case 0x8: case 0x9: case 0xa: case 0xb: - break; - - case 0xc: - es1371->dac[0].size = val & 0xffff; - es1371->dac[0].count = val >> 16; - if (es1371->dac[0].count) - es1371->dac[0].count -= 4; - break; - - case 0xd: - es1371->adc.size = val & 0xffff; - es1371->adc.count = val >> 16; - break; - - default: - audiopci_log("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); - } - break; - case 0x38: - switch (es1371->mem_page) - { - case 0x0: case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - case 0x8: case 0x9: case 0xa: case 0xb: - break; - - case 0xc: - es1371->dac[1].addr_latch = val; - break; - - case 0xd: - break; - - default: - audiopci_log("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); - } - break; - case 0x3c: - switch (es1371->mem_page) - { - case 0x0: case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - case 0x8: case 0x9: case 0xa: case 0xb: - break; - - case 0xc: - es1371->dac[1].size = val & 0xffff; - es1371->dac[1].count = val >> 16; - break; - - default: - audiopci_log("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); - } - break; - - default: - audiopci_log("Bad es1371_outl: port=%04x val=%08x\n", port, val); - } -} - -static void capture_event(es1371_t *es1371, int type, int rw, uint16_t port) -{ - es1371->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); - es1371->legacy_ctrl |= type; - if (rw) - es1371->legacy_ctrl |= LEGACY_EVENT_TYPE_RW; - else - es1371->legacy_ctrl &= ~LEGACY_EVENT_TYPE_RW; - es1371->legacy_ctrl |= ((port << LEGACY_EVENT_ADDR_SHIFT) & LEGACY_EVENT_ADDR_MASK); - es1371->legacy_ctrl &= ~LEGACY_INT; - nmi = 1; -// audiopci_log("Event! %s %04x\n", rw ? "write" : "read", port); -} - -static void capture_write_sscape(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_SSCAPE, 1, port); -} -static void capture_write_codec(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_CODEC, 1, port); -} -static void capture_write_sb(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_SB, 1, port); -} -static void capture_write_adlib(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_ADLIB, 1, port); -} -static void capture_write_master_pic(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_MASTER_PIC, 1, port); -} -static void capture_write_master_dma(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_MASTER_DMA, 1, port); -} -static void capture_write_slave_pic(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_SLAVE_PIC, 1, port); -} -static void capture_write_slave_dma(uint16_t port, uint8_t val, void *p) -{ - capture_event(p, LEGACY_EVENT_SLAVE_DMA, 1, port); -} - -static uint8_t capture_read_sscape(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_SSCAPE, 0, port); - return 0xff; -} -static uint8_t capture_read_codec(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_CODEC, 0, port); - return 0xff; -} -static uint8_t capture_read_sb(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_SB, 0, port); - return 0xff; -} -static uint8_t capture_read_adlib(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_ADLIB, 0, port); - return 0xff; -} -static uint8_t capture_read_master_pic(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_MASTER_PIC, 0, port); - return 0xff; -} -static uint8_t capture_read_master_dma(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_MASTER_DMA, 0, port); - return 0xff; -} -static uint8_t capture_read_slave_pic(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_SLAVE_PIC, 0, port); - return 0xff; -} -static uint8_t capture_read_slave_dma(uint16_t port, void *p) -{ - capture_event(p, LEGACY_EVENT_SLAVE_DMA, 0, port); - return 0xff; -} - -static void update_legacy(es1371_t *es1371) -{ - io_removehandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - - io_removehandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - io_removehandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - io_removehandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - - io_removehandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - io_removehandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - - io_removehandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); - - io_removehandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); - io_removehandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); - io_removehandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); - io_removehandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); - - if (es1371->legacy_ctrl & LEGACY_CAPTURE_SSCAPE) - { - switch ((es1371->legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) - { - case 0: io_sethandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; - case 1: io_sethandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; - case 2: io_sethandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; - case 3: io_sethandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; - } - } - if (es1371->legacy_ctrl & LEGACY_CAPTURE_CODEC) - { - switch ((es1371->legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) - { - case 0: io_sethandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; - case 2: io_sethandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; - case 3: io_sethandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; - } - } - if (es1371->legacy_ctrl & LEGACY_CAPTURE_SB) - { - if (!(es1371->legacy_ctrl & LEGACY_SB_ADDR)) - io_sethandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - else - io_sethandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - } - if (es1371->legacy_ctrl & LEGACY_CAPTURE_ADLIB) - io_sethandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); - if (es1371->legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) - io_sethandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); - if (es1371->legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) - io_sethandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); - if (es1371->legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) - io_sethandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); - if (es1371->legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) - io_sethandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); -} - - -static uint8_t es1371_pci_read(int func, int addr, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - - if (func) - return 0; - - //audiopci_log("ES1371 PCI read %08X PC=%08x\n", addr, cpu_state.pc); - - switch (addr) - { - case 0x00: return 0x74; /*Ensoniq*/ - case 0x01: return 0x12; - - case 0x02: return 0x71; /*ES1371*/ - case 0x03: return 0x13; - - case 0x04: return es1371->pci_command; - case 0x05: return es1371->pci_serr; - - case 0x06: return 0x10; /*Supports ACPI*/ - case 0x07: return 0; - - case 0x08: return 2; /*Revision ID*/ - case 0x09: return 0x00; /*Multimedia audio device*/ - case 0x0a: return 0x01; - case 0x0b: return 0x04; - - case 0x10: return 0x01 | (es1371->base_addr & 0xc0); /*memBaseAddr*/ - case 0x11: return es1371->base_addr >> 8; - case 0x12: return es1371->base_addr >> 16; - case 0x13: return es1371->base_addr >> 24; - - case 0x2c: return 0x74; /*Subsystem vendor ID*/ - case 0x2d: return 0x12; - case 0x2e: return 0x71; - case 0x2f: return 0x13; - - case 0x34: return 0xdc; /*Capabilites pointer*/ - - case 0x3c: return es1371->int_line; - case 0x3d: return 0x01; /*INTA*/ - - case 0x3e: return 0xc; /*Minimum grant*/ - case 0x3f: return 0x80; /*Maximum latency*/ - - case 0xdc: return 0x01; /*Capabilities identifier*/ - case 0xdd: return 0x00; /*Next item pointer*/ - case 0xde: return 0x31; /*Power management capabilities*/ - case 0xdf: return 0x6c; - - case 0xe0: return es1371->pmcsr & 0xff; - case 0xe1: return es1371->pmcsr >> 8; - } - return 0; -} - -static void es1371_pci_write(int func, int addr, uint8_t val, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - - if (func) - return; - -// audiopci_log("ES1371 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - - switch (addr) - { - case 0x04: - if (es1371->pci_command & PCI_COMMAND_IO) - io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - es1371->pci_command = val & 0x05; - if (es1371->pci_command & PCI_COMMAND_IO) - io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - break; - case 0x05: - es1371->pci_serr = val & 1; - break; - - case 0x10: - if (es1371->pci_command & PCI_COMMAND_IO) - io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - es1371->base_addr = (es1371->base_addr & 0xffffff00) | (val & 0xc0); - if (es1371->pci_command & PCI_COMMAND_IO) - io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - break; - case 0x11: - if (es1371->pci_command & PCI_COMMAND_IO) - io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - es1371->base_addr = (es1371->base_addr & 0xffff00c0) | (val << 8); - if (es1371->pci_command & PCI_COMMAND_IO) - io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); - break; - case 0x12: - es1371->base_addr = (es1371->base_addr & 0xff00ffc0) | (val << 16); - break; - case 0x13: - es1371->base_addr = (es1371->base_addr & 0x00ffffc0) | (val << 24); - break; - - case 0x3c: - es1371->int_line = val; - break; - - case 0xe0: - es1371->pmcsr = (es1371->pmcsr & 0xff00) | (val & 0x03); - break; - case 0xe1: - es1371->pmcsr = (es1371->pmcsr & 0x00ff) | ((val & 0x01) << 8); - break; - } -// audiopci_log("es1371->base_addr %08x\n", es1371->base_addr); -} - -static void es1371_fetch(es1371_t *es1371, int dac_nr) -{ - int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); - int pos = es1371->dac[dac_nr].buffer_pos & 63; - int c; - -//audiopci_log("Fetch format=%i %08x %08x %08x %08x %08x\n", format, es1371->dac[dac_nr].count, es1371->dac[dac_nr].size, es1371->dac[dac_nr].curr_samp_ct,es1371->dac[dac_nr].samp_ct, es1371->dac[dac_nr].addr); - switch (format) - { - case FORMAT_MONO_8: - for (c = 0; c < 32; c += 4) - { - es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+1) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_l[(pos+c+2) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+2) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+2) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_l[(pos+c+3) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+3) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+3) ^ 0x80) << 8; - es1371->dac[dac_nr].addr += 4; - - es1371->dac[dac_nr].buffer_pos_end += 4; - es1371->dac[dac_nr].count++; - if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) - { - es1371->dac[dac_nr].count = 0; - es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; - break; - } - } - break; - case FORMAT_STEREO_8: - for (c = 0; c < 16; c += 2) - { - es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 1) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 2) ^ 0x80) << 8; - es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 3) ^ 0x80) << 8; - es1371->dac[dac_nr].addr += 4; - - es1371->dac[dac_nr].buffer_pos_end += 2; - es1371->dac[dac_nr].count++; - if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) - { - es1371->dac[dac_nr].count = 0; - es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; - break; - } - } - break; - case FORMAT_MONO_16: - for (c = 0; c < 16; c += 2) - { - es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr); - es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr + 2); - es1371->dac[dac_nr].addr += 4; - - es1371->dac[dac_nr].buffer_pos_end += 2; - es1371->dac[dac_nr].count++; - if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) - { - es1371->dac[dac_nr].count = 0; - es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; - break; - } - } - break; - case FORMAT_STEREO_16: - for (c = 0; c < 4; c++) - { - es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr); - es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr + 2); -// audiopci_log("Fetch %02x %08x %04x %04x\n", (pos+c) & 63, es1371->dac[dac_nr].addr, es1371->dac[dac_nr].buffer_l[(pos+c) & 63], es1371->dac[dac_nr].buffer_r[(pos+c) & 63]); - es1371->dac[dac_nr].addr += 4; - - es1371->dac[dac_nr].buffer_pos_end++; - es1371->dac[dac_nr].count++; - if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) - { - es1371->dac[dac_nr].count = 0; - es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; - break; - } - } - break; - } -} - -static inline float low_fir_es1371(int dac_nr, int i, float NewSample) -{ - static float x[2][2][128]; //input samples - static int x_pos[2] = {0, 0}; - float out = 0.0; - int read_pos; - int n_coef; - int pos = x_pos[dac_nr]; - - x[dac_nr][i][pos] = NewSample; - - /*Since only 1/16th of input samples are non-zero, only filter those that - are valid.*/ - read_pos = (pos + 15) & (127 & ~15); - n_coef = (16 - pos) & 15; - - while (n_coef < ES1371_NCoef) - { - out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; - read_pos = (read_pos + 16) & (127 & ~15); - n_coef += 16; - } - - if (i == 1) - { - x_pos[dac_nr] = (x_pos[dac_nr] + 1) & 127; - if (x_pos[dac_nr] > 127) - x_pos[dac_nr] = 0; - } - - return out; -} - -static void es1371_next_sample_filtered(es1371_t *es1371, int dac_nr, int out_idx) -{ - int out_l, out_r; - int c; - - if ((es1371->dac[dac_nr].buffer_pos - es1371->dac[dac_nr].buffer_pos_end) >= 0) - { - es1371_fetch(es1371, dac_nr); - } - - out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; - out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; - - es1371->dac[dac_nr].filtered_l[out_idx] = (int)low_fir_es1371(dac_nr, 0, (float)out_l); - es1371->dac[dac_nr].filtered_r[out_idx] = (int)low_fir_es1371(dac_nr, 1, (float)out_r); - for (c = 1; c < 16; c++) - { - es1371->dac[dac_nr].filtered_l[out_idx+c] = (int)low_fir_es1371(dac_nr, 0, 0); - es1371->dac[dac_nr].filtered_r[out_idx+c] = (int)low_fir_es1371(dac_nr, 1, 0); - } - -// audiopci_log("Use %02x %04x %04x\n", es1371->dac[dac_nr].buffer_pos & 63, es1371->dac[dac_nr].out_l, es1371->dac[dac_nr].out_r); - - es1371->dac[dac_nr].buffer_pos++; -// audiopci_log("Next sample %08x %08x %08x\n", es1371->dac[dac_nr].buffer_pos, es1371->dac[dac_nr].buffer_pos_end, es1371->dac[dac_nr].curr_samp_ct); -} - -//static FILE *es1371_f;//,*es1371_f2; - -static void es1371_update(es1371_t *es1371) -{ - int32_t l, r; - - l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; - l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); - r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; - r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); - - l >>= 1; - r >>= 1; - - l = (l * es1371->master_vol_l) >> 15; - r = (r * es1371->master_vol_r) >> 15; - - if (l < -32768) - l = -32768; - else if (l > 32767) - l = 32767; - if (r < -32768) - r = -32768; - else if (r > 32767) - r = 32767; - - for (; es1371->pos < sound_pos_global; es1371->pos++) - { - es1371->buffer[es1371->pos*2] = l; - es1371->buffer[es1371->pos*2 + 1] = r; - } -} - -static void es1371_poll(void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - - es1371->dac[1].time += es1371->dac[1].latch; - - es1371_update(es1371); - - if (es1371->int_ctrl & INT_DAC1_EN) - { - int frac = es1371->dac[0].ac & 0x7fff; - int idx = es1371->dac[0].ac >> 15; - int samp1_l = es1371->dac[0].filtered_l[idx]; - int samp1_r = es1371->dac[0].filtered_r[idx]; - int samp2_l = es1371->dac[0].filtered_l[(idx + 1) & 31]; - int samp2_r = es1371->dac[0].filtered_r[(idx + 1) & 31]; - - es1371->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - es1371->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; -// audiopci_log("1Samp %i %i %08x\n", es1371->dac[0].curr_samp_ct, es1371->dac[0].samp_ct, es1371->dac[0].ac); - es1371->dac[0].ac += es1371->dac[0].vf; - es1371->dac[0].ac &= ((32 << 15) - 1); - if ((es1371->dac[0].ac >> (15+4)) != es1371->dac[0].f_pos) - { - es1371_next_sample_filtered(es1371, 0, es1371->dac[0].f_pos ? 16 : 0); - es1371->dac[0].f_pos = (es1371->dac[0].f_pos + 1) & 1; - - es1371->dac[0].curr_samp_ct++; - if (es1371->dac[0].curr_samp_ct == es1371->dac[0].samp_ct) - { -// audiopci_log("DAC1 IRQ\n"); - es1371->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(es1371); - } - if (es1371->dac[0].curr_samp_ct > es1371->dac[0].samp_ct) - { - es1371->dac[0].curr_samp_ct = 0; - } - } - } - - if (es1371->int_ctrl & INT_DAC2_EN) - { - int frac = es1371->dac[1].ac & 0x7fff; - int idx = es1371->dac[1].ac >> 15; - int samp1_l = es1371->dac[1].filtered_l[idx]; - int samp1_r = es1371->dac[1].filtered_r[idx]; - int samp2_l = es1371->dac[1].filtered_l[(idx + 1) & 31]; - int samp2_r = es1371->dac[1].filtered_r[(idx + 1) & 31]; - - es1371->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - es1371->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; -// audiopci_log("2Samp %i %i %08x\n", es1371->dac[1].curr_samp_ct, es1371->dac[1].samp_ct, es1371->dac[1].ac); - es1371->dac[1].ac += es1371->dac[1].vf; - es1371->dac[1].ac &= ((32 << 15) - 1); - if ((es1371->dac[1].ac >> (15+4)) != es1371->dac[1].f_pos) - { - es1371_next_sample_filtered(es1371, 1, es1371->dac[1].f_pos ? 16 : 0); - es1371->dac[1].f_pos = (es1371->dac[1].f_pos + 1) & 1; - - es1371->dac[1].curr_samp_ct++; - if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) - { -// es1371->dac[1].curr_samp_ct = 0; -// audiopci_log("DAC2 IRQ\n"); - es1371->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(es1371); - } - if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) - es1371->dac[1].curr_samp_ct = 0; - } - } -} - -static void es1371_get_buffer(int32_t *buffer, int len, void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - int c; - - es1371_update(es1371); - - for (c = 0; c < len * 2; c++) - buffer[c] += (es1371->buffer[c] / 2); - - es1371->pos = 0; -} - -static inline double sinc(double x) -{ - return sin(M_PI * x) / (M_PI * x); -} - -static void generate_es1371_filter() -{ - /*Cutoff frequency = 1 / 32*/ - float fC = 1.0 / 32.0; - float gain; - int n; - - for (n = 0; n < ES1371_NCoef; n++) - { - /*Blackman window*/ - double w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(ES1371_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(ES1371_NCoef-1))); - /*Sinc filter*/ - double h = sinc(2.0 * fC * ((double)n - ((double)(ES1371_NCoef-1) / 2.0))); - - /*Create windowed-sinc filter*/ - low_fir_es1371_coef[n] = w * h; - } - - low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; - - gain = 0.0; - for (n = 0; n < ES1371_NCoef; n++) - gain += low_fir_es1371_coef[n] / (float)N; - - gain /= 0.95; - - /*Normalise filter, to produce unity gain*/ - for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; -} - -static void *es1371_init() -{ - es1371_t *es1371 = malloc(sizeof(es1371_t)); - memset(es1371, 0, sizeof(es1371_t)); - - sound_add_handler(es1371_get_buffer, es1371); - - es1371->card = pci_add_card(PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, es1371); - - timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371); - - generate_es1371_filter(); - - return es1371; -} - -static void es1371_close(void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - - free(es1371); -} - -static void es1371_speed_changed(void *p) -{ - es1371_t *es1371 = (es1371_t *)p; - - es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); -} - -void es1371_add_status_info_dac(es1371_t *es1371, char *s, int max_len, int dac_nr) -{ - int ena = dac_nr ? INT_DAC2_EN : INT_DAC1_EN; - char *dac_name = dac_nr ? "DAC2 (Wave)" : "DAC1 (MIDI)"; - char temps[128]; - - if (es1371->int_ctrl & ena) - { - int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); - double freq = 48000.0 * ((double)es1371->dac[dac_nr].vf / (32768.0 * 16.0)); - - switch (format) - { - case FORMAT_MONO_8: - snprintf(temps, 128, "%s format : 8-bit mono\n", dac_name); - break; - case FORMAT_STEREO_8: - snprintf(temps, 128, "%s format : 8-bit stereo\n", dac_name); - break; - case FORMAT_MONO_16: - snprintf(temps, 128, "%s format : 16-bit mono\n", dac_name); - break; - case FORMAT_STEREO_16: - snprintf(temps, 128, "%s format : 16-bit stereo\n", dac_name); - break; - } - - strncat(s, temps, max_len); - max_len -= strlen(temps); - - snprintf(temps, 128, "Playback frequency : %i Hz\n", (int)freq); - strncat(s, temps, max_len); - } - else - { - snprintf(temps, max_len, "%s stopped\n", dac_name); - strncat(s, temps, max_len); - } -} - -const device_t es1371_device = -{ - "Ensoniq AudioPCI (ES1371)", - DEVICE_PCI, - 0, - es1371_init, - es1371_close, - NULL, - NULL, - es1371_speed_changed, - NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_audiopci.h b/src - Cópia/sound/snd_audiopci.h deleted file mode 100644 index 66600ed24..000000000 --- a/src - Cópia/sound/snd_audiopci.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t es1371_device; diff --git a/src - Cópia/sound/snd_cms.c b/src - Cópia/sound/snd_cms.c deleted file mode 100644 index 5d3e73c8d..000000000 --- a/src - Cópia/sound/snd_cms.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" -#include "sound.h" -#include "snd_cms.h" - - -#define MASTER_CLOCK 7159090 - - -typedef struct cms_t -{ - int addrs[2]; - uint8_t regs[2][32]; - uint16_t latch[2][6]; - int freq[2][6]; - float count[2][6]; - int vol[2][6][2]; - int stat[2][6]; - uint16_t noise[2][2]; - uint16_t noisefreq[2][2]; - int noisecount[2][2]; - int noisetype[2][2]; - - uint8_t latched_data; - - int16_t buffer[SOUNDBUFLEN * 2]; - - int pos; -} cms_t; - -void cms_update(cms_t *cms) -{ - for (; cms->pos < sound_pos_global; cms->pos++) - { - int c, d; - int16_t out_l = 0, out_r = 0; - - for (c = 0; c < 4; c++) - { - switch (cms->noisetype[c >> 1][c & 1]) - { - case 0: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/256; break; - case 1: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/512; break; - case 2: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/1024; break; - case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; - } - } - for (c = 0; c < 2; c ++) - { - if (cms->regs[c][0x1C] & 1) - { - for (d = 0; d < 6; d++) - { - if (cms->regs[c][0x14] & (1 << d)) - { - if (cms->stat[c][d]) out_l += (cms->vol[c][d][0] * 90); - if (cms->stat[c][d]) out_r += (cms->vol[c][d][1] * 90); - cms->count[c][d] += cms->freq[c][d]; - if (cms->count[c][d] >= 24000) - { - cms->count[c][d] -= 24000; - cms->stat[c][d] ^= 1; - } - } - else if (cms->regs[c][0x15] & (1 << d)) - { - if (cms->noise[c][d / 3] & 1) out_l += (cms->vol[c][d][0] * 90); - if (cms->noise[c][d / 3] & 1) out_r += (cms->vol[c][d][0] * 90); - } - } - for (d = 0; d < 2; d++) - { - cms->noisecount[c][d] += cms->noisefreq[c][d]; - while (cms->noisecount[c][d] >= 24000) - { - cms->noisecount[c][d] -= 24000; - cms->noise[c][d] <<= 1; - if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) - cms->noise[c][d] |= 1; - } - } - } - } - cms->buffer[(cms->pos << 1)] = out_l; - cms->buffer[(cms->pos << 1) + 1] = out_r; - } -} - -void cms_get_buffer(int32_t *buffer, int len, void *p) -{ - cms_t *cms = (cms_t *)p; - - int c; - - cms_update(cms); - - for (c = 0; c < len * 2; c++) - buffer[c] += cms->buffer[c]; - - cms->pos = 0; -} - -void cms_write(uint16_t addr, uint8_t val, void *p) -{ - cms_t *cms = (cms_t *)p; - int voice; - int chip = (addr & 2) >> 1; - - switch (addr & 0xf) - { - case 1: - cms->addrs[0] = val & 31; - break; - case 3: - cms->addrs[1] = val & 31; - break; - - case 0: case 2: - cms_update(cms); - cms->regs[chip][cms->addrs[chip] & 31] = val; - switch (cms->addrs[chip] & 31) - { - case 0x00: case 0x01: case 0x02: /*Volume*/ - case 0x03: case 0x04: case 0x05: - voice = cms->addrs[chip] & 7; - cms->vol[chip][voice][0] = val & 0xf; - cms->vol[chip][voice][1] = val >> 4; - break; - case 0x08: case 0x09: case 0x0A: /*Frequency*/ - case 0x0B: case 0x0C: case 0x0D: - voice = cms->addrs[chip] & 7; - cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; - cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - break; - case 0x10: case 0x11: case 0x12: /*Octave*/ - voice = (cms->addrs[chip] & 3) << 1; - cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); - cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); - cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - cms->freq[chip][voice + 1] = (MASTER_CLOCK/512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); - break; - case 0x16: /*Noise*/ - cms->noisetype[chip][0] = val & 3; - cms->noisetype[chip][1] = (val >> 4) & 3; - break; - } - break; - case 0x6: case 0x7: - cms->latched_data = val; - break; - } -} - -uint8_t cms_read(uint16_t addr, void *p) -{ - cms_t *cms = (cms_t *)p; - - switch (addr & 0xf) - { - case 0x1: - return cms->addrs[0]; - case 0x3: - return cms->addrs[1]; - case 0x4: - return 0x7f; - case 0xa: case 0xb: - return cms->latched_data; - } - return 0xff; -} - -void *cms_init(const device_t *info) -{ - cms_t *cms = malloc(sizeof(cms_t)); - memset(cms, 0, sizeof(cms_t)); - - io_sethandler(0x0220, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); - sound_add_handler(cms_get_buffer, cms); - return cms; -} - -void cms_close(void *p) -{ - cms_t *cms = (cms_t *)p; - - free(cms); -} - -const device_t cms_device = -{ - "Creative Music System / Game Blaster", - 0, 0, - cms_init, cms_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_cms.h b/src - Cópia/sound/snd_cms.h deleted file mode 100644 index 41b6d6059..000000000 --- a/src - Cópia/sound/snd_cms.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t cms_device; diff --git a/src - Cópia/sound/snd_dbopl.cc b/src - Cópia/sound/snd_dbopl.cc deleted file mode 100644 index 78840f4a6..000000000 --- a/src - Cópia/sound/snd_dbopl.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ -#include "dbopl.h" -#include "nukedopl.h" -#include "sound.h" -#include "snd_dbopl.h" - - -int opl_type = 0; - - -static struct -{ - DBOPL::Chip chip; - opl3_chip opl3chip; - int addr; - int timer[2]; - uint8_t timer_ctrl; - uint8_t status_mask; - uint8_t status; - int is_opl3; - - void (*timer_callback)(void *param, int timer, int64_t period); - void *timer_param; -} opl[2]; - -enum -{ - STATUS_TIMER_1 = 0x40, - STATUS_TIMER_2 = 0x20, - STATUS_TIMER_ALL = 0x80 -}; - -enum -{ - CTRL_IRQ_RESET = 0x80, - CTRL_TIMER1_MASK = 0x40, - CTRL_TIMER2_MASK = 0x20, - CTRL_TIMER2_CTRL = 0x02, - CTRL_TIMER1_CTRL = 0x01 -}; - -void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3) -{ - opl[nr].timer_callback = timer_callback; - opl[nr].timer_param = timer_param; - opl[nr].is_opl3 = is_opl3; - - if (!opl_type) - { - DBOPL::InitTables(); - opl[nr].chip.Setup(48000, is_opl3); - } - else - { - opl[nr].opl3chip.newm = 0; - OPL3_Reset(&opl[nr].opl3chip, 48000); - } -} - -void opl_status_update(int nr) -{ - if (opl[nr].status & (STATUS_TIMER_1 | STATUS_TIMER_2) & opl[nr].status_mask) - opl[nr].status |= STATUS_TIMER_ALL; - else - opl[nr].status &= ~STATUS_TIMER_ALL; -} - -void opl_timer_over(int nr, int timer) -{ - if (!timer) - { - opl[nr].status |= STATUS_TIMER_1; - opl[nr].timer_callback(opl[nr].timer_param, 0, opl[nr].timer[0] * 4); - } - else - { - opl[nr].status |= STATUS_TIMER_2; - opl[nr].timer_callback(opl[nr].timer_param, 1, opl[nr].timer[1] * 16); - } - - opl_status_update(nr); -} - -void opl_write(int nr, uint16_t addr, uint8_t val) -{ - if (!(addr & 1)) - { - if (!opl_type) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0x1ff; - else - opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; - if (!opl[nr].is_opl3) - opl[nr].addr &= 0xff; - } - else - { - if (!opl_type) - opl[nr].chip.WriteReg(opl[nr].addr, val); - else { - OPL3_WriteRegBuffered(&opl[nr].opl3chip, (uint16_t) opl[nr].addr, val); - if (opl[nr].addr == 0x105) - opl[nr].opl3chip.newm = opl[nr].addr & 0x01; - } - - switch (opl[nr].addr) - { - case 0x02: /*Timer 1*/ - opl[nr].timer[0] = 256 - val; - break; - case 0x03: /*Timer 2*/ - opl[nr].timer[1] = 256 - val; - break; - case 0x04: /*Timer control*/ - if (val & CTRL_IRQ_RESET) /*IRQ reset*/ - { - opl[nr].status &= ~(STATUS_TIMER_1 | STATUS_TIMER_2); - opl_status_update(nr); - return; - } - if ((val ^ opl[nr].timer_ctrl) & CTRL_TIMER1_CTRL) - { - if (val & CTRL_TIMER1_CTRL) - opl[nr].timer_callback(opl[nr].timer_param, 0, opl[nr].timer[0] * 4); - else - opl[nr].timer_callback(opl[nr].timer_param, 0, 0); - } - if ((val ^ opl[nr].timer_ctrl) & CTRL_TIMER2_CTRL) - { - if (val & CTRL_TIMER2_CTRL) - opl[nr].timer_callback(opl[nr].timer_param, 1, opl[nr].timer[1] * 16); - else - opl[nr].timer_callback(opl[nr].timer_param, 1, 0); - } - opl[nr].status_mask = (~val & (CTRL_TIMER1_MASK | CTRL_TIMER2_MASK)) | 0x80; - opl[nr].timer_ctrl = val; - break; - } - } - -} - -uint8_t opl_read(int nr, uint16_t addr) -{ - if (!(addr & 1)) - { - return (opl[nr].status & opl[nr].status_mask) | (opl[nr].is_opl3 ? 0 : 0x06); - } - return opl[nr].is_opl3 ? 0 : 0xff; -} - -void opl2_update(int nr, int16_t *buffer, int samples) -{ - int c; - Bit32s buffer_32[SOUNDBUFLEN]; - - if (opl_type) - { - OPL3_GenerateStream(&opl[nr].opl3chip, buffer, samples); - } - else - { - opl[nr].chip.GenerateBlock2(samples, buffer_32); - - for (c = 0; c < samples; c++) - buffer[c*2] = (int16_t)buffer_32[c]; - } -} - -void opl3_update(int nr, int16_t *buffer, int samples) -{ - int c; - Bit32s buffer_32[SOUNDBUFLEN*2]; - - if (opl_type) - { - OPL3_GenerateStream(&opl[nr].opl3chip, buffer, samples); - } - else - { - opl[nr].chip.GenerateBlock3(samples, buffer_32); - - for (c = 0; c < samples*2; c++) - buffer[c] = (int16_t)buffer_32[c]; - } -} diff --git a/src - Cópia/sound/snd_dbopl.h b/src - Cópia/sound/snd_dbopl.h deleted file mode 100644 index ca6299724..000000000 --- a/src - Cópia/sound/snd_dbopl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3); - void opl_write(int nr, uint16_t addr, uint8_t val); - uint8_t opl_read(int nr, uint16_t addr); - void opl_timer_over(int nr, int timer); - void opl2_update(int nr, int16_t *buffer, int samples); - void opl3_update(int nr, int16_t *buffer, int samples); - - extern int opl_type; -#ifdef __cplusplus -} -#endif diff --git a/src - Cópia/sound/snd_emu8k.c b/src - Cópia/sound/snd_emu8k.c deleted file mode 100644 index d273e4953..000000000 --- a/src - Cópia/sound/snd_emu8k.c +++ /dev/null @@ -1,2386 +0,0 @@ -#include -#include -#include -#include -#include -#include -#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 "sound.h" -#include "snd_emu8k.h" - - -#if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT -//#define FILTER_INITIAL -#define FILTER_MOOG -//#define FILTER_CONSTANT -#endif - -#if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC -//#define RESAMPLER_LINEAR -#define RESAMPLER_CUBIC -#endif - -//#define EMU8K_DEBUG_REGISTERS - -char *PORT_NAMES[][8] = -{ - /* Data 0 ( 0x620/0x622) */ - { "AWE_CPF", - "AWE_PTRX", - "AWE_CVCF", - "AWE_VTFT", - "Unk-620-4", - "Unk-620-5", - "AWE_PSST", - "AWE_CSL", - }, - /* Data 1 0xA20 */ - { "AWE_CCCA", - 0, - /* - "AWE_HWCF4" - "AWE_HWCF5" - "AWE_HWCF6" - "AWE_HWCF7" - "AWE_SMALR" - "AWE_SMARR" - "AWE_SMALW" - "AWE_SMARW" - "AWE_SMLD" - "AWE_SMRD" - "AWE_WC" - "AWE_HWCF1" - "AWE_HWCF2" - "AWE_HWCF3" - */ - 0,//"AWE_INIT1", - 0,//"AWE_INIT3", - "AWE_ENVVOL", - "AWE_DCYSUSV", - "AWE_ENVVAL", - "AWE_DCYSUS", - }, - /* Data 2 0xA22 */ - { "AWE_CCCA", - 0, - 0,//"AWE_INIT2", - 0,//"AWE_INIT4", - "AWE_ATKHLDV", - "AWE_LFO1VAL", - "AWE_ATKHLD", - "AWE_LFO2VAL", - }, - /* Data 3 0xE20 */ - { "AWE_IP", - "AWE_IFATN", - "AWE_PEFE", - "AWE_FMMOD", - "AWE_TREMFRQ", - "AWE_FM2FRQ2", - 0, - 0, - }, -}; - -enum -{ - ENV_STOPPED = 0, - ENV_DELAY = 1, - ENV_ATTACK = 2, - ENV_HOLD = 3, - //ENV_DECAY = 4, - ENV_SUSTAIN = 5, - //ENV_RELEASE = 6, - ENV_RAMP_DOWN = 7, - ENV_RAMP_UP = 8 -}; - - -static int random_helper = 0; -int dmareadbit = 0; -int dmawritebit = 0; - - -/* cubic and linear tables resolution. Note: higher than 10 does not improve the result. */ -#define CUBIC_RESOLUTION_LOG 10 -#define CUBIC_RESOLUTION (1<> 15 to move back to +/-1 range). */ -static int32_t lfotable[65536]; -/* Table to transform the speed parameter to emu8k_mem_internal_t range. */ -static int64_t lfofreqtospeed[256]; - -/* LFO used for the chorus. a sine wave.(signed 16bits with 32768 max int. >> 15 to move back to +/-1 range). */ -static double chortable[65536]; - -static const int REV_BUFSIZE_STEP=242; - - -/* These lines come from the awe32faq, describing the NRPN control for the initial filter - * where it describes a linear increment filter instead of an octave-incremented one. - * NRPN LSB 21 (Initial Filter Cutoff) - * Range : [0, 127] - * Unit : 62Hz - * Filter cutoff from 100Hz to 8000Hz - - * This table comes from the awe32faq, describing the NRPN control for the filter Q. - * I don't know if is meant to be interpreted as the actual measured output of the - * filter or what. Especially, I don't understand the "low" and "high" ranges. - * What is otherwise documented is that the Q ranges from 0dB to 24dB and the attenuation - * is half of the Q ( i.e. for 12dB Q, attenuate the input signal with -6dB) -Coeff Low Fc(Hz)Low Q(dB)High Fc(kHz)High Q(dB)DC Attenuation(dB) -* 0 92 5 Flat Flat -0.0 -* 1 93 6 8.5 0.5 -0.5 -* 2 94 8 8.3 1 -1.2 -* 3 95 10 8.2 2 -1.8 -* 4 96 11 8.1 3 -2.5 -* 5 97 13 8.0 4 -3.3 -* 6 98 14 7.9 5 -4.1 -* 7 99 16 7.8 6 -5.5 -* 8 100 17 7.7 7 -6.0 -* 9 100 19 7.5 9 -6.6 -* 10 100 20 7.4 10 -7.2 -* 11 100 22 7.3 11 -7.9 -* 12 100 23 7.2 13 -8.5 -* 13 100 25 7.1 15 -9.3 -* 14 100 26 7.1 16 -10.1 -* 15 100 28 7.0 18 -11.0 -* -* Attenuation as above, codified in amplitude.*/ -static int32_t filter_atten[16] = -{ - 65536, 61869, 57079, 53269, 49145, 44820, 40877, 34792, 32845, 30653, 28607, - 26392, 24630, 22463, 20487, 18470 -}; - -/*Coefficients for the filters for a defined Q and cutoff.*/ -static int32_t filt_coeffs[16][256][3]; - -#define READ16_SWITCH(addr, var) switch ((addr) & 2) \ - { \ - case 0: ret = (var) & 0xffff; break; \ - case 2: ret = ((var) >> 16) & 0xffff; break; \ - } - -#define WRITE16_SWITCH(addr, var, val) switch ((addr) & 2) \ - { \ - case 0: var = (var & 0xffff0000) | (val); break; \ - case 2: var = (var & 0x0000ffff) | ((val) << 16); break; \ - } - -#ifdef EMU8K_DEBUG_REGISTERS -uint32_t dw_value = 0; -uint32_t last_read = 0; -uint32_t last_write = 0; -uint32_t rep_count_r = 0; -uint32_t rep_count_w = 0; - -# define READ16(addr, var) READ16_SWITCH(addr, var) \ - { \ - const char *name=0; \ - switch(addr&0xF02) \ - { \ - case 0x600: case 0x602: \ - name = PORT_NAMES[0][emu8k->cur_reg]; \ - break; \ - case 0xA00: \ - name = PORT_NAMES[1][emu8k->cur_reg]; \ - break; \ - case 0xA02: \ - name = PORT_NAMES[2][emu8k->cur_reg]; \ - break; \ - } \ - if (name == 0) \ - { \ - /*emu8k_log("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ - } \ - else \ - { \ - emu8k_log("EMU8K READ %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice, ret); \ - }\ - } -# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) \ - { \ - const char *name=0; \ - switch(addr&0xF02) \ - { \ - case 0x600: case 0x602: \ - name = PORT_NAMES[0][emu8k->cur_reg]; \ - break; \ - case 0xA00: \ - name = PORT_NAMES[1][emu8k->cur_reg]; \ - break; \ - case 0xA02: \ - name = PORT_NAMES[2][emu8k->cur_reg]; \ - break; \ - } \ - if (name == 0) \ - { \ - /*emu8k_log("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ - } \ - else \ - { \ - emu8k_log("EMU8K WRITE %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice,val); \ - }\ - } - -#else -# define READ16(addr, var) READ16_SWITCH(addr, var) -# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) -#endif //EMU8K_DEBUG_REGISTERS - - -#ifdef ENABLE_EMU8K_LOG -int emu8k_do_log = ENABLE_EMU8K_LOG; -#endif - - -static void -emu8k_log(const char *fmt, ...) -{ -#ifdef ENABLE_EMU8K_LOG - va_list ap; - - if (emu8k_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) -{ - const register emu8k_mem_pointers_t addrmem = {{addr}}; - return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; -} - -#if NOTUSED -static inline int16_t EMU8K_READ_INTERP_LINEAR(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) -{ - /* The interpolation in AWE32 used a so-called patented 3-point interpolation - * ( I guess some sort of spline having one point before and one point after). - * Also, it has the consequence that the playback is delayed by one sample. - * I simulate the "one sample later" than the address with addr+1 and addr+2 - * instead of +0 and +1 */ - int16_t dat1 = EMU8K_READ(emu8k, int_addr+1); - int32_t dat2 = EMU8K_READ(emu8k, int_addr+2); - dat1 += ((dat2-(int32_t)dat1)* fract) >> 16; - return dat1; -} -#endif - -static inline int32_t EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) -{ - /*Since there are four floats in the table for each fraction, the position is 16byte aligned. */ - fract >>= 16-CUBIC_RESOLUTION_LOG; - fract <<=2; - - /* TODO: I still have to verify how this works, but I think that - * the card could use two oscillators (usually 31 and 32) where it would - * be writing the OPL3 output, and to which, chorus and reverb could be applied to get - * those effects for OPL3 sounds.*/ -// if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} - - /* This is cubic interpolation. - * Not the same than 3-point interpolation, but a better approximation than linear - * interpolation. - * Also, it takes into account the "Note that the actual audio location is the point - * 1 word higher than this value due to interpolation offset". - * That's why the pointers are 0, 1, 2, 3 and not -1, 0, 1, 2 */ - int32_t dat2 = EMU8K_READ(emu8k, int_addr+1); - const float *table = &cubic_table[fract]; - const int32_t dat1 = EMU8K_READ(emu8k, int_addr); - const int32_t dat3 = EMU8K_READ(emu8k, int_addr+2); - const int32_t dat4 = EMU8K_READ(emu8k, int_addr+3); - /* Note: I've ended using float for the table values to avoid some cases of integer overflow. */ - dat2 = dat1*table[0] + dat2*table[1] + dat3*table[2] + dat4*table[3]; - return dat2; -} - -static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) -{ - addr &= EMU8K_MEM_ADDRESS_MASK; - if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START || addr >= EMU8K_FM_MEM_ADDRESS ) - return; - - /* It looks like if an application writes to a memory part outside of the available - * amount on the card, it wraps, and opencubicplayer uses that to detect the amount - * of memory, as opposed to simply check at the address that it has just tried to write. */ - while (addr >= emu8k->ram_end_addr) - addr -= emu8k->ram_end_addr - EMU8K_RAM_MEM_START; - - emu8k->ram[addr - EMU8K_RAM_MEM_START] = val; -} - -uint16_t emu8k_inw(uint16_t addr, void *p) -{ - emu8k_t *emu8k = (emu8k_t *)p; - uint16_t ret = 0xffff; - -#ifdef EMU8K_DEBUG_REGISTERS - if (addr == 0xE22) - { - emu8k_log("EMU8K READ POINTER: %d\n", - ((0x80 | ((random_helper + 1) & 0x1F)) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice); - } - else if ((addr&0xF00) == 0x600) - { - /* These are automatically reported by READ16 */ - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) - { - /* These are automatically reported by READ16 */ - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) - { - uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); - if (tmpz != last_read) - { - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - emu8k_log("EMU8K READ RAM I/O or configuration or clock \n"); - } - //emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - } - else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) - { - uint32_t tmpz = ((addr&0xF00) << 16); - if (tmpz != last_read) - { - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - emu8k_log("EMU8K READ INIT \n"); - } - //emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - } - else - { - uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; - if (tmpz != last_read) - { - char* name = 0; - uint16_t val = 0xBAAD; - if (addr == 0xA20) - { - name = PORT_NAMES[1][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 2: val = emu8k->init1[emu8k->cur_voice]; break; - case 3: val = emu8k->init3[emu8k->cur_voice]; break; - case 4: val = emu8k->voice[emu8k->cur_voice].envvol; break; - case 5: val = emu8k->voice[emu8k->cur_voice].dcysusv; break; - case 6: val = emu8k->voice[emu8k->cur_voice].envval; break; - case 7: val = emu8k->voice[emu8k->cur_voice].dcysus; break; - } - } - else if (addr == 0xA22) - { - name = PORT_NAMES[2][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 2: val = emu8k->init2[emu8k->cur_voice]; break; - case 3: val = emu8k->init4[emu8k->cur_voice]; break; - case 4: val = emu8k->voice[emu8k->cur_voice].atkhldv; break; - case 5: val = emu8k->voice[emu8k->cur_voice].lfo1val; break; - case 6: val = emu8k->voice[emu8k->cur_voice].atkhld; break; - case 7: val = emu8k->voice[emu8k->cur_voice].lfo2val; break; - } - } - else if (addr == 0xE20) - { - name = PORT_NAMES[3][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 0: val = emu8k->voice[emu8k->cur_voice].ip; break; - case 1: val = emu8k->voice[emu8k->cur_voice].ifatn; break; - case 2: val = emu8k->voice[emu8k->cur_voice].pefe; break; - case 3: val = emu8k->voice[emu8k->cur_voice].fmmod; break; - case 4: val = emu8k->voice[emu8k->cur_voice].tremfrq; break; - case 5: val = emu8k->voice[emu8k->cur_voice].fm2frq2;break; - case 6: val = 0xffff; break; - case 7: val = 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); break; - } - } - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - } - if (name == 0) - { - emu8k_log("EMU8K READ %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice,val); - } - else - { - emu8k_log("EMU8K READ %s (%d): %04X\n",name,emu8k->cur_voice, val); - } - - rep_count_r=0; - last_read=tmpz; - } - rep_count_r++; - } -#endif // EMU8K_DEBUG_REGISTERS - - - switch (addr & 0xF02) - { - case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); - return ret; - - case 1: - READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); - return ret; - - case 2: - READ16(addr, emu8k->voice[emu8k->cur_voice].cvcf); - return ret; - - case 3: - READ16(addr, emu8k->voice[emu8k->cur_voice].vtft); - return ret; - - case 4: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); - return ret; - - case 5: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); - return ret; - - case 6: - READ16(addr, emu8k->voice[emu8k->cur_voice].psst); - return ret; - - case 7: - READ16(addr, emu8k->voice[emu8k->cur_voice].csl); - return ret; - } - break; - - case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; - - case 1: - switch (emu8k->cur_voice) - { - case 9: - READ16(addr, emu8k->hwcf4); - return ret; - case 10: - READ16(addr, emu8k->hwcf5); - return ret; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ - case 13: - READ16(addr, emu8k->hwcf6); - return ret; - case 14: - READ16(addr, emu8k->hwcf7); - return ret; - - case 20: - READ16(addr, emu8k->smalr); - return ret; - case 21: - READ16(addr, emu8k->smarr); - return ret; - case 22: - READ16(addr, emu8k->smalw); - return ret; - case 23: - READ16(addr, emu8k->smarw); - return ret; - - case 26: - { - uint16_t val = emu8k->smld_buffer; - emu8k->smld_buffer = EMU8K_READ(emu8k, emu8k->smalr); - emu8k->smalr = (emu8k->smalr+1) & EMU8K_MEM_ADDRESS_MASK; - return val; - } - - /*The EMU8000 PGM describes the return values of these registers as 'a VLSI error'*/ - case 29: /*Configuration Word 1*/ - return (emu8k->hwcf1 & 0xfe) | (emu8k->hwcf3 & 0x01); - case 30: /*Configuration Word 2*/ - return ((emu8k->hwcf2 >> 4) & 0x0e) | (emu8k->hwcf1 & 0x01) | ((emu8k->hwcf3 & 0x02) ? 0x10 : 0) | ((emu8k->hwcf3 & 0x04) ? 0x40 : 0) - | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); - case 31: /*Configuration Word 3*/ - return emu8k->hwcf2 & 0x1f; - } - break; - - case 2: - return emu8k->init1[emu8k->cur_voice]; - - case 3: - return emu8k->init3[emu8k->cur_voice]; - - case 4: - return emu8k->voice[emu8k->cur_voice].envvol; - - case 5: - return emu8k->voice[emu8k->cur_voice].dcysusv; - - case 6: - return emu8k->voice[emu8k->cur_voice].envval; - - case 7: - return emu8k->voice[emu8k->cur_voice].dcysus; - } - break; - - case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; - - case 1: - switch (emu8k->cur_voice) - { - case 9: - READ16(addr, emu8k->hwcf4); - return ret; - case 10: - READ16(addr, emu8k->hwcf5); - return ret; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ - case 13: - READ16(addr, emu8k->hwcf6); - return ret; - case 14: - READ16(addr, emu8k->hwcf7); - return ret; - - /* Simulating empty/full bits by unsetting it once read. */ - case 20: - READ16(addr, emu8k->smalr|dmareadbit); - /* xor with itself to set to zero faster. */ - dmareadbit^=dmareadbit; - return ret; - case 21: - READ16(addr, emu8k->smarr|dmareadbit); - /* xor with itself to set to zero faster.*/ - dmareadbit^=dmareadbit; - return ret; - case 22: - READ16(addr, emu8k->smalw|dmawritebit); - /*xor with itself to set to zero faster.*/ - dmawritebit^=dmawritebit; - return ret; - case 23: - READ16(addr, emu8k->smarw|dmawritebit); - /*xor with itself to set to zero faster.*/ - dmawritebit^=dmawritebit; - return ret; - - case 26: - { - uint16_t val = emu8k->smrd_buffer; - emu8k->smrd_buffer = EMU8K_READ(emu8k, emu8k->smarr); - emu8k->smarr = (emu8k->smarr+1) & EMU8K_MEM_ADDRESS_MASK; - return val; - } - /*TODO: We need to improve the precision of this clock, since - it is used by programs to wait. Not critical, but should help reduce - the amount of calls and wait time */ - case 27: /*Sample Counter ( 44Khz clock) */ - return emu8k->wc; - } - break; - - case 2: - return emu8k->init2[emu8k->cur_voice]; - - case 3: - return emu8k->init4[emu8k->cur_voice]; - - case 4: - return emu8k->voice[emu8k->cur_voice].atkhldv; - - case 5: - return emu8k->voice[emu8k->cur_voice].lfo1val; - - case 6: - return emu8k->voice[emu8k->cur_voice].atkhld; - - case 7: - return emu8k->voice[emu8k->cur_voice].lfo2val; - } - break; - - case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ - switch (emu8k->cur_reg) - { - case 0: - return emu8k->voice[emu8k->cur_voice].ip; - - case 1: - return emu8k->voice[emu8k->cur_voice].ifatn; - - case 2: - return emu8k->voice[emu8k->cur_voice].pefe; - - case 3: - return emu8k->voice[emu8k->cur_voice].fmmod; - - case 4: - return emu8k->voice[emu8k->cur_voice].tremfrq; - - case 5: - return emu8k->voice[emu8k->cur_voice].fm2frq2; - - case 6: - return 0xffff; - - case 7: /*ID?*/ - return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); - } - break; - - case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ - /* LS five bits = channel number, next 3 bits = register number - * and MS 8 bits = VLSI test register. - * Impulse tracker tests the non variability of the LS byte that it has set, and the variability - * of the MS byte to determine that it really is an AWE32. - * cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero.*/ - random_helper = (random_helper + 1) & 0x1F; - return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; - } - emu8k_log("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - return 0xffff; -} - -void emu8k_outw(uint16_t addr, uint16_t val, void *p) -{ - emu8k_t *emu8k = (emu8k_t *)p; - - /*TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). - * Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread.*/ - emu8k_update(emu8k); - -#ifdef EMU8K_DEBUG_REGISTERS - if (addr == 0xE22) - { - //emu8k_log("EMU8K WRITE POINTER: %d\n", val); - } - else if ((addr&0xF00) == 0x600) - { - /* These are automatically reported by WRITE16 */ - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) - { - /* These are automatically reported by WRITE16 */ - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) - { - uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); - if (tmpz != last_write) - { - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - emu8k_log("EMU8K WRITE RAM I/O or configuration \n"); - } - //emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); - } - else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) - { - uint32_t tmpz = ((addr&0xF00) << 16); - if (tmpz != last_write) - { - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - emu8k_log("EMU8K WRITE INIT \n"); - } - //emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); - } - else if (addr != 0xE22) - { - uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; - //if (tmpz != last_write) - if(1) - { - char* name = 0; - if (addr == 0xA20) - { - name = PORT_NAMES[1][emu8k->cur_reg]; - } - else if (addr == 0xA22) - { - name = PORT_NAMES[2][emu8k->cur_reg]; - } - else if (addr == 0xE20) - { - name = PORT_NAMES[3][emu8k->cur_reg]; - } - - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - } - if (name == 0) - { - emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); - } - else - { - emu8k_log("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); - } - - rep_count_w=0; - last_write=tmpz; - } - rep_count_w++; - } -#endif //EMU8K_DEBUG_REGISTERS - - - switch (addr & 0xF02) - { - case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ - switch (emu8k->cur_reg) - { - case 0: - /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over ptrx */ - WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); - return; - - case 1: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ptrx, val); - return; - - case 2: - /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over vtft */ - WRITE16(addr, emu8k->voice[emu8k->cur_voice].cvcf, val); - return; - - case 3: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].vtft, val); - return; - - case 4: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); - return; - - case 5: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); - return; - - case 6: - { - emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; - WRITE16(addr, emu_voice->psst, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu_voice->loop_start.int_address = emu_voice->psst & EMU8K_MEM_ADDRESS_MASK; - if (addr & 2) - { - emu_voice->vol_l = emu_voice->psst_pan; - emu_voice->vol_r = 255 - (emu_voice->psst_pan); - } - } - return; - - case 7: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].csl, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].loop_end.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; - return; - } - break; - - case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ - switch (emu8k->cur_reg) - { - case 0: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].addr.int_address = emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK; - return; - - case 1: - switch (emu8k->cur_voice) - { - case 9: - WRITE16(addr, emu8k->hwcf4, val); - return; - case 10: - WRITE16(addr, emu8k->hwcf5, val); - return; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ - case 13: - WRITE16(addr, emu8k->hwcf6, val); - return; - case 14: - WRITE16(addr, emu8k->hwcf7, val); - return; - - case 20: - WRITE16(addr, emu8k->smalr, val); - return; - case 21: - WRITE16(addr, emu8k->smarr, val); - return; - case 22: - WRITE16(addr, emu8k->smalw, val); - return; - case 23: - WRITE16(addr, emu8k->smarw, val); - return; - - case 26: - EMU8K_WRITE(emu8k, emu8k->smalw, val); - emu8k->smalw = (emu8k->smalw+1) & EMU8K_MEM_ADDRESS_MASK; - return; - - case 29: - emu8k->hwcf1 = val; - return; - case 30: - emu8k->hwcf2 = val; - return; - case 31: - emu8k->hwcf3 = val; - return; - } - break; - - case 2: - emu8k->init1[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 0x3: emu8k->reverb_engine.out_mix = val&0xFF; - break; - case 0x5: - { - int c; - for (c=0;c<8;c++) - { - emu8k->reverb_engine.allpass[c].feedback=(val&0xFF)/((float)0xFF); - } - } - break; - case 0x7: emu8k->reverb_engine.link_return_type = (val==0x8474)? 1:0; - break; - case 0xF: emu8k->reverb_engine.reflections[0].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x17: emu8k->reverb_engine.reflections[1].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x1F: emu8k->reverb_engine.reflections[2].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val&0xF)/15.0; - break; - case 0xB: //emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; - break; - case 0x11:emu8k->reverb_engine.reflections[1].feedback = (val&0xF)/15.0; - break; - case 0x13: //emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; - break; - case 0x19: emu8k->reverb_engine.reflections[2].feedback = (val&0xF)/15.0; - break; - case 0x1B: //emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; - break; - } - } - return; - - case 3: - emu8k->init3[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 9: - emu8k->chorus_engine.feedback = (val&0xFF); - break; - case 12: - /* Limiting this to a sane value given our buffer. */ - emu8k->chorus_engine.delay_samples_central = (val&0x1FFF); - break; - - case 1: emu8k->reverb_engine.refl_in_amp = val&0xFF; - break; - case 3: //emu8k->reverb_engine.refl_in_amp_r = val&0xFF; - break; - } - } - return; - - case 4: - emu8k->voice[emu8k->cur_voice].envvol = val; - emu8k->voice[emu8k->cur_voice].vol_envelope.delay_samples = ENVVOL_TO_EMU_SAMPLES(val); - return; - - case 5: - { - emu8k->voice[emu8k->cur_voice].dcysusv = val; - emu8k_envelope_t * const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; - int old_on=emu8k->voice[emu8k->cur_voice].env_engine_on; - emu8k->voice[emu8k->cur_voice].env_engine_on = DCYSUSV_GENERATOR_ENGINE_ON(val); - - if (emu8k->voice[emu8k->cur_voice].env_engine_on && - old_on != emu8k->voice[emu8k->cur_voice].env_engine_on) - { - if (emu8k->hwcf3 != 0x04) - { - /* This is a hack for some programs like Doom or cubic player 1.7 that don't initialize - the hwcfg and init registers (doom does not init the card at all. only tests the cfg registers) */ - emu8k->hwcf3 = 0x04; - } - - //reset lfos. - emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; - emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; - // Trigger envelopes - if (ATKHLDV_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhldv)) - { - vol_env->value_amp_hz = 0; - if (vol_env->delay_samples) - { - vol_env->state = ENV_DELAY; - } - else if (vol_env->attack_amount_amp_hz == 0) - { - vol_env->state = ENV_STOPPED; - } - else - { - vol_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal mute, - * or it means skip attack, go to hold". - if (vol_env->attack_amount == 0) - { - vol_env->value = (1 << 21); - vol_env->state = ENV_HOLD; - }*/ - } - } - - if (ATKHLD_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhld)) - { - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - mod_env->value_amp_hz = 0; - mod_env->value_db_oct = 0; - if (mod_env->delay_samples) - { - mod_env->state = ENV_DELAY; - } - else if (mod_env->attack_amount_amp_hz == 0) - { - mod_env->state = ENV_STOPPED; - } - else - { - mod_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal start, - * or it means skip attack, go to hold". - if (mod_env->attack_amount == 0) - { - mod_env->value = (1 << 21); - mod_env->state = ENV_HOLD; - }*/ - } - } - } - - - /* Converting the input in dBs to envelope value range. */ - vol_env->sustain_value_db_oct = DCYSUSV_SUS_TO_ENV_RANGE(DCYSUSV_SUSVALUE_GET(val)); - vol_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUSV_DECAYRELEASE_GET(val)]; - if (DCYSUSV_IS_RELEASE(val)) - { - if (vol_env->state == ENV_DELAY || vol_env->state == ENV_ATTACK || vol_env->state == ENV_HOLD) - { - vol_env->value_db_oct = env_vol_amplitude_to_db[vol_env->value_amp_hz >> 5] << 5; - if (vol_env->value_db_oct > (1 << 21)) - vol_env->value_db_oct = 1 << 21; - } - - vol_env->state = (vol_env->value_db_oct >= vol_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; - } - } - return; - - case 6: - emu8k->voice[emu8k->cur_voice].envval = val; - emu8k->voice[emu8k->cur_voice].mod_envelope.delay_samples = ENVVAL_TO_EMU_SAMPLES(val); - return; - - case 7: - { - //TODO: Look for a bug on delay (first trigger it works, next trigger it doesn't) - emu8k->voice[emu8k->cur_voice].dcysus = val; - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - /* Converting the input in octaves to envelope value range. */ - mod_env->sustain_value_db_oct = DCYSUS_SUS_TO_ENV_RANGE(DCYSUS_SUSVALUE_GET(val)); - mod_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUS_DECAYRELEASE_GET(val)]; - if (DCYSUS_IS_RELEASE(val)) - { - if (mod_env->state == ENV_DELAY || mod_env->state == ENV_ATTACK || mod_env->state == ENV_HOLD) - { - mod_env->value_db_oct = env_mod_hertz_to_octave[mod_env->value_amp_hz >> 9] << 9; - if (mod_env->value_db_oct >= (1 << 21)) - mod_env->value_db_oct = (1 << 21)-1; - } - - mod_env->state = (mod_env->value_db_oct >= mod_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; - } - } - return; - } - break; - - case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ - switch (emu8k->cur_reg) - { - case 0: - { - emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; - WRITE16(addr, emu_voice->ccca, val); - emu_voice->addr.int_address = emu_voice->ccca & EMU8K_MEM_ADDRESS_MASK; - uint32_t paramq = CCCA_FILTQ_GET(emu_voice->ccca); - emu_voice->filt_att = filter_atten[paramq]; - emu_voice->filterq_idx = paramq; - } - return; - - case 1: - switch (emu8k->cur_voice) - { - case 9: - WRITE16(addr, emu8k->hwcf4, val); - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - /*(1/256th of a 44Khz sample) */ - /* clip the value to a reasonable value given our buffer */ - int32_t tmp = emu8k->hwcf4&0x1FFFFF; - emu8k->chorus_engine.delay_offset_samples_right = ((double)tmp)/256.0; - } - return; - case 10: - WRITE16(addr, emu8k->hwcf5, val); - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - /* The scale of this value is unknown. I've taken it as milliHz. - * Another interpretation could be periods. (and so, Hz = 1/period)*/ - double osc_speed = emu8k->hwcf5;//*1.316; -#if 1 // milliHz - /*milliHz to lfotable samples.*/ - osc_speed *= 65.536/44100.0; -#elif 0 //periods - /* 44.1Khz ticks to lfotable samples.*/ - osc_speed = 65.536/osc_speed; -#endif - /*left shift 32bits for 32.32 fixed.point*/ - osc_speed *= 65536.0*65536.0; - emu8k->chorus_engine.lfo_inc.addr = (uint64_t)osc_speed; - } - return; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ - case 13: - WRITE16(addr, emu8k->hwcf6, val); - return; - case 14: - WRITE16(addr, emu8k->hwcf7, val); - return; - - case 20: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ - WRITE16(addr, emu8k->smalr, val&0xFF); - dmareadbit=0x8000; - return; - case 21: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ - WRITE16(addr, emu8k->smarr, val&0xFF); - dmareadbit=0x8000; - return; - case 22: /*Top 8 bits are for full bit or non-addressable.*/ - WRITE16(addr, emu8k->smalw, val&0xFF); - return; - case 23: /*Top 8 bits are for full bit or non-addressable.*/ - WRITE16(addr, emu8k->smarw, val&0xFF); - return; - - case 26: - dmawritebit=0x8000; - EMU8K_WRITE(emu8k, emu8k->smarw, val); - emu8k->smarw++; - return; - } - break; - - case 2: - emu8k->init2[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 0x14: - { - int multip = ((val&0xF00)>>8)+18; - emu8k->reverb_engine.reflections[5].bufsize = multip*REV_BUFSIZE_STEP; - emu8k->reverb_engine.tailL.bufsize = (multip+1)*REV_BUFSIZE_STEP; - if ( emu8k->reverb_engine.link_return_type == 0) - { - emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; - } - } - break; - case 0x16: - if ( emu8k->reverb_engine.link_return_type == 1) - { - int multip = ((val&0xF00)>>8)+18; - emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; - } - break; - case 0x7: emu8k->reverb_engine.reflections[3].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0xf: emu8k->reverb_engine.reflections[4].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x17: emu8k->reverb_engine.reflections[5].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x1d: - { - int c; - for (c=0;c<6;c++) - { - emu8k->reverb_engine.reflections[c].damp1=(val&0xFF)/255.0; - emu8k->reverb_engine.reflections[c].damp2=(0xFF-(val&0xFF))/255.0; - emu8k->reverb_engine.reflections[c].filterstore=0; - } - emu8k->reverb_engine.damper.damp1=(val&0xFF)/255.0; - emu8k->reverb_engine.damper.damp2=(0xFF-(val&0xFF))/255.0; - emu8k->reverb_engine.damper.filterstore=0; - } - break; - case 0x1f: /* filter r */ - break; - case 0x1: emu8k->reverb_engine.reflections[3].feedback = (val&0xF)/15.0; - break; - case 0x3: //emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; - break; - case 0x9: emu8k->reverb_engine.reflections[4].feedback = (val&0xF)/15.0; - break; - case 0xb: //emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; - break; - case 0x11: emu8k->reverb_engine.reflections[5].feedback = (val&0xF)/15.0; - break; - case 0x13: //emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; - break; - } - } - return; - - case 3: - emu8k->init4[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 0x3: - { - int32_t samples = ((val&0xFF)*emu8k->chorus_engine.delay_samples_central) >> 8; - emu8k->chorus_engine.lfodepth_multip = samples; - - } - break; - - case 0x1F: - emu8k->reverb_engine.link_return_amp = val&0xFF; - break; - } - } - return ; - - case 4: - { - emu8k->voice[emu8k->cur_voice].atkhldv = val; - emu8k_envelope_t* const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; - vol_env->attack_samples = env_attack_to_samples[ATKHLDV_ATTACK(val)]; - if (vol_env->attack_samples == 0) - { - vol_env->attack_amount_amp_hz = 0; - } - else - { - /* Linear amplitude increase each sample. */ - vol_env->attack_amount_amp_hz = (1<<21) / vol_env->attack_samples; - } - vol_env->hold_samples = ATKHLDV_HOLD_TO_EMU_SAMPLES(val); - if (ATKHLDV_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) - { - /*TODO: I assume that "envelope trigger" is the same as new note - * (since changing the IP can be done when modulating pitch too) */ - emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; - emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; - - vol_env->value_amp_hz = 0; - if (vol_env->delay_samples) - { - vol_env->state = ENV_DELAY; - } - else if (vol_env->attack_amount_amp_hz == 0) - { - vol_env->state = ENV_STOPPED; - } - else - { - vol_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal mute, - * or it means skip attack, go to hold". - if (vol_env->attack_amount == 0) - { - vol_env->value = (1 << 21); - vol_env->state = ENV_HOLD; - }*/ - } - } - } - return; - - case 5: - emu8k->voice[emu8k->cur_voice].lfo1val = val; - /* TODO: verify if this is set once, or set every time. */ - emu8k->voice[emu8k->cur_voice].lfo1_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); - return; - - case 6: - { - emu8k->voice[emu8k->cur_voice].atkhld = val; - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - mod_env->attack_samples = env_attack_to_samples[ATKHLD_ATTACK(val)]; - if (mod_env->attack_samples == 0) - { - mod_env->attack_amount_amp_hz = 0; - } - else - { - /* Linear amplitude increase each sample. */ - mod_env->attack_amount_amp_hz = (1<<21) / mod_env->attack_samples; - } - mod_env->hold_samples = ATKHLD_HOLD_TO_EMU_SAMPLES(val); - if (ATKHLD_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) - { - mod_env->value_amp_hz = 0; - mod_env->value_db_oct = 0; - if (mod_env->delay_samples) - { - mod_env->state = ENV_DELAY; - } - else if (mod_env->attack_amount_amp_hz == 0) - { - mod_env->state = ENV_STOPPED; - } - else - { - mod_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal start, - * or it means skip attack, go to hold". - if (mod_env->attack_amount == 0) - { - mod_env->value = (1 << 21); - mod_env->state = ENV_HOLD; - }*/ - } - } - } - return; - - case 7: - emu8k->voice[emu8k->cur_voice].lfo2val = val; - emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); - - return; - } - break; - - case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ - switch (emu8k->cur_reg) - { - case 0: - emu8k->voice[emu8k->cur_voice].ip = val; - emu8k->voice[emu8k->cur_voice].ptrx_pit_target = freqtable[val] >> 18; - return; - - case 1: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - if ((val&0xFF) == 0 && the_voice->cvcf_curr_volume == 0 && the_voice->vtft_vol_target == 0 - && the_voice->dcysusv == 0x80 && the_voice->ip == 0) - { - // Patch to avoid some clicking noises with Impulse tracker or other software that sets - // different values to 0 to set noteoff, but here, 0 means no attenuation = full volume. - return; - } - the_voice->ifatn = val; - the_voice->initial_att = (((int32_t)the_voice->ifatn_attenuation <<21)/0xFF); - the_voice->vtft_vol_target = attentable[the_voice->ifatn_attenuation]; - - the_voice->initial_filter = (((int32_t)the_voice->ifatn_init_filter <<21)/0xFF); - if (the_voice->ifatn_init_filter==0xFF) - { - the_voice->vtft_filter_target = 0xFFFF; - } - else - { - the_voice->vtft_filter_target = the_voice->initial_filter >> 5; - } - } - return; - - case 2: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->pefe = val; - - int divider = (the_voice->pefe_modenv_filter_height < 0) ? 0x80 : 0x7F; - the_voice->fixed_modenv_filter_height = ((int32_t)the_voice->pefe_modenv_filter_height)*0x4000/divider; - - divider = (the_voice->pefe_modenv_pitch_height < 0) ? 0x80 : 0x7F; - the_voice->fixed_modenv_pitch_height = ((int32_t)the_voice->pefe_modenv_pitch_height)*0x4000/divider; - } - return; - - case 3: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->fmmod = val; - - int divider = (the_voice->fmmod_lfo1_filt_mod < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_filt_mod = ((int32_t)the_voice->fmmod_lfo1_filt_mod)*0x4000/divider; - - divider = (the_voice->fmmod_lfo1_vibrato < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_vibrato = ((int32_t)the_voice->fmmod_lfo1_vibrato)*0x4000/divider; - } - return; - - case 4: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->tremfrq = val; - the_voice->lfo1_speed = lfofreqtospeed[the_voice->tremfrq_lfo1_freq]; - - int divider = (the_voice->tremfrq_lfo1_tremolo < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_tremolo = ((int32_t)the_voice->tremfrq_lfo1_tremolo)*0x4000/divider; - } - return; - - case 5: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->fm2frq2 = val; - the_voice->lfo2_speed = lfofreqtospeed[the_voice->fm2frq2_lfo2_freq]; - - int divider = (the_voice->fm2frq2_lfo2_vibrato < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo2_vibrato = ((int32_t)the_voice->fm2frq2_lfo2_vibrato)*0x4000/divider; - } - return; - - case 7: /*ID? I believe that this allows applications to know if the emu is in use by another application */ - emu8k->id = val; - return; - } - break; - - case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ - emu8k->cur_voice = (val & 31); - emu8k->cur_reg = ((val >> 5) & 7); - return; - } - emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg)<<5|emu8k->cur_voice, - emu8k->cur_reg,emu8k->cur_voice, val); - -} - -uint8_t emu8k_inb(uint16_t addr, void *p) -{ - /* Reading a single byte is a feature that at least Impulse tracker uses, - * but only on detection code and not for odd addresses.*/ - if (addr & 1) - return emu8k_inw(addr & ~1, p) >> 1; - return emu8k_inw(addr, p) & 0xff; -} - -void emu8k_outb(uint16_t addr, uint8_t val, void *p) -{ - /* TODO: AWE32 docs says that you cannot write in bytes, but if - * an app were to use this implementation, the content of the LS Byte would be lost.*/ - if (addr & 1) - emu8k_outw(addr & ~1, val << 8, p); - else - emu8k_outw(addr, val, p); -} - -/* TODO: This is not a correct emulation, just a workalike implementation. */ -void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, int count) -{ - int pos; - for (pos = 0; pos < count; pos++) - { - double lfo_inter1 = chortable[engine->lfo_pos.int_address]; - // double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; - - double offset_lfo =lfo_inter1; //= lfo_inter1 + ((lfo_inter2-lfo_inter1)*engine->lfo_pos.fract_address/65536.0); - offset_lfo *= engine->lfodepth_multip; - - /* Work left */ - double readdouble = (double)engine->write - (double)engine->delay_samples_central - offset_lfo; - int read = (int32_t)floor(readdouble); - int fraction_part = (readdouble - (double)read)*65536.0; - int next_value = read + 1; - if(read < 0) - { - read += EMU8K_LFOCHORUS_SIZE; - if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; - } - else if(next_value >= EMU8K_LFOCHORUS_SIZE) - { - next_value -= EMU8K_LFOCHORUS_SIZE; - if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; - } - int32_t dat1 = engine->chorus_left_buffer[read]; - int32_t dat2 = engine->chorus_left_buffer[next_value]; - dat1 += ((dat2-dat1)* fraction_part) >> 16; - - engine->chorus_left_buffer[engine->write] = *inbuf + ((dat1 * engine->feedback)>>8); - - - /* Work right */ - readdouble = (double)engine->write - (double)engine->delay_samples_central - engine->delay_offset_samples_right - offset_lfo; - read = (int32_t)floor(readdouble); - next_value = read + 1; - if(read < 0) - { - read += EMU8K_LFOCHORUS_SIZE; - if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; - } - else if(next_value >= EMU8K_LFOCHORUS_SIZE) - { - next_value -= EMU8K_LFOCHORUS_SIZE; - if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; - } - int32_t dat3 = engine->chorus_right_buffer[read]; - int32_t dat4 = engine->chorus_right_buffer[next_value]; - dat3 += ((dat4-dat3)* fraction_part) >> 16; - - engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback)>>8); - - ++engine->write; - engine->write %= EMU8K_LFOCHORUS_SIZE; - engine->lfo_pos.addr +=engine->lfo_inc.addr; - engine->lfo_pos.int_address &= 0xFFFF; - - (*outbuf++) += dat1; - (*outbuf++) += dat3; - inbuf++; - } - -} - -int32_t emu8k_reverb_comb_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - - int32_t bufin; - /* get echo */ - int32_t output = comb->reflection[comb->read_pos]; - /* apply lowpass */ - comb->filterstore = (output*comb->damp2) + (comb->filterstore*comb->damp1); - /* appply feedback */ - bufin = in - (comb->filterstore*comb->feedback); - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = bufin; - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output*comb->output_gain; -} - -int32_t emu8k_reverb_diffuser_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - - int32_t bufout = comb->reflection[comb->read_pos]; - /*diffuse*/ - int32_t bufin = -in + (bufout*comb->feedback); - int32_t output = bufout - (bufin*comb->feedback); - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = bufin; - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output; -} - -int32_t emu8k_reverb_tail_work(emu8k_reverb_combfilter_t* comb, emu8k_reverb_combfilter_t* allpasses, int32_t in) -{ - int32_t output = comb->reflection[comb->read_pos]; - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = in; - - //output = emu8k_reverb_allpass_work(&allpasses[0],output); - output = emu8k_reverb_diffuser_work(&allpasses[1],output); - output = emu8k_reverb_diffuser_work(&allpasses[2],output); - //output = emu8k_reverb_allpass_work(&allpasses[3],output); - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output; -} -int32_t emu8k_reverb_damper_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - /* apply lowpass */ - comb->filterstore = (in*comb->damp2) + (comb->filterstore*comb->damp1); - return comb->filterstore; -} - -/* TODO: This is not a correct emulation, just a workalike implementation. */ -void emu8k_work_reverb(int32_t *inbuf, int32_t *outbuf, emu8k_reverb_eng_t *engine, int count) -{ - int pos; - if (engine->link_return_type) - { - for (pos = 0; pos < count; pos++) - { - int32_t dat1, dat2, in, in2; - in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); - in2 = (in * engine->refl_in_amp) >> 8; - dat2 = emu8k_reverb_comb_work(&engine->reflections[0], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[1], in2); - dat1 = emu8k_reverb_comb_work(&engine->reflections[2], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[3], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[5], in2); - - dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; - dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; - - (*outbuf++) += (dat1 * engine->out_mix) >> 8; - (*outbuf++) += (dat2 * engine->out_mix) >> 8; - } - } - else - { - for (pos = 0; pos < count; pos++) - { - int32_t dat1, dat2, in, in2; - in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); - in2 = (in * engine->refl_in_amp) >> 8; - dat1 = emu8k_reverb_comb_work(&engine->reflections[0], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[1], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[2], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[3], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[5], in2); - dat2 = dat1; - - dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; - dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; - - (*outbuf++) += (dat1 * engine->out_mix) >> 8; - (*outbuf++) += (dat2 * engine->out_mix) >> 8; - } - } -} -void emu8k_work_eq(int32_t *inoutbuf, int count) -{ - // TODO: Work EQ over buf -} - - -int32_t emu8k_vol_slide(emu8k_slide_t* slide, int32_t target) -{ - if (slide->last < target) - { - slide->last+=0x400; - if (slide->last > target) slide->last = target; - } - else if (slide->last > target) - { - slide->last-=0x400; - if (slide->last < target) slide->last = target; - } - return slide->last; -} - -//int32_t old_pitch[32]={0}; -//int32_t old_cut[32]={0}; -//int32_t old_vol[32]={0}; -void emu8k_update(emu8k_t *emu8k) -{ - int new_pos = (sound_pos_global * 44100) / 48000; - if (emu8k->pos >= new_pos) - return; - - int32_t *buf; - emu8k_voice_t* emu_voice; - int pos; - int c; - - /* Clean the buffers since we will accumulate into them. */ - buf = &emu8k->buffer[emu8k->pos*2]; - memset(buf, 0, 2*(new_pos-emu8k->pos)*sizeof(emu8k->buffer[0])); - memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->chorus_in_buffer[0])); - memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->reverb_in_buffer[0])); - - /* Voices section */ - for (c = 0; c < 32; c++) - { - emu_voice = &emu8k->voice[c]; - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - { - int32_t dat; - - /* Waveform oscillator */ -#ifdef RESAMPLER_LINEAR - dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); - -#elif defined RESAMPLER_CUBIC - dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); -#endif - - /* Filter section */ - if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) - { - int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; - const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; - const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; - const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; - /* clip at twice the range */ - #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf - - #ifdef FILTER_INITIAL - #define NOOP(x) (void)x; - NOOP(coef1) - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). - * Work in 24bits. */ - dat = (dat * emu_voice->filt_att) >> 8; - - int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; - emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; - emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #elif defined FILTER_MOOG - - /*move to 24bits*/ - dat <<= 8; - - dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; - emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - int64_t t2 = emu_voice->filt_buffer[2]; - emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; - emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - - int64_t t3 = emu_voice->filt_buffer[3]; - emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; - emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); - - emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; - emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); - - emu_voice->filt_buffer[0] = ClipBuffer(dat); - - dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #elif defined FILTER_CONSTANT - - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). - * Also stay at 24bits.*/ - dat = (dat * emu_voice->filt_att) >> 8; - - emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] - + coef0 * (dat + - ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) - ) >> 24; - emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] - + coef0 * emu_voice->filt_buffer[0]) >> 24; - - emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #endif - - } - if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) - { - /*volume and pan*/ - dat = (dat * emu_voice->cvcf_curr_volume) >> 16; - - (*buf++) += (dat * emu_voice->vol_l) >> 8; - (*buf++) += (dat * emu_voice->vol_r) >> 8; - - /* Effects section */ - if (emu_voice->ptrx_revb_send > 0) - { - emu8k->reverb_in_buffer[pos]+=(dat*emu_voice->ptrx_revb_send) >> 8; - } - if (emu_voice->csl_chor_send > 0) - { - emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; - } - } - - if ( emu_voice->env_engine_on) - { - int32_t attenuation = emu_voice->initial_att; - int32_t filtercut = emu_voice->initial_filter; - int32_t currentpitch = emu_voice->ip; - /* run envelopes */ - emu8k_envelope_t *volenv = &emu_voice->vol_envelope; - switch (volenv->state) - { - case ENV_DELAY: - volenv->delay_samples--; - if (volenv->delay_samples <=0) - { - volenv->state=ENV_ATTACK; - volenv->delay_samples=0; - } - attenuation = 0x1FFFFF; - break; - - case ENV_ATTACK: - /* Attack amount is in linear amplitude */ - volenv->value_amp_hz += volenv->attack_amount_amp_hz; - if (volenv->value_amp_hz >= (1 << 21)) - { - volenv->value_amp_hz = 1 << 21; - volenv->value_db_oct = 0; - if (volenv->hold_samples) - { - volenv->state = ENV_HOLD; - } - else - { - /* RAMP_UP since db value is inverted and it is 0 at this point. */ - volenv->state = ENV_RAMP_UP; - } - } - attenuation += env_vol_amplitude_to_db[volenv->value_amp_hz >> 5] << 5; - break; - - case ENV_HOLD: - volenv->hold_samples--; - if (volenv->hold_samples <=0) - { - volenv->state=ENV_RAMP_UP; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_RAMP_DOWN: - /* Decay/release amount is in fraction of dBs and is always positive */ - volenv->value_db_oct -= volenv->ramp_amount_db_oct; - if (volenv->value_db_oct <= volenv->sustain_value_db_oct) - { - volenv->value_db_oct = volenv->sustain_value_db_oct; - volenv->state = ENV_SUSTAIN; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_RAMP_UP: - /* Decay/release amount is in fraction of dBs and is always positive */ - volenv->value_db_oct += volenv->ramp_amount_db_oct; - if (volenv->value_db_oct >= volenv->sustain_value_db_oct) - { - volenv->value_db_oct = volenv->sustain_value_db_oct; - volenv->state = ENV_SUSTAIN; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_SUSTAIN: - attenuation += volenv->value_db_oct; - break; - - case ENV_STOPPED: - attenuation = 0x1FFFFF; - break; - } - - emu8k_envelope_t *modenv = &emu_voice->mod_envelope; - switch (modenv->state) - { - case ENV_DELAY: - modenv->delay_samples--; - if (modenv->delay_samples <=0) - { - modenv->state=ENV_ATTACK; - modenv->delay_samples=0; - } - break; - - case ENV_ATTACK: - /* Attack amount is in linear amplitude */ - modenv->value_amp_hz += modenv->attack_amount_amp_hz; - modenv->value_db_oct = env_mod_hertz_to_octave[modenv->value_amp_hz >> 5] << 5; - if (modenv->value_amp_hz >= (1 << 21)) - { - modenv->value_amp_hz = 1 << 21; - modenv->value_db_oct = 1 << 21; - if (modenv->hold_samples) - { - modenv->state = ENV_HOLD; - } - else - { - modenv->state = ENV_RAMP_DOWN; - } - } - break; - - case ENV_HOLD: - modenv->hold_samples--; - if (modenv->hold_samples <=0) - { - modenv->state=ENV_RAMP_UP; - } - break; - - case ENV_RAMP_DOWN: - /* Decay/release amount is in fraction of octave and is always positive */ - modenv->value_db_oct -= modenv->ramp_amount_db_oct; - if (modenv->value_db_oct <= modenv->sustain_value_db_oct) - { - modenv->value_db_oct = modenv->sustain_value_db_oct; - modenv->state = ENV_SUSTAIN; - } - break; - - case ENV_RAMP_UP: - /* Decay/release amount is in fraction of octave and is always positive */ - modenv->value_db_oct += modenv->ramp_amount_db_oct; - if (modenv->value_db_oct >= modenv->sustain_value_db_oct) - { - modenv->value_db_oct = modenv->sustain_value_db_oct; - modenv->state = ENV_SUSTAIN; - } - break; - } - - /* run lfos */ - if (emu_voice->lfo1_delay_samples) - { - emu_voice->lfo1_delay_samples--; - } - else - { - emu_voice->lfo1_count.addr += emu_voice->lfo1_speed; - emu_voice->lfo1_count.int_address &= 0xFFFF; - } - if (emu_voice->lfo2_delay_samples) - { - emu_voice->lfo2_delay_samples--; - } - else - { - emu_voice->lfo2_count.addr += emu_voice->lfo2_speed; - emu_voice->lfo2_count.int_address &= 0xFFFF; - } - - - if (emu_voice->fixed_modenv_pitch_height) - { - /* modenv range 1<<21, pitch height range 1<<14 desired range 0x1000 (+/-one octave) */ - currentpitch += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_pitch_height) >> 14; - } - - if (emu_voice->fixed_lfo1_vibrato) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ - int32_t lfo1_vibrato = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_vibrato) >> 17; - currentpitch += lfo1_vibrato; - } - if (emu_voice->fixed_lfo2_vibrato) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ - int32_t lfo2_vibrato = (lfotable[emu_voice->lfo2_count.int_address]*emu_voice->fixed_lfo2_vibrato) >> 17; - currentpitch += lfo2_vibrato; - } - - if (emu_voice->fixed_modenv_filter_height) - { - /* modenv range 1<<21, pitch height range 1<<14 desired range 0x200000 (+/-full filter range) */ - filtercut += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_filter_height) >> 5; - } - - if (emu_voice->fixed_lfo1_filt_mod) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x100000 (+/-three octaves) */ - int32_t lfo1_filtmod = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_filt_mod) >> 9; - filtercut += lfo1_filtmod; - } - - if (emu_voice->fixed_lfo1_tremolo) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x40000 (+/-12dBs). */ - int32_t lfo1_tremolo = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_tremolo) >> 11; - attenuation += lfo1_tremolo; - } - - if (currentpitch > 0xFFFF) currentpitch = 0xFFFF; - if (currentpitch < 0) currentpitch = 0; - if (attenuation > 0x1FFFFF) attenuation = 0x1FFFFF; - if (attenuation < 0) attenuation = 0; - if (filtercut > 0x1FFFFF) filtercut = 0x1FFFFF; - if (filtercut < 0) filtercut = 0; - - emu_voice->vtft_vol_target = env_vol_db_to_vol_target[attenuation >> 5]; - emu_voice->vtft_filter_target = filtercut >> 5; - emu_voice->ptrx_pit_target = freqtable[currentpitch]>>18; - - } -/* -I've recopilated these sentences to get an idea of how to loop - -- Set its PSST register and its CLS register to zero to cause no loops to occur. --Setting the Loop Start Offset and the Loop End Offset to the same value, will cause the oscillator to loop the entire memory. - --Setting the PlayPosition greater than the Loop End Offset, will cause the oscillator to play in reverse, back to the Loop End Offset. - It's pretty neat, but appears to be uncontrollable (the rate at which the samples are played in reverse). - --Note that due to interpolator offset, the actual loop point is one greater than the start address --Note that due to interpolator offset, the actual loop point will end at an address one greater than the loop address --Note that the actual audio location is the point 1 word higher than this value due to interpolation offset --In programs that use the awe, they generally set the loop address as "loopaddress -1" to compensate for the above. -(Note: I am already using address+1 in the interpolators so these things are already as they should.) -*/ - emu_voice->addr.addr += ((uint64_t)emu_voice->cpf_curr_pitch) << 18; - if (emu_voice->addr.addr >= emu_voice->loop_end.addr) - { - emu_voice->addr.int_address -= (emu_voice->loop_end.int_address - emu_voice->loop_start.int_address); - emu_voice->addr.int_address &= EMU8K_MEM_ADDRESS_MASK; - } - - /* TODO: How and when are the target and current values updated */ - emu_voice->cpf_curr_pitch = emu_voice->ptrx_pit_target; - emu_voice->cvcf_curr_volume = emu8k_vol_slide(&emu_voice->volumeslide,emu_voice->vtft_vol_target); - emu_voice->cvcf_curr_filt_ctoff = emu_voice->vtft_filter_target; - } - - /* Update EMU voice registers. */ - emu_voice->ccca = (((uint32_t)emu_voice->ccca_qcontrol) << 24) | emu_voice->addr.int_address; - emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; - - //if ( emu_voice->cvcf_curr_volume != old_vol[c]) { - // emu8k_log("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); - // old_vol[c]=emu_voice->cvcf_curr_volume; - //} - //emu8k_log("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); - } - - - buf = &emu8k->buffer[emu8k->pos*2]; - emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos-emu8k->pos); - emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos-emu8k->pos); - emu8k_work_eq(buf, new_pos-emu8k->pos); - - // Clip signal - for (pos = emu8k->pos; pos < new_pos; pos++) - { - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - - /* Update EMU clock. */ - emu8k->wc += (new_pos - emu8k->pos); - - emu8k->pos = new_pos; -} -/* onboard_ram in kilobytes */ -void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) -{ - uint32_t const BLOCK_SIZE_WORDS = 0x10000; - FILE *f; - int c; - double out; - - f = rom_fopen(L"roms/sound/awe32.raw", L"rb"); - if (!f) - fatal("AWE32.RAW not found\n"); - - emu8k->rom = malloc(1024 * 1024); - fread(emu8k->rom, 1024 * 1024, 1, f); - fclose(f); - /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this - then correct it*/ - if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) - { - memmove(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); - emu8k->rom[0x7ffff] = 0; - } - - emu8k->empty = malloc(2*BLOCK_SIZE_WORDS); - memset(emu8k->empty, 0, 2*BLOCK_SIZE_WORDS); - - int j=0; - for (;j<0x8;j++) - { - emu8k->ram_pointers[j]=emu8k->rom+(j*BLOCK_SIZE_WORDS); - } - for (;j<0x20;j++) - { - emu8k->ram_pointers[j]=emu8k->empty; - } - - if (onboard_ram) - { - /*Clip to 28MB, since that's the max that we can address. */ - if (onboard_ram > 0x7000) onboard_ram = 0x7000; - emu8k->ram = malloc(onboard_ram * 1024); - memset(emu8k->ram, 0, onboard_ram * 1024); - const int i_end=onboard_ram>>7; - int i=0; - for(;iram_pointers[j]=emu8k->ram+(i*BLOCK_SIZE_WORDS); - } - emu8k->ram_end_addr = EMU8K_RAM_MEM_START + (onboard_ram<<9); - } - else - { - emu8k->ram = 0; - emu8k->ram_end_addr = EMU8K_RAM_MEM_START; - } - for (;j < 0x100;j++) - { - emu8k->ram_pointers[j]=emu8k->empty; - - } - - io_sethandler(emu_addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(emu_addr+0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(emu_addr+0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - - /*Create frequency table. (Convert initial pitch register value to a linear speed change) - * The input is encoded such as 0xe000 is center note (no pitch shift) - * and from then on , changing up or down 0x1000 (4096) increments/decrements an octave. - * Note that this is in reference to the 44.1Khz clock that the channels play at. - * The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. - */ - for (c = 0; c < 0x10000; c++) - { - freqtable[c] = (uint64_t)(exp2((double)(c - 0xe000) / 4096.0) * 65536.0 * 65536.0); - } - /* Shortcut: minimum pitch equals stopped. I don't really know if this is true, but it's better - * since some programs set the pitch to 0 for unused channels. */ - freqtable[0] = 0; - - /* starting at 65535 because it is used for "volume target" register conversion. */ - out = 65535.0; - for (c = 0; c < 256; c++) - { - attentable[c] = (int32_t)out; - out /= sqrt(1.09018); /*0.375 dB steps*/ - } - /* Shortcut: max attenuation is silent, not -96dB. */ - attentable[255]=0; - - /* Note: these two tables have "db" inverted: 0 dB is max volume, 65535 "db" (-96.32dBFS) is silence. - * Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ - out = 65535.0; - for (c = 0; c < 0x10000; c++) - { - //double db = -(c*6.0205999/65535.0)*16.0; - //out = powf(10.f,db/20.f) * 65536.0; - env_vol_db_to_vol_target[c] = (int32_t)out; - /* calculated from the 65536th root of 65536 */ - out /= 1.00016923970; - } - /* Shortcut: max attenuation is silent, not -96dB. */ - env_vol_db_to_vol_target[0x10000-1]=0; - /* One more position to accept max value being 65536. */ - env_vol_db_to_vol_target[0x10000]=0; - - for (c = 1; c < 0x10000; c++) - { - out = -680.32142884264* 20.0 * log10(((double)c)/65535.0); - env_vol_amplitude_to_db[c] = (int32_t)out; - } - /*Shortcut: max attenuation is silent, not -96dB.*/ - env_vol_amplitude_to_db[0]=65535; - /* One more position to accept max value being 65536. */ - env_vol_amplitude_to_db[0x10000]=0; - - - for (c = 1; c < 0x10000; c++) - { - out = log2((((double)c)/0x10000)+1.0) *65536.0; - env_mod_hertz_to_octave[c] = (int32_t)out; - } - /*No hertz change, no octave change. */ - env_mod_hertz_to_octave[0]=0; - /* One more position to accept max value being 65536. */ - env_mod_hertz_to_octave[0x10000]=65536; - - - /* This formula comes from vince vu/judge dredd's awe32p10 and corresponds to what the freebsd/linux AWE32 driver has. */ - float millis; - for (c=0;c<128;c++) - { - if (c==0) - millis = 0; /* This means never attack. */ - else if (c < 32) - millis = 11878.0/c; - else - millis = 360*exp((c - 32) / (16.0/log(1.0/2.0))); - - env_attack_to_samples[c] = 44.1*millis; - /* This is an alternate formula with linear increments, but probably incorrect: - * millis = (256+4096*(0x7F-c)) */ - } - - /* The LFOs use a triangular waveform starting at zero and going 1/-1/1/-1. - * This table is stored in signed 16bits precision, with a period of 65536 samples */ - for (c = 0; c < 65536; c++) - { - int d = (c + 16384) & 65535; - if (d >= 32768) - lfotable[c] = 32768 + ((32768 - d)*2); - else - lfotable[c] = (d*2) - 32768; - } - /* The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. */ - out = 0.01; - for (c = 0; c < 256; c++) - { - lfofreqtospeed[c] = (uint64_t)(out *65536.0/44100.0 * 65536.0 * 65536.0); - out += 0.042; - } - - for (c = 0; c < 65536; c++) - { - chortable[c] = sin(c*M_PI/32768.0); - } - - - /* Filter coefficients tables. Note: Values are multiplied by *16777216 to left shift 24 bits. (i.e. 8.24 fixed point) */ - int qidx; - for (qidx = 0; qidx < 16; qidx++) - { - out = 125.0; /* Start at 125Hz */ - for (c = 0; c < 256; c++) - { -#ifdef FILTER_INITIAL - float w0 = sin(2.0*M_PI*out / 44100.0); - /* The value 102.5f has been selected a bit randomly. Pretends to reach 0.2929 at w0 = 1.0 */ - float q = (qidx / 102.5f) * (1.0 + 1.0 / w0); - /* Limit max value. Else it would be 470. */ - if (q > 200) q=200; - filt_coeffs[qidx][c][0] = (int32_t)(w0 * 16777216.0); - filt_coeffs[qidx][c][1] = 16777216.0; - filt_coeffs[qidx][c][2] = (int32_t)((1.0f / (0.7071f + q)) * 16777216.0); -#elif defined FILTER_MOOG - float w0 = sin(2.0*M_PI*out / 44100.0); - float q_factor = 1.0f - w0; - float p = w0 + 0.8f * w0 * q_factor; - float f = p + p - 1.0f; - float resonance = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; - float q = resonance * (1.0f + 0.5f * q_factor * (w0 + 5.6f * q_factor * q_factor)); - filt_coeffs[qidx][c][0] = (int32_t)(p * 16777216.0); - filt_coeffs[qidx][c][1] = (int32_t)(f * 16777216.0); - filt_coeffs[qidx][c][2] = (int32_t)(q * 16777216.0); -#elif defined FILTER_CONSTANT - float q = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; - float coef0 = sin(2.0*M_PI*out / 44100.0); - float coef1 = 1.0 - coef0; - float coef2 = q * (1.0 + 1.0 / coef1); - filt_coeffs[qidx][c][0] = (int32_t)(coef0 * 16777216.0); - filt_coeffs[qidx][c][1] = (int32_t)(coef1 * 16777216.0); - filt_coeffs[qidx][c][2] = (int32_t)(coef2 * 16777216.0); -#endif //FILTER_TYPE - /* 42.66 divisions per octave (the doc says quarter seminotes which is 48, but then it would be almost an octave less) */ - out *= 1.016378315; - /* 42 divisions. This moves the max frequency to 8.5Khz.*/ - //out *= 1.0166404394; - /* This is a linear increment method, that corresponds to the NRPN table, but contradicts the EMU8KPRM doc: */ - //out = 100.0 + (c+1.0)*31.25; //31.25Hz steps */ - } - } - /* NOTE! read_pos and buffer content is implicitly initialized to zero by the sb_t structure memset on sb_awe32_init() */ - emu8k->reverb_engine.reflections[0].bufsize=2*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[1].bufsize=4*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[2].bufsize=8*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[3].bufsize=13*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[4].bufsize=19*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[5].bufsize=26*REV_BUFSIZE_STEP; - - /*This is a bit random.*/ - for (c=0;c<4;c++) - { - emu8k->reverb_engine.allpass[3-c].feedback=0.5; - emu8k->reverb_engine.allpass[3-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; - emu8k->reverb_engine.allpass[7-c].feedback=0.5; - emu8k->reverb_engine.allpass[7-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; - } - - - - /* Cubic Resampling ( 4point cubic spline) */ - double const resdouble = 1.0/(double)CUBIC_RESOLUTION; - for (c = 0; c < CUBIC_RESOLUTION; c++) - { - double x = (double)c * resdouble; - /* Cubic resolution is made of four table, but I've put them all in one table to optimize memory access. */ - cubic_table[c*4] = (-0.5 * x * x * x + x * x - 0.5 * x) ; - cubic_table[c*4+1] = ( 1.5 * x * x * x - 2.5 * x * x + 1.0) ; - cubic_table[c*4+2] = (-1.5 * x * x * x + 2.0 * x * x + 0.5 * x) ; - cubic_table[c*4+3] = ( 0.5 * x * x * x - 0.5 * x * x) ; - } - /* Even when the documentation says that this has to be written by applications to initialize the card, - * several applications and drivers ( aweman on windows, linux oss driver..) read it to detect an AWE card. */ - emu8k->hwcf1 = 0x59; - emu8k->hwcf2 = 0x20; - /* Initial state is muted. 0x04 is unmuted. */ - emu8k->hwcf3 = 0x00; -} - -void emu8k_close(emu8k_t *emu8k) -{ - free(emu8k->rom); - free(emu8k->ram); -} - diff --git a/src - Cópia/sound/snd_emu8k.h b/src - Cópia/sound/snd_emu8k.h deleted file mode 100644 index 16323a13b..000000000 --- a/src - Cópia/sound/snd_emu8k.h +++ /dev/null @@ -1,775 +0,0 @@ - -/* All these defines are in samples, not in bytes. */ -#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF -#define EMU8K_RAM_MEM_START 0x200000 -#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 -#define EMU8K_RAM_POINTERS_MASK 0x3F -#define EMU8K_LFOCHORUS_SIZE 0x4000 -/* - * Everything in this file assumes little endian - */ -/* used for the increment of oscillator position*/ -typedef struct emu8k_mem_internal_t { - union { - uint64_t addr; - struct { - uint16_t fract_lw_address; - uint16_t fract_address; - uint32_t int_address; - }; - }; -} emu8k_mem_internal_t; - -/* used for access to ram pointers from oscillator position. */ -typedef struct emu8k_mem_pointers_t { - union { - uint32_t addr; - struct { - uint16_t lw_address; - uint8_t hb_address; - uint8_t unused_address; - }; - }; -} emu8k_mem_pointers_t; - -/* - * From the Soundfount 2.0 fileformat Spec.: - * - An envelope generates a control signal in six phases. - When key-on occurs, a delay period begins during which the envelope value is zero. - The envelope then rises in a convex curve to a value of one during the attack phase. - " Note that the attack is convex; the curve is nominally such that when applied to a - decibel or semitone parameter, the result is linear in amplitude or Hz respectively" - - When a value of one is reached, the envelope enters a hold phase during which it remains at one. - When the hold phase ends, the envelope enters a decay phase during which its value decreases linearly to a sustain level. - " For the Volume Envelope, the decay phase linearly ramps toward the sustain level, causing a constant dB change for each time unit. " - When the sustain level is reached, the envelope enters sustain phase, during which the envelope stays at the sustain level. - - Whenever a key-off occurs, the envelope immediately enters a release phase during which the value linearly ramps from the current value to zero. - " For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit" - - When zero is reached, the envelope value remains at zero. - - Modulation of pitch and filter cutoff are in octaves, semitones, and cents. - These parameters can be modulated to varying degree, either positively or negatively, by the modulation envelope. - The degree of modulation is specified in cents for the full-scale attack peak. - - The volume envelope operates in dB, with the attack peak providing a full scale output, appropriately scaled by the initial volume. - The zero value, however, is actually zero gain. - The implementation in the EMU8000 provides for 96 dB of amplitude control. - When 96 dB of attenuation is reached in the final gain amplifier, an abrupt jump to zero gain - (infinite dB of attenuation) occurs. In a 16-bit system, this jump is inaudible -*/ -/* It seems that the envelopes don't really have a decay/release stage, - * but instead they have a volume ramper that can be triggered - * automatically (after hold period), or manually (by activating release) - * and the "sustain" value is the target of any of both cases. - * Some programs like cubic player and AWEAmp use this, and it was - * described in the following way in Vince Vu/Judge Dredd's awe32p10.txt: - * If the MSB (most significant bit or bit 15) of this register is set, - * the Decay/Release will begin immediately, overriding the Delay, Attack, - * and Hold. Otherwise the Decay/Release will wait until the Delay, Attack, - * and Hold are finished. If you set the MSB of this register, you can use - * it as a volume ramper, as on the GUS. The upper byte (except the MSB), - * contains the destination volume, and the lower byte contains the ramp time. - */ - -/* attack_amount is linear amplitude (added directly to value). - * ramp_amount_db is linear dB (added directly to value too, but needs conversion to get linear amplitude). - * value range is 21bits for both, linear amplitude being 1<<21 = 0dBFS and 0 = -96dBFS (which is shortcut to silence), - * and db amplutide being 0 = 0dBFS and -(1<<21) = -96dBFS (which is shortcut to silence). - * This allows to operate db values by simply adding them. - */ -typedef struct emu8k_envelope_t { - int state; - int32_t delay_samples, hold_samples, attack_samples; - int32_t value_amp_hz, value_db_oct; - int32_t sustain_value_db_oct; - int32_t attack_amount_amp_hz, ramp_amount_db_oct; -} emu8k_envelope_t; - - - -typedef struct emu8k_chorus_eng_t { - int32_t write; - int32_t feedback; - int32_t delay_samples_central; - double lfodepth_multip; - double delay_offset_samples_right; - emu8k_mem_internal_t lfo_inc; - emu8k_mem_internal_t lfo_pos; - - int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; - int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; - -} emu8k_chorus_eng_t; - -/* 32 * 242. 32 comes from the "right" room resso case.*/ -#define MAX_REFL_SIZE 7744 - - -/* Reverb parameters description, extracted from AST sources. - Mix level - Decay - Link return amp - Link type Switches between normal or panned - Room reso ( ms) L&R (Ref 6 +1) - Ref 1 x2 (11 ms)R - Ref 2 x4 (22 ms)R - Ref 3 x8 (44 ms)L - Ref 4 x13(71 ms)R - Ref 5 x19(105ms)L - Ref 6 x ( ms)R (multiplier changes with room reso) - Ref 1-6 filter L&R - Ref 1-6 amp L&R - Ref 1 feedback L&R - Ref 2 feedback L&R - Ref 3 feedback L&R - Ref 4 feedback L&R - Ref 5 feedback L&R - Ref 6 feedback L&R -*/ -typedef struct emu8k_reverb_combfilter_t { - int read_pos; - int32_t reflection[MAX_REFL_SIZE]; - float output_gain; - float feedback; - float damp1; - float damp2; - int bufsize; - int32_t filterstore; -} emu8k_reverb_combfilter_t; - -typedef struct emu8k_reverb_eng_t { - - int16_t out_mix; - int16_t link_return_amp; /* tail part output gain ? */ - int8_t link_return_type; - - uint8_t refl_in_amp; - - emu8k_reverb_combfilter_t reflections[6]; - emu8k_reverb_combfilter_t allpass[8]; - emu8k_reverb_combfilter_t tailL; - emu8k_reverb_combfilter_t tailR; - - emu8k_reverb_combfilter_t damper; -} emu8k_reverb_eng_t; - -typedef struct emu8k_slide_t { - int32_t last; -} emu8k_slide_t; - - -typedef struct emu8k_voice_t -{ - union { - uint32_t cpf; - struct { - uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ - uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ - }; - }; - union { - uint32_t ptrx; - struct { - uint8_t ptrx_pan_aux; - uint8_t ptrx_revb_send; - uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ - }; - }; - union { - uint32_t cvcf; - struct { - uint16_t cvcf_curr_filt_ctoff; - uint16_t cvcf_curr_volume; - }; - }; - emu8k_slide_t volumeslide; - union { - uint32_t vtft; - struct { - uint16_t vtft_filter_target; - uint16_t vtft_vol_target; /* written to by the envelope engine. */ - }; - }; - /* These registers are used at least by the Windows drivers, and seem to be resetting - * something, similarly to targets and current, but... of what? - * what is curious is that if they are already zero, they are not written to, so it really - * looks like they are information about the status of the channel. (lfo position maybe?) */ - uint32_t unknown_data0_4; - uint32_t unknown_data0_5; - union { - uint32_t psst; - struct { - uint16_t psst_lw_address; - uint8_t psst_hw_address; - uint8_t psst_pan; - }; - #define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ - }; - union { - uint32_t csl; - struct { - uint16_t csl_lw_address; - uint8_t csl_hw_address; - uint8_t csl_chor_send; - }; - #define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ - }; - union { - uint32_t ccca; - struct { - uint16_t ccca_lw_addr; - uint8_t ccca_hb_addr; - uint8_t ccca_qcontrol; - }; - }; - #define CCCA_FILTQ_GET(ccca) (ccca>>28) - #define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28) - /* Bit 27 should always be zero */ - #define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000) - #define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000) - #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000) - - uint16_t envvol; - #define ENVVOL_NODELAY(envol) (envvol&0x8000) - /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ - #define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5) - - uint16_t dcysusv; - #define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000) - #define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080) - #define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F) - /* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ - #define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F) - #define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F) - - uint16_t envval; - #define ENVVAL_NODELAY(enval) (envval&0x8000) - /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ - #define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5) - - uint16_t dcysus; - #define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000) - #define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F) - #define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F) - #define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F) - - uint16_t atkhldv; - #define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000) - #define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F) - #define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F))) - #define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F) - - uint16_t lfo1val, lfo2val; - #define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000) - #define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5) - - uint16_t atkhld; - #define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000) - #define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F) - #define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F))) - #define ATKHLD_ATTACK(atkhld) (atkhld&0x7F) - - - uint16_t ip; - #define INTIAL_PITCH_CENTER 0xE000 - #define INTIAL_PITCH_OCTAVE 0x1000 - - union { - uint16_t ifatn; - struct{ - uint8_t ifatn_attenuation; - uint8_t ifatn_init_filter; - }; - }; - union { - uint16_t pefe; - struct { - int8_t pefe_modenv_filter_height; - int8_t pefe_modenv_pitch_height; - }; - }; - union { - uint16_t fmmod; - struct { - int8_t fmmod_lfo1_filt_mod; - int8_t fmmod_lfo1_vibrato; - }; - }; - union { - uint16_t tremfrq; - struct { - uint8_t tremfrq_lfo1_freq; - int8_t tremfrq_lfo1_tremolo; - }; - }; - union { - uint16_t fm2frq2; - struct { - uint8_t fm2frq2_lfo2_freq; - int8_t fm2frq2_lfo2_vibrato; - }; - }; - - int env_engine_on; - - emu8k_mem_internal_t addr, loop_start, loop_end; - - int32_t initial_att; - int32_t initial_filter; - - emu8k_envelope_t vol_envelope; - emu8k_envelope_t mod_envelope; - - int64_t lfo1_speed, lfo2_speed; - emu8k_mem_internal_t lfo1_count, lfo2_count; - int32_t lfo1_delay_samples, lfo2_delay_samples; - int vol_l, vol_r; - - int16_t fixed_modenv_filter_height; - int16_t fixed_modenv_pitch_height; - int16_t fixed_lfo1_filt_mod; - int16_t fixed_lfo1_vibrato; - int16_t fixed_lfo1_tremolo; - int16_t fixed_lfo2_vibrato; - - /* filter internal data. */ - int filterq_idx; - int32_t filt_att; - int64_t filt_buffer[5]; - -} emu8k_voice_t; - -typedef struct emu8k_t -{ - emu8k_voice_t voice[32]; - - uint16_t hwcf1, hwcf2, hwcf3; - uint32_t hwcf4, hwcf5, hwcf6, hwcf7; - - uint16_t init1[32], init2[32], init3[32], init4[32]; - - uint32_t smalr, smarr, smalw, smarw; - uint16_t smld_buffer, smrd_buffer; - - uint16_t wc; - - uint16_t id; - - /* The empty block is used to act as an unallocated memory returning zero. */ - int16_t *ram, *rom, *empty; - - /* RAM pointers are a way to avoid checking ram boundaries on read */ - int16_t *ram_pointers[0x100]; - uint32_t ram_end_addr; - - int cur_reg, cur_voice; - - int16_t out_l, out_r; - - emu8k_chorus_eng_t chorus_engine; - int32_t chorus_in_buffer[SOUNDBUFLEN]; - emu8k_reverb_eng_t reverb_engine; - int32_t reverb_in_buffer[SOUNDBUFLEN]; - - int pos; - int32_t buffer[SOUNDBUFLEN * 2]; -} emu8k_t; - - - -void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram); -void emu8k_close(emu8k_t *emu8k); - -void emu8k_update(emu8k_t *emu8k); - - - - -/* - -Section E - Introduction to the EMU8000 Chip - - The EMU8000 has its roots in E-mu's Proteus sample playback - modules and their renowned Emulator sampler. The EMU8000 has - 32 individual oscillators, each playing back at 44.1 kHz. By - incorporating sophisticated sample interpolation algorithms - and digital filtering, the EMU8000 is capable of producing - high fidelity sample playback. - - The EMU8000 has an extensive modulation capability using two - sine-wave LFOs (Low Frequency Oscillator) and two multi- - stage envelope generators. - - What exactly does modulation mean? Modulation means to - dynamically change a parameter of an audio signal, whether - it be the volume (amplitude modulation, or tremolo), pitch - (frequency modulation, or vibrato) or filter cutoff - frequency (filter modulation, or wah-wah). To modulate - something we would require a modulation source, and a - modulation destination. In the EMU8000, the modulation - sources are the LFOs and the envelope generators, and the - modulation destinations can be the pitch, the volume or the - filter cutoff frequency. - - The EMU8000's LFOs and envelope generators provide a complex - modulation environment. Each sound producing element of the - EMU8000 consists of a resonant low-pass filter, two LFOs, in - which one modulates the pitch (LFO2), and the other - modulates pitch, filter cutoff and volume (LFO1) - simultaneously. There are two envelope generators; envelope - 1 contours both pitch and filter cutoff simultaneously, and - envelope 2 contours volume. The output stage consists of an - effects engine that mixes the dry signals with the - Reverb/chorus level signals to produce the final mix. - - What are the EMU8000 sound elements? - - Each of the sound elements in an EMU8000 consists of the - following: - - Oscillator - An oscillator is the source of an audio signal. - - Low Pass Filter - The low pass filter is responsible for modifying the - timbres of an instrument. The low pass filter's filter - cutoff values can be varied from 100 Hz to 8000 Hz. By - changing the values of the filter cutoff, a myriad of - analogue sounding filter sweeps can be achieved. An - example of a GM instrument that makes use of filter sweep - is instrument number 87, Lead 7 (fifths). - - Amplifier - The amplifier determines the loudness of an audio signal. - - LFO1 - An LFO, or Low Frequency Oscillator, is normally used to - periodically modulate, that is, change a sound parameter, - whether it be volume (amplitude modulation), pitch - (frequency modulation) or filter cutoff (filter - modulation). It operates at sub-audio frequency from - 0.042 Hz to 10.71 Hz. The LFO1 in the EMU8000 modulates - the pitch, volume and filter cutoff simultaneously. - - LFO2 - The LFO2 is similar to the LFO1, except that it modulates - the pitch of the audio signal only. - - Resonance - A filter alone would be like an equalizer, making a - bright audio signal duller, but the addition of resonance - greatly increases the creative potential of a filter. - Increasing the resonance of a filter makes it emphasize - signals at the cutoff frequency, giving the audio signal - a subtle wah-wah, that is, imagine a siren sound going - from bright to dull to bright again periodically. - - LFO1 to Volume (Tremolo) - The LFO1's output is routed to the amplifier, with the - depth of oscillation determined by LFO1 to Volume. LFO1 - to Volume produces tremolo, which is a periodic - fluctuation of volume. Lets say you are listening to a - piece of music on your home stereo system. When you - rapidly increase and decrease the playback volume, you - are creating tremolo effect, and the speed in which you - increases and decreases the volume is the tremolo rate - (which corresponds to the speed at which the LFO is - oscillating). An example of a GM instrument that makes - use of LFO1 to Volume is instrument number 45, Tremolo - Strings. - - LFO1 to Filter Cutoff (Wah-Wah) - The LFO1's output is routed to the filter, with the depth - of oscillation determined by LFO1 to Filter. LFO1 to - Filter produces a periodic fluctuation in the filter - cutoff frequency, producing an effect very similar to - that of a wah-wah guitar (see resonance for a description - of wah-wah) An example of a GM instrument that makes - use of LFO1 to Filter Cutoff is instrument number 19, - Rock Organ. - - LFO1 to Pitch (Vibrato) - The LFO1's output is routed to the oscillator, with the - depth of oscillation determined by LFO1 to Pitch. LFO1 to - Pitch produces a periodic fluctuation in the pitch of the - oscillator, producing a vibrato effect. An example of a - GM instrument that makes use of LFO1 to Pitch is - instrument number 57, Trumpet. - - LFO2 to Pitch (Vibrato) - The LFO1 in the EMU8000 can simultaneously modulate - pitch, volume and filter. LFO2, on the other hand, - modulates only the pitch, with the depth of modulation - determined by LFO2 to Pitch. LFO2 to Pitch produces a - periodic fluctuation in the pitch of the oscillator, - producing a vibrato effect. When this is coupled with - LFO1 to Pitch, a complex vibrato effect can be achieved. - - Volume Envelope - The character of a musical instrument is largely - determined by its volume envelope, the way in which the - level of the sound changes with time. For example, - percussive sounds usually start suddenly and then die - away, whereas a bowed sound might take quite some time to - start and then sustain at a more or less fixed level. - - A six-stage envelope makes up the volume envelope of the - EMU8000. The six stages are delay, attack, hold, decay, - sustain and release. The stages can be described as - follows: - - Delay The time between when a key is played and when - the attack phase begins - Attack The time it takes to go from zero to the peak - (full) level. - Hold The time the envelope will stay at the peak - level before starting the decay phase. - Decay The time it takes the envelope to go from the - peak level to the sustain level. - Sustain The level at which the envelope remains as long - as a key is held down. - Release The time it takes the envelope to fall to the - zero level after the key is released. - - Using these six parameters can yield very realistic - reproduction of the volume envelope characteristics of - many musical instruments. - - Pitch and Filter Envelope - The pitch and filter envelope is similar to the volume - envelope in that it has the same envelope stages. The - difference between them is that whereas the volume - envelope contours the volume of the instrument over time, - the pitch and filter envelope contours the pitch and - filter values of the instrument over time. The pitch - envelope is particularly useful in putting the finishing - touches in simulating a natural instrument. For example, - some wind instruments tend to go slightly sharp when they - are first blown, and this characteristic can be simulated - by setting up a pitch envelope with a fairly fast attack - and decay. The filter envelope, on the other hand, is - useful in creating synthetic sci-fi sound textures. An - example of a GM instrument that makes use of the filter - envelope is instrument number 86, Pad 8 (Sweep). - - Pitch/Filter Envelope Modulation - These two parameters determine the modulation depth of - the pitch and filter envelope. In the wind instrument - example above, a small amount of pitch envelope - modulation is desirable to simulate its natural pitch - characteristics. - - This rich modulation capability of the EMU8000 is fully - exploited by the SB AWE32 MIDI drivers. The driver also - provides you with a means to change these parameters over - MIDI in real time. Refer to the section "How do I change an - instrument's sound parameter in real time" for more - information. - - - - - Room 1 - 3 - This group of reverb variation simulates the natural - ambiance of a room. Room 1 simulates a small room, Room 2 - simulates a slightly bigger room, and Room 3 simulates a - big room. - - Hall 1 - 2 - This group of reverb variation simulates the natural - ambiance of a concert hall. It has greater depth than the - room variations. Again, Hall 1 simulates a small hall, - and Hall 2 simulates a larger hall. - - Plate - Back in the old days, reverb effects were sometimes - produced using a metal plate, and this type of reverb - produces a metallic echo. The SB AWE32's Plate variation - simulates this form of reverb. - - Delay - This reverb produces a delay, that is, echo effect. - - Panning Delay - This reverb variation produces a delay effect that is - continuously panned left and right. - - Chorus 1 - 4 - Chorus produces a "beating" effect. The chorus effects - are more prominent going from chorus 1 to chorus 4. - - Feedback Chorus - This chorus variation simulates a soft "swishing" effect. - - Flanger - This chorus variation produces a more prominent feedback - chorus effect. - - Short Delay - This chorus variation simulates a delay repeated in a - short time. - - Short Delay (feed back) - This chorus variation simulates a short delay repeated - (feedback) many times. - - - -Registers to write the Chorus Parameters to (all are 16-bit, unless noted): -(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) -( 3409 = register 3, port A20, voice 9) - -0x3409 -0x340C -0x3603 -0x1409 (32-Bit) -0x140A (32-Bit) -then write 0x8000 to 0x140D (32-Bit) -and then 0x0000 to 0x140E (32-Bit) - -Chorus Parameters: - -Chorus 1 Chorus 2 Chorus 3 Chorus 4 Feedback Flanger - -0xE600 0xE608 0xE610 0xE620 0xE680 0xE6E0 -0x03F6 0x031A 0x031A 0x0269 0x04D3 0x044E -0xBC2C 0xBC6E 0xBC84 0xBC6E 0xBCA6 0xBC37 -0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 -0x006D 0x017C 0x0083 0x017C 0x005B 0x0026 - -Short Delay Short Delay + Feedback - -0xE600 0xE6C0 -0x0B06 0x0B06 -0xBC00 0xBC00 -0xE000 0xE000 -0x0083 0x0083 - -// Chorus Params -typedef struct { - WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) - WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] - WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) - DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] - DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) - } CHORUS_TYPE; - - -Registers to write the Reverb Parameters to (they are all 16-bit): -(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) -( 3409 = register 3, port A20, voice 9) - -0x2403,0x2405,0x361F,0x2407,0x2614,0x2616,0x240F,0x2417, -0x241F,0x2607,0x260F,0x2617,0x261D,0x261F,0x3401,0x3403, -0x2409,0x240B,0x2411,0x2413,0x2419,0x241B,0x2601,0x2603, -0x2609,0x260B,0x2611,0x2613 - -Reverb Parameters: - -Room 1: - -0xB488,0xA450,0x9550,0x84B5,0x383A,0x3EB5,0x72F4,0x72A4, -0x7254,0x7204,0x7204,0x7204,0x4416,0x4516,0xA490,0xA590, -0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, -0x8428,0x8528,0x8428,0x8528 - -Room 2: - -0xB488,0xA458,0x9558,0x84B5,0x383A,0x3EB5,0x7284,0x7254, -0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, -0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, -0x8428,0x8528,0x8428,0x8528 - -Room 3: - -0xB488,0xA460,0x9560,0x84B5,0x383A,0x3EB5,0x7284,0x7254, -0x7224,0x7224,0x7254,0x7284,0x4416,0x4516,0xA490,0xA590, -0x842C,0x852C,0x842C,0x852C,0x842B,0x852B,0x842B,0x852B, -0x842A,0x852A,0x842A,0x852A - -Hall 1: - -0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7284,0x7254, -0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, -0x842B,0x852B,0x842B,0x852B,0x842A,0x852A,0x842A,0x852A, -0x8429,0x8529,0x8429,0x8529 - -Hall 2: - -0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7254,0x7234, -0x7224,0x7254,0x7264,0x7294,0x44C3,0x45C3,0xA404,0xA504, -0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, -0x8428,0x8528,0x8428,0x8528 - -Plate: - -0xB4FF,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7234,0x7234, -0x7234,0x7234,0x7234,0x7234,0x4448,0x4548,0xA440,0xA540, -0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, -0x8428,0x8528,0x8428,0x8528 - -Delay: - -0xB4FF,0xA470,0x9500,0x84B5,0x333A,0x39B5,0x7204,0x7204, -0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, -0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, -0x8420,0x8520,0x8420,0x8520 - -Panning Delay: - -0xB4FF,0xA490,0x9590,0x8474,0x333A,0x39B5,0x7204,0x7204, -0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, -0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, -0x8420,0x8520,0x8420,0x8520 - -Registers to write the EQ Parameters to (16-Bit): -(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) -( 3409 = register 3, port A20, voice 9) - -Bass: - -0x3601 -0x3611 - -Treble: - -0x3411 -0x3413 -0x341B -0x3607 -0x360B -0x360D -0x3617 -0x3619 - -Total: - -write the 0x0263 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. -write the 0x8363 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. - - -Bass Parameters: - -0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: - -0xD26A 0xD25B 0xD24C 0xD23D 0xD21F 0xC208 0xC219 0xC22A 0xC24C 0xC26E 0xC248 0xC26A -0xD36A 0xD35B 0xD34C 0xD33D 0xC31F 0xC308 0xC308 0xC32A 0xC34C 0xC36E 0xC384 0xC36A -0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 - -Treble Parameters: - -0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: -0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821D 0x821C -0xC26A 0xC25B 0xC24C 0xC23D 0xC21F 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A -0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031D 0x031C -0xC36A 0xC35B 0xC34C 0xC33D 0xC31F 0xD308 0xD308 0xD308 0xD308 0xD308 0xD319 0xD32A -0x021E 0x021E 0x021E 0x021E 0x021E 0x021E 0x021D 0x021C 0x021A 0x0219 0x0219 0x0219 -0xD208 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A 0xD24C 0xD26E 0xD26E 0xD26E -0x831E 0x831E 0x831E 0x831E 0x831E 0x831E 0x831D 0x831C 0x831A 0x8319 0x8319 0x8319 -0xD308 0xD308 0xD308 0xD308 0xD308 0xD308 0xD3019 0xD32A 0xD34C 0xD36E 0xD36E 0xD36E -0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 -*/ diff --git a/src - Cópia/sound/snd_gus.c b/src - Cópia/sound/snd_gus.c deleted file mode 100644 index 3bd367e63..000000000 --- a/src - Cópia/sound/snd_gus.c +++ /dev/null @@ -1,1067 +0,0 @@ -#include -#include -#include -#include -#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 "sound.h" -#include "snd_gus.h" - - -typedef struct gus_t -{ - int reset; - - int global; - uint32_t addr,dmaaddr; - int voice; - uint32_t start[32],end[32],cur[32]; - uint32_t startx[32],endx[32],curx[32]; - int rstart[32],rend[32]; - int rcur[32]; - uint16_t freq[32]; - uint16_t rfreq[32]; - uint8_t ctrl[32]; - uint8_t rctrl[32]; - int curvol[32]; - int pan_l[32], pan_r[32]; - int t1on,t2on; - uint8_t tctrl; - uint16_t t1,t2,t1l,t2l; - uint8_t irqstatus,irqstatus2; - uint8_t adcommand; - int waveirqs[32],rampirqs[32]; - int voices; - uint8_t dmactrl; - - int32_t out_l, out_r; - - int16_t buffer[2][SOUNDBUFLEN]; - int pos; - - int64_t samp_timer, samp_latch; - - uint8_t *ram; - - int irqnext; - - int64_t timer_1, timer_2; - - int irq, dma, irq_midi; - int latch_enable; - - uint8_t sb_2xa, sb_2xc, sb_2xe; - uint8_t sb_ctrl; - int sb_nmi; - - uint8_t reg_ctrl; - - uint8_t ad_status, ad_data; - uint8_t ad_timer_ctrl; - - uint8_t midi_ctrl, midi_status; - uint8_t midi_data; - int midi_loopback; - - uint8_t gp1, gp2; - uint16_t gp1_addr, gp2_addr; - - uint8_t usrr; -} gus_t; - -static int gus_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; -static int gus_irqs_midi[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; -static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1}; - -int gusfreqs[]= -{ - 44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696, - 23746,22866,22050,21289,20580,19916,19293 -}; - -double vol16bit[4096]; - -void pollgusirqs(gus_t *gus) -{ - int c; - - gus->irqstatus&=~0x60; - for (c=0;c<32;c++) - { - if (gus->waveirqs[c]) - { - gus->irqstatus2=0x60|c; - if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80; - gus->irqstatus|=0x20; - if (gus->irq != -1) - picint(1 << gus->irq); - return; - } - if (gus->rampirqs[c]) - { - gus->irqstatus2=0xA0|c; - gus->irqstatus|=0x40; - if (gus->irq != -1) - picint(1 << gus->irq); - return; - } - } - gus->irqstatus2=0xE0; - if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq); -} - -enum -{ - MIDI_INT_RECEIVE = 0x01, - MIDI_INT_TRANSMIT = 0x02, - MIDI_INT_MASTER = 0x80 -}; - -enum -{ - MIDI_CTRL_TRANSMIT_MASK = 0x60, - MIDI_CTRL_TRANSMIT = 0x20, - MIDI_CTRL_RECEIVE = 0x80 -}; - -enum -{ - GUS_INT_MIDI_TRANSMIT = 0x01, - GUS_INT_MIDI_RECEIVE = 0x02 -}; - -enum -{ - GUS_TIMER_CTRL_AUTO = 0x01 -}; - -void gus_midi_update_int_status(gus_t *gus) -{ - gus->midi_status &= ~MIDI_INT_MASTER; - if ((gus->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (gus->midi_status & MIDI_INT_TRANSMIT)) - { - gus->midi_status |= MIDI_INT_MASTER; - gus->irqstatus |= GUS_INT_MIDI_TRANSMIT; - } - else - gus->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; - - if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE)) - { - gus->midi_status |= MIDI_INT_MASTER; - gus->irqstatus |= GUS_INT_MIDI_RECEIVE; - } - else - gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE; - - if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1)) - { - picint(1 << gus->irq_midi); - } -} - -void writegus(uint16_t addr, uint8_t val, void *p) -{ - gus_t *gus = (gus_t *)p; - int c, d; - int old; - if (gus->latch_enable && addr != 0x24b) - gus->latch_enable = 0; - switch (addr) - { - case 0x340: /*MIDI control*/ - old = gus->midi_ctrl; - gus->midi_ctrl = val; - - if ((val & 3) == 3) - gus->midi_status = 0; - else if ((old & 3) == 3) - { - gus->midi_status |= MIDI_INT_TRANSMIT; - } - gus_midi_update_int_status(gus); - break; - - case 0x341: /*MIDI data*/ - if (gus->midi_loopback) - { - gus->midi_status |= MIDI_INT_RECEIVE; - gus->midi_data = val; - } - else - gus->midi_status |= MIDI_INT_TRANSMIT; - break; - - case 0x342: /*Voice select*/ - gus->voice=val&31; - break; - case 0x343: /*Global select*/ - gus->global=val; - break; - case 0x344: /*Global low*/ - switch (gus->global) - { - case 0: /*Voice control*/ - gus->ctrl[gus->voice]=val; - break; - case 1: /*Frequency control*/ - gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF00)|val; - break; - case 2: /*Start addr high*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0xF807F)|(val<<7); - gus->start[gus->voice]=(gus->start[gus->voice]&0x1F00FFFF)|(val<<16); - break; - case 3: /*Start addr low*/ - gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFFFF00)|val; - break; - case 4: /*End addr high*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0xF807F)|(val<<7); - gus->end[gus->voice]=(gus->end[gus->voice]&0x1F00FFFF)|(val<<16); - break; - case 5: /*End addr low*/ - gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFFFF00)|val; - break; - - case 0x6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); - break; - - case 0x9: /*Current volume*/ - gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); - break; - - case 0xA: /*Current addr high*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); - break; - case 0xB: /*Current addr low*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val; - break; - - case 0x42: /*DMA address low*/ - gus->dmaaddr=(gus->dmaaddr&0xFF000)|(val<<4); - break; - - case 0x43: /*Address low*/ - gus->addr=(gus->addr&0xFFF00)|val; - break; - case 0x45: /*Timer control*/ - gus->tctrl=val; - break; - } - break; - case 0x345: /*Global high*/ - switch (gus->global) - { - case 0: /*Voice control*/ - if (!(val&1) && gus->ctrl[gus->voice]&1) - { - } - - gus->ctrl[gus->voice] = val & 0x7f; - - old = gus->waveirqs[gus->voice]; - gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (gus->waveirqs[gus->voice] != old) - pollgusirqs(gus); - break; - case 1: /*Frequency control*/ - gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8); - break; - case 2: /*Start addr high*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0x07FFF)|(val<<15); - gus->start[gus->voice]=(gus->start[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - break; - case 3: /*Start addr low*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0xFFF80)|(val&0x7F); - gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFF00FF)|(val<<8); - break; - case 4: /*End addr high*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0x07FFF)|(val<<15); - gus->end[gus->voice]=(gus->end[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - break; - case 5: /*End addr low*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0xFFF80)|(val&0x7F); - gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFF00FF)|(val<<8); - break; - - case 0x6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)( (double)((val & 63) * (1 << 10))/(double)(1 << (3 * (val >> 6)))); - break; - case 0x7: /*Ramp start*/ - gus->rstart[gus->voice] = val << 14; - break; - case 0x8: /*Ramp end*/ - gus->rend[gus->voice] = val << 14; - break; - case 0x9: /*Current volume*/ - gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); - break; - - case 0xA: /*Current addr high*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - gus->curx[gus->voice]=(gus->curx[gus->voice]&0x07FFF00)|((val<<15)<<8); - break; - case 0xB: /*Current addr low*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); - break; - case 0xC: /*Pan*/ - gus->pan_l[gus->voice] = 15 - (val & 0xf); - gus->pan_r[gus->voice] = (val & 0xf); - break; - case 0xD: /*Ramp control*/ - old = gus->rampirqs[gus->voice]; - gus->rctrl[gus->voice] = val & 0x7F; - gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (gus->rampirqs[gus->voice] != old) - pollgusirqs(gus); - break; - - case 0xE: - gus->voices=(val&63)+1; - if (gus->voices>32) gus->voices=32; - if (gus->voices<14) gus->voices=14; - gus->global=val; - if (gus->voices < 14) - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); - break; - - case 0x41: /*DMA*/ - if (val&1 && gus->dma != -1) - { - if (val & 2) - { - c=0; - while (c<65536) - { - int dma_result; - if (val & 0x04) - { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); - if (val & 0x80) - d ^= 0x8080; - dma_result = dma_channel_write(gus->dma, d); - if (dma_result == DMA_NODATA) - break; - } - else - { - d = gus->ram[gus->dmaaddr]; - if (val & 0x80) - d ^= 0x80; - dma_result = dma_channel_write(gus->dma, d); - if (dma_result == DMA_NODATA) - break; - } - gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; - c++; - if (dma_result & DMA_OVER) - break; - } - gus->dmactrl=val&~0x40; - if (val&0x20) gus->irqnext=1; - } - else - { - c=0; - while (c<65536) - { - d = dma_channel_read(gus->dma); - if (d == DMA_NODATA) - break; - if (val & 0x04) - { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - if (val & 0x80) - d ^= 0x8080; - gus->ram[gus_addr] = d & 0xff; - gus->ram[gus_addr +1] = (d >> 8) & 0xff; - } - else - { - if (val & 0x80) - d ^= 0x80; - gus->ram[gus->dmaaddr] = d; - } - gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; - c++; - if (d & DMA_OVER) - break; - } - gus->dmactrl=val&~0x40; - if (val&0x20) gus->irqnext=1; - } - } - break; - - case 0x42: /*DMA address low*/ - gus->dmaaddr=(gus->dmaaddr&0xFF0)|(val<<12); - break; - - case 0x43: /*Address low*/ - gus->addr=(gus->addr&0xF00FF)|(val<<8); - break; - case 0x44: /*Address high*/ - gus->addr=(gus->addr&0xFFFF)|((val<<16)&0xF0000); - break; - case 0x45: /*Timer control*/ - if (!(val&4)) gus->irqstatus&=~4; - if (!(val&8)) gus->irqstatus&=~8; - if (!(val & 0x20)) - { - gus->ad_status &= ~0x18; - nmi = 0; - } - if (!(val & 0x02)) - { - gus->ad_status &= ~0x01; - nmi = 0; - } - gus->tctrl=val; - gus->sb_ctrl = val; - break; - case 0x46: /*Timer 1*/ - gus->t1 = gus->t1l = val; - gus->t1on = 1; - break; - case 0x47: /*Timer 2*/ - gus->t2 = gus->t2l = val; - gus->t2on = 1; - break; - - case 0x4c: /*Reset*/ - gus->reset = val; - break; - } - break; - case 0x347: /*DRAM access*/ - gus->ram[gus->addr]=val; - gus->addr&=0xFFFFF; - break; - case 0x248: case 0x388: - gus->adcommand = val; - break; - - case 0x389: - if ((gus->tctrl & GUS_TIMER_CTRL_AUTO) || gus->adcommand != 4) - { - gus->ad_data = val; - gus->ad_status |= 0x01; - if (gus->sb_ctrl & 0x02) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - } - else if (!(gus->tctrl & GUS_TIMER_CTRL_AUTO) && gus->adcommand == 4) - { - if (val & 0x80) - { - gus->ad_status &= ~0x60; - } - else - { - gus->ad_timer_ctrl = val; - - if (val & 0x01) - gus->t1on = 1; - else - gus->t1 = gus->t1l; - - if (val & 0x02) - gus->t2on = 1; - else - gus->t2 = gus->t2l; - } - } - break; - - case 0x240: - gus->midi_loopback = val & 0x20; - gus->latch_enable = (val & 0x40) ? 2 : 1; - break; - - case 0x24b: - switch (gus->reg_ctrl & 0x07) - { - case 0: - if (gus->latch_enable == 1) - gus->dma = gus_dmas[val & 7]; - if (gus->latch_enable == 2) - { - gus->irq = gus_irqs[val & 7]; - - if (val & 0x40) - { - if (gus->irq == -1) - gus->irq = gus->irq_midi = gus_irqs[(val >> 3) & 7]; - else - gus->irq_midi = gus->irq; - } - else - gus->irq_midi = gus_irqs_midi[(val >> 3) & 7]; - - gus->sb_nmi = val & 0x80; - } - gus->latch_enable = 0; - break; - case 1: - gus->gp1 = val; - break; - case 2: - gus->gp2 = val; - break; - case 3: - gus->gp1_addr = val; - break; - case 4: - gus->gp2_addr = val; - break; - case 5: - gus->usrr = 0; - break; - case 6: - break; - } - break; - - case 0x246: - gus->ad_status |= 0x08; - if (gus->sb_ctrl & 0x20) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - break; - case 0x24a: - gus->sb_2xa = val; - break; - case 0x24c: - gus->ad_status |= 0x10; - if (gus->sb_ctrl & 0x20) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - case 0x24d: - gus->sb_2xc = val; - break; - case 0x24e: - gus->sb_2xe = val; - break; - case 0x24f: - gus->reg_ctrl = val; - break; - } -} - -uint8_t readgus(uint16_t addr, void *p) -{ - gus_t *gus = (gus_t *)p; - uint8_t val = 0xff; - switch (addr) - { - case 0x340: /*MIDI status*/ - val = gus->midi_status; - break; - - case 0x341: /*MIDI data*/ - val = gus->midi_data; - gus->midi_status &= ~MIDI_INT_RECEIVE; - gus_midi_update_int_status(gus); - break; - - case 0x240: return 0; - case 0x246: /*IRQ status*/ - val = gus->irqstatus & ~0x10; - if (gus->ad_status & 0x19) - val |= 0x10; - return val; - - case 0x24F: return 0; - case 0x342: return gus->voice; - case 0x343: return gus->global; - case 0x344: /*Global low*/ - switch (gus->global) - { - case 0x82: /*Start addr high*/ - return gus->start[gus->voice]>>16; - case 0x83: /*Start addr low*/ - return gus->start[gus->voice]&0xFF; - - case 0x89: /*Current volume*/ - return gus->rcur[gus->voice]>>6; - case 0x8A: /*Current addr high*/ - return gus->cur[gus->voice]>>16; - case 0x8B: /*Current addr low*/ - return gus->cur[gus->voice]&0xFF; - - case 0x8F: /*IRQ status*/ - val=gus->irqstatus2; - gus->rampirqs[gus->irqstatus2&0x1F]=0; - gus->waveirqs[gus->irqstatus2&0x1F]=0; - pollgusirqs(gus); - return val; - - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - val = 0xff; - break; - } - break; - case 0x345: /*Global high*/ - switch (gus->global) - { - case 0x80: /*Voice control*/ - return gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0); - - case 0x82: /*Start addr high*/ - return gus->start[gus->voice]>>24; - case 0x83: /*Start addr low*/ - return gus->start[gus->voice]>>8; - - case 0x89: /*Current volume*/ - return gus->rcur[gus->voice]>>14; - - case 0x8A: /*Current addr high*/ - return gus->cur[gus->voice]>>24; - case 0x8B: /*Current addr low*/ - return gus->cur[gus->voice]>>8; - - case 0x8C: /*Pan*/ - return gus->pan_r[gus->voice]; - - case 0x8D: - return gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0); - - case 0x8F: /*IRQ status*/ - val=gus->irqstatus2; - gus->rampirqs[gus->irqstatus2&0x1F]=0; - gus->waveirqs[gus->irqstatus2&0x1F]=0; - pollgusirqs(gus); - return val; - - case 0x41: /*DMA control*/ - val=gus->dmactrl|((gus->irqstatus&0x80)?0x40:0); - gus->irqstatus&=~0x80; - return val; - case 0x45: /*Timer control*/ - return gus->tctrl; - case 0x49: /*Sampling control*/ - return 0; - - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - val = 0xff; - break; - } - break; - case 0x346: return 0xff; - case 0x347: /*DRAM access*/ - val=gus->ram[gus->addr]; - gus->addr&=0xFFFFF; - return val; - case 0x349: return 0; - case 0x746: /*Revision level*/ - return 0xff; /*Pre 3.7 - no mixer*/ - - case 0x24b: - switch (gus->reg_ctrl & 0x07) - { - case 1: - val = gus->gp1; - break; - case 2: - val = gus->gp2; - break; - case 3: - val = gus->gp1_addr; - break; - case 4: - val = gus->gp2_addr; - break; - } - break; - - case 0x24c: - val = gus->sb_2xc; - if (gus->reg_ctrl & 0x20) - gus->sb_2xc &= 0x80; - break; - case 0x24e: - return gus->sb_2xe; - - case 0x248: case 0x388: - if (gus->tctrl & GUS_TIMER_CTRL_AUTO) - val = gus->sb_2xa; - else - { - val = gus->ad_status & ~(gus->ad_timer_ctrl & 0x60); - if (val & 0x60) - val |= 0x80; - } - break; - - case 0x249: - gus->ad_status &= ~0x01; - nmi = 0; - case 0x389: - val = gus->ad_data; - break; - - case 0x24A: - val = gus->adcommand; - break; - - } - return val; -} - -void gus_poll_timer_1(void *p) -{ - gus_t *gus = (gus_t *)p; - - gus->timer_1 += (TIMER_USEC * 80LL); - if (gus->t1on) - { - gus->t1++; - if (gus->t1 > 0xFF) - { - gus->t1=gus->t1l; - gus->ad_status |= 0x40; - if (gus->tctrl&4) - { - if (gus->irq != -1) - picint(1 << gus->irq); - gus->ad_status |= 0x04; - gus->irqstatus |= 0x04; - } - } - } - if (gus->irqnext) - { - gus->irqnext=0; - gus->irqstatus|=0x80; - if (gus->irq != -1) - picint(1 << gus->irq); - } - gus_midi_update_int_status(gus); -} - -void gus_poll_timer_2(void *p) -{ - gus_t *gus = (gus_t *)p; - - gus->timer_2 += (TIMER_USEC * 320LL); - if (gus->t2on) - { - gus->t2++; - if (gus->t2 > 0xFF) - { - gus->t2=gus->t2l; - gus->ad_status |= 0x20; - if (gus->tctrl&8) - { - if (gus->irq != -1) - picint(1 << gus->irq); - gus->ad_status |= 0x02; - gus->irqstatus |= 0x08; - } - } - } - if (gus->irqnext) - { - gus->irqnext=0; - gus->irqstatus|=0x80; - if (gus->irq != -1) - picint(1 << gus->irq); - } -} - -static void gus_update(gus_t *gus) -{ - for (; gus->pos < sound_pos_global; gus->pos++) - { - if (gus->out_l < -32768) - gus->buffer[0][gus->pos] = -32768; - else if (gus->out_l > 32767) - gus->buffer[0][gus->pos] = 32767; - else - gus->buffer[0][gus->pos] = gus->out_l; - if (gus->out_r < -32768) - gus->buffer[1][gus->pos] = -32768; - else if (gus->out_r > 32767) - gus->buffer[1][gus->pos] = 32767; - else - gus->buffer[1][gus->pos] = gus->out_r; - } -} - -void gus_poll_wave(void *p) -{ - gus_t *gus = (gus_t *)p; - uint32_t addr; - int d; - int16_t v; - int32_t vl; - int update_irqs = 0; - - gus_update(gus); - - gus->samp_timer += gus->samp_latch; - - gus->out_l = gus->out_r = 0; - - if ((gus->reset & 3) != 3) - return; - for (d=0;d<32;d++) - { - if (!(gus->ctrl[d] & 3)) - { - if (gus->ctrl[d] & 4) - { - addr = gus->cur[d] >> 9; - addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); - vl += (int16_t)(int8_t)((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); - } - else - { - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = ((int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); - vl += ((int8_t)((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); - } - - if ((gus->rcur[d] >> 14) > 4095) v = (int16_t)(float)(v) * 24.0 * vol16bit[4095]; - else v = (int16_t)(float)(v) * 24.0 * vol16bit[(gus->rcur[d]>>10) & 4095]; - - gus->out_l += (v * gus->pan_l[d]) / 7; - gus->out_r += (v * gus->pan_r[d]) / 7; - - if (gus->ctrl[d]&0x40) - { - gus->cur[d] -= (gus->freq[d] >> 1); - if (gus->cur[d] <= gus->start[d]) - { - int diff = gus->start[d] - gus->cur[d]; - - if (gus->ctrl[d]&8) - { - if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); - } - else if (!(gus->rctrl[d]&4)) - { - gus->ctrl[d] |= 1; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; - } - - if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) - { - gus->waveirqs[d] = 1; - update_irqs = 1; - } - } - } - else - { - gus->cur[d] += (gus->freq[d] >> 1); - - if (gus->cur[d] >= gus->end[d]) - { - int diff = gus->cur[d] - gus->end[d]; - - if (gus->ctrl[d]&8) - { - if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); - } - else if (!(gus->rctrl[d]&4)) - { - gus->ctrl[d] |= 1; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; - } - - if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) - { - gus->waveirqs[d] = 1; - update_irqs = 1; - } - } - } - } - if (!(gus->rctrl[d] & 3)) - { - if (gus->rctrl[d] & 0x40) - { - gus->rcur[d] -= gus->rfreq[d]; - if (gus->rcur[d] <= gus->rstart[d]) - { - int diff = gus->rstart[d] - gus->rcur[d]; - if (!(gus->rctrl[d] & 8)) - { - gus->rctrl[d] |= 1; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; - } - else - { - if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); - } - - if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) - { - gus->rampirqs[d] = 1; - update_irqs = 1; - } - } - } - else - { - gus->rcur[d] += gus->rfreq[d]; - if (gus->rcur[d] >= gus->rend[d]) - { - int diff = gus->rcur[d] - gus->rend[d]; - if (!(gus->rctrl[d] & 8)) - { - gus->rctrl[d] |= 1; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; - } - else - { - if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); - } - - if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) - { - gus->rampirqs[d] = 1; - update_irqs = 1; - } - } - } - } - } - - if (update_irqs) - pollgusirqs(gus); -} - -static void gus_get_buffer(int32_t *buffer, int len, void *p) -{ - gus_t *gus = (gus_t *)p; - int c; - - gus_update(gus); - - for (c = 0; c < len * 2; c++) - { - buffer[c] += (int32_t)gus->buffer[c & 1][c >> 1]; - } - - gus->pos = 0; -} - - -void *gus_init(const device_t *info) -{ - int c; - double out = 1.0; - gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0, sizeof(gus_t)); - - gus->ram = malloc(1 << 20); - memset(gus->ram, 0, 1 << 20); - - for (c=0;c<32;c++) - { - gus->ctrl[c]=1; - gus->rctrl[c]=1; - gus->rfreq[c]=63*512; - } - - for (c=4095;c>=0;c--) { - vol16bit[c]=out; - out/=1.002709201; /* 0.0235 dB Steps */ - } - - gus->voices=14; - - gus->samp_timer = gus->samp_latch = (int64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - - gus->t1l = gus->t2l = 0xff; - - io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); - timer_add(gus_poll_wave, &gus->samp_timer, TIMER_ALWAYS_ENABLED, gus); - timer_add(gus_poll_timer_1, &gus->timer_1, TIMER_ALWAYS_ENABLED, gus); - timer_add(gus_poll_timer_2, &gus->timer_2, TIMER_ALWAYS_ENABLED, gus); - - sound_add_handler(gus_get_buffer, gus); - - return gus; -} - -void gus_close(void *p) -{ - gus_t *gus = (gus_t *)p; - - free(gus->ram); - free(gus); -} - -void gus_speed_changed(void *p) -{ - gus_t *gus = (gus_t *)p; - - if (gus->voices < 14) - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); -} - -const device_t gus_device = -{ - "Gravis UltraSound", - 0, 0, - gus_init, gus_close, NULL, NULL, - gus_speed_changed, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_gus.h b/src - Cópia/sound/snd_gus.h deleted file mode 100644 index 89e8ea331..000000000 --- a/src - Cópia/sound/snd_gus.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t gus_device; diff --git a/src - Cópia/sound/snd_lpt_dac.c b/src - Cópia/sound/snd_lpt_dac.c deleted file mode 100644 index 0e271ea2d..000000000 --- a/src - Cópia/sound/snd_lpt_dac.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../lpt.h" -#include "../timer.h" -#include "sound.h" -#include "filters.h" -#include "snd_lpt_dac.h" - -typedef struct lpt_dac_t -{ - uint8_t dac_val_l, dac_val_r; - - int is_stereo; - int channel; - - int16_t buffer[2][SOUNDBUFLEN]; - int pos; -} lpt_dac_t; - -static void dac_update(lpt_dac_t *lpt_dac) -{ - for (; lpt_dac->pos < sound_pos_global; lpt_dac->pos++) - { - lpt_dac->buffer[0][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_l ^ 0x80) * 0x40; - lpt_dac->buffer[1][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_r ^ 0x80) * 0x40; - } -} - - -static void dac_write_data(uint8_t val, void *p) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - - timer_clock(); - - if (lpt_dac->is_stereo) - { - if (lpt_dac->channel) - lpt_dac->dac_val_r = val; - else - lpt_dac->dac_val_l = val; - } - else - lpt_dac->dac_val_l = lpt_dac->dac_val_r = val; - dac_update(lpt_dac); -} - -static void dac_write_ctrl(uint8_t val, void *p) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - - if (lpt_dac->is_stereo) - lpt_dac->channel = val & 0x01; -} - -static uint8_t dac_read_status(void *p) -{ - return 0; -} - - -static void dac_get_buffer(int32_t *buffer, int len, void *p) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - int c; - - dac_update(lpt_dac); - - for (c = 0; c < len; c++) - { - buffer[c*2] += dac_iir(0, lpt_dac->buffer[0][c]); - buffer[c*2 + 1] += dac_iir(1, lpt_dac->buffer[1][c]); - } - lpt_dac->pos = 0; -} - -static void *dac_init() -{ - lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t)); - memset(lpt_dac, 0, sizeof(lpt_dac_t)); - - sound_add_handler(dac_get_buffer, lpt_dac); - - return lpt_dac; -} -static void *dac_stereo_init() -{ - lpt_dac_t *lpt_dac = dac_init(); - - lpt_dac->is_stereo = 1; - - return lpt_dac; -} -static void dac_close(void *p) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - - free(lpt_dac); -} - -const lpt_device_t lpt_dac_device = -{ - "LPT DAC / Covox Speech Thing", - dac_init, - dac_close, - dac_write_data, - dac_write_ctrl, - dac_read_status -}; -const lpt_device_t lpt_dac_stereo_device = -{ - "Stereo LPT DAC", - dac_stereo_init, - dac_close, - dac_write_data, - dac_write_ctrl, - dac_read_status -}; diff --git a/src - Cópia/sound/snd_lpt_dac.h b/src - Cópia/sound/snd_lpt_dac.h deleted file mode 100644 index d9f505353..000000000 --- a/src - Cópia/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 - Cópia/sound/snd_lpt_dss.c b/src - Cópia/sound/snd_lpt_dss.c deleted file mode 100644 index bacd1e706..000000000 --- a/src - Cópia/sound/snd_lpt_dss.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../lpt.h" -#include "sound.h" -#include "filters.h" -#include "snd_lpt_dss.h" - -typedef struct dss_t -{ - uint8_t fifo[16]; - int read_idx, write_idx; - - uint8_t dac_val; - - int64_t time; - - int16_t buffer[SOUNDBUFLEN]; - int pos; -} dss_t; - -static void dss_update(dss_t *dss) -{ - for (; dss->pos < sound_pos_global; dss->pos++) - dss->buffer[dss->pos] = (int8_t)(dss->dac_val ^ 0x80) * 0x40; -} - - -static void dss_write_data(uint8_t val, void *p) -{ - dss_t *dss = (dss_t *)p; - - timer_clock(); - - if ((dss->write_idx - dss->read_idx) < 16) - { - dss->fifo[dss->write_idx & 15] = val; - dss->write_idx++; - } -} - -static void dss_write_ctrl(uint8_t val, void *p) -{ -} - -static uint8_t dss_read_status(void *p) -{ - dss_t *dss = (dss_t *)p; - - if ((dss->write_idx - dss->read_idx) >= 16) - return 0x40; - return 0; -} - - -static void dss_get_buffer(int32_t *buffer, int len, void *p) -{ - dss_t *dss = (dss_t *)p; - int c; - - dss_update(dss); - - for (c = 0; c < len*2; c += 2) - { - int16_t val = (int16_t)dss_iir((float)dss->buffer[c >> 1]); - - buffer[c] += val; - buffer[c+1] += val; - } - - dss->pos = 0; -} - -static void dss_callback(void *p) -{ - dss_t *dss = (dss_t *)p; - - dss_update(dss); - - if ((dss->write_idx - dss->read_idx) > 0) - { - dss->dac_val = dss->fifo[dss->read_idx & 15]; - dss->read_idx++; - } - - dss->time += (int64_t) (TIMER_USEC * (1000000.0 / 7000.0)); -} - -static void *dss_init() -{ - dss_t *dss = malloc(sizeof(dss_t)); - memset(dss, 0, sizeof(dss_t)); - - sound_add_handler(dss_get_buffer, dss); - timer_add(dss_callback, &dss->time, TIMER_ALWAYS_ENABLED, dss); - - return dss; -} -static void dss_close(void *p) -{ - dss_t *dss = (dss_t *)p; - - free(dss); -} - -const lpt_device_t dss_device = -{ - "Disney Sound Source", - dss_init, - dss_close, - dss_write_data, - dss_write_ctrl, - dss_read_status -}; diff --git a/src - Cópia/sound/snd_lpt_dss.h b/src - Cópia/sound/snd_lpt_dss.h deleted file mode 100644 index 07d37617a..000000000 --- a/src - Cópia/sound/snd_lpt_dss.h +++ /dev/null @@ -1 +0,0 @@ -extern const lpt_device_t dss_device; diff --git a/src - Cópia/sound/snd_mpu401.c b/src - Cópia/sound/snd_mpu401.c deleted file mode 100644 index 4bc619d90..000000000 --- a/src - Cópia/sound/snd_mpu401.c +++ /dev/null @@ -1,984 +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. - * - * Roland MPU-401 emulation. - * - * Version: @(#)snd_mpu401.c 1.0.10 2018/04/29 - * - * Authors: Sarah Walker, - * DOSBox Team, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2008-2018 DOSBox Team. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../pic.h" -#include "../timer.h" -#include "sound.h" -#include "snd_mpu401.h" -#include "midi.h" - - -enum { - STATUS_OUTPUT_NOT_READY = 0x40, - STATUS_INPUT_NOT_READY = 0x80 -}; - - -int mpu401_standalone_enable = 0; - -static int64_t mpu401_event_callback = 0LL; -static int64_t mpu401_eoi_callback = 0LL; -static int64_t mpu401_reset_callback = 0LL; - - -static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); -static void MPU401_EOIHandlerDispatch(void *p); - - -#ifdef ENABLE_MPU401_LOG -int mpu401_do_log = ENABLE_MPU401_LOG; -#endif - - -static void -mpu401_log(const char *fmt, ...) -{ -#ifdef ENABLE_MPU401_LOG - va_list ap; - - if (mpu401_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -QueueByte(mpu_t *mpu, uint8_t data) -{ - if (mpu->state.block_ack) { - mpu->state.block_ack=0; - return; - } - - if (mpu->queue_used == 0 && mpu->intelligent) { - mpu->state.irq_pending=1; - picint(1 << mpu->irq); - } - if (mpu->queue_used < MPU401_QUEUE) { - int pos = mpu->queue_used+mpu->queue_pos; - - if (mpu->queue_pos >= MPU401_QUEUE) - mpu->queue_pos -= MPU401_QUEUE; - - if (pos>=MPU401_QUEUE) - pos-=MPU401_QUEUE; - - mpu->queue_used++; - mpu->queue[pos]=data; - } else - mpu401_log("MPU401:Data queue full\n"); -} - - -static void -ClrQueue(mpu_t *mpu) -{ - mpu->queue_used=0; - mpu->queue_pos=0; -} - - -static void -MPU401_Reset(mpu_t *mpu) -{ - uint8_t i; - - picintc(1 << mpu->irq); - - mpu->mode = (mpu->intelligent ? M_INTELLIGENT : M_UART); - mpu->state.eoi_scheduled = 0; - mpu->state.wsd = 0; - mpu->state.wsm = 0; - mpu->state.conductor = 0; - mpu->state.cond_req = 0; - mpu->state.cond_set = 0; - mpu->state.playing = 0; - mpu->state.run_irq = 0; - mpu->state.irq_pending = 0; - mpu->state.cmask = 0xff; - mpu->state.amask = mpu->state.tmask = 0; - mpu->state.midi_mask = 0xffff; - mpu->state.data_onoff = 0; - mpu->state.command_byte = 0; - mpu->state.block_ack = 0; - mpu->clock.tempo = mpu->clock.old_tempo = 100; - mpu->clock.timebase = mpu->clock.old_timebase = 120; - mpu->clock.tempo_rel = mpu->clock.old_tempo_rel = 40; - mpu->clock.tempo_grad = 0; - mpu->clock.clock_to_host = 0; - mpu->clock.cth_rate = 60; - mpu->clock.cth_counter = 0; - - ClrQueue(mpu); - - mpu->state.req_mask = 0; - mpu->condbuf.counter = 0; - mpu->condbuf.type = T_OVERFLOW; - - for (i=0;i<8;i++) { - mpu->playbuf[i].type = T_OVERFLOW; - mpu->playbuf[i].counter = 0; - } -} - - -static void -MPU401_ResetDone(void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - - mpu401_log("MPU-401 reset callback\n"); - - mpu401_reset_callback = 0LL; - - mpu->state.reset=0; - if (mpu->state.cmd_pending) { - MPU401_WriteCommand(mpu, mpu->state.cmd_pending-1); - mpu->state.cmd_pending=0; - } -} - - -static void -MPU401_WriteCommand(mpu_t *mpu, uint8_t val) -{ - uint8_t i; - - if (mpu->state.reset) { - mpu->state.cmd_pending=val+1; - } - - if (val <= 0x2f) { - switch (val&3) { /* MIDI stop, start, continue */ - case 1: - midi_write(0xfc); - break; - - case 2: - midi_write(0xfa); - break; - - case 3: - midi_write(0xfb); - break; - } - - switch (val & 0xc) { - case 0x4: /* Stop */ - mpu->state.playing = 0; - mpu401_event_callback = 0LL; - - for (i=0xb0; i<0xbf; i++) { - /* All notes off */ - midi_write(i); - midi_write(0x7b); - midi_write(0); - } - break; - - case 0x8: /* Play */ - mpu->state.playing = 1; - mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * 1000LL * TIMER_USEC; - ClrQueue(mpu); - break; - } - } else if (val>=0xa0 && val<=0xa7) { /* Request play counter */ - if (mpu->state.cmask&(1<<(val&7))) QueueByte(mpu, mpu->playbuf[val&7].counter); - } else if (val>=0xd0 && val<=0xd7) { /* Send data */ - mpu->state.old_chan = mpu->state.channel; - mpu->state.channel= val & 7; - mpu->state.wsd = 1; - mpu->state.wsm = 0; - mpu->state.wsd_start = 1; - } else switch (val) { - case 0xdf: /* Send system message */ - mpu->state.wsd = 0; - mpu->state.wsm = 1; - mpu->state.wsd_start = 1; - break; - - case 0x8e: /* Conductor */ - mpu->state.cond_set = 0; - break; - - case 0x8f: - mpu->state.cond_set = 1; - break; - - case 0x94: /* Clock to host */ - mpu->clock.clock_to_host=0; - break; - - case 0x95: - mpu->clock.clock_to_host=1; - break; - - case 0xc2: /* Internal timebase */ - mpu->clock.timebase=48; - break; - - case 0xc3: - mpu->clock.timebase=72; - break; - - case 0xc4: - mpu->clock.timebase=96; - break; - - case 0xc5: - mpu->clock.timebase=120; - break; - - case 0xc6: - mpu->clock.timebase=144; - break; - - case 0xc7: - mpu->clock.timebase=168; - break; - case 0xc8: - mpu->clock.timebase=192; - break; - - /* Commands with data byte */ - case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: - case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: - mpu->state.command_byte=val; - break; - - /* Commands 0xa# returning data */ - case 0xab: /* Request and clear recording counter */ - QueueByte(mpu, MSG_MPU_ACK); - QueueByte(mpu, 0); - return; - - case 0xac: /* Request version */ - QueueByte(mpu, MSG_MPU_ACK); - QueueByte(mpu, MPU401_VERSION); - return; - - case 0xad: /* Request revision */ - QueueByte(mpu, MSG_MPU_ACK); - QueueByte(mpu, MPU401_REVISION); - return; - - case 0xaf: /* Request tempo */ - QueueByte(mpu, MSG_MPU_ACK); - QueueByte(mpu, mpu->clock.tempo); - return; - - case 0xb1: /* Reset relative tempo */ - mpu->clock.tempo_rel=40; - break; - - case 0xb9: /* Clear play map */ - case 0xb8: /* Clear play counters */ - for (i=0xb0;i<0xbf;i++) { - /* All notes off */ - midi_write(i); - midi_write(0x7b); - midi_write(0); - } - for (i=0;i<8;i++) { - mpu->playbuf[i].counter=0; - mpu->playbuf[i].type=T_OVERFLOW; - } - mpu->condbuf.counter=0; - mpu->condbuf.type=T_OVERFLOW; - if (!(mpu->state.conductor=mpu->state.cond_set)) - mpu->state.cond_req=0; - mpu->state.amask=mpu->state.tmask; - mpu->state.req_mask=0; - mpu->state.irq_pending=1; - break; - - case 0xff: /* Reset MPU-401 */ - mpu401_log("MPU-401:Reset %X\n",val); - mpu401_reset_callback = MPU401_RESETBUSY * 33LL * TIMER_USEC; - mpu->state.reset=1; - MPU401_Reset(mpu); -#if 0 - if (mpu->mode==M_UART) return;//do not send ack in UART mode -#endif - break; - - case 0x3f: /* UART mode */ - mpu401_log("MPU-401:Set UART mode %X\n",val); - mpu->mode=M_UART; - break; - - default:; - //mpu401_log("MPU-401:Unhandled command %X",val); - } - - QueueByte(mpu, MSG_MPU_ACK); -} - - -static void -MPU401_WriteData(mpu_t *mpu, uint8_t val) -{ - if (mpu->mode==M_UART) {midi_write(val); return;} - - switch (mpu->state.command_byte) { /* 0xe# command data */ - case 0x00: - break; - - case 0xe0: /* Set tempo */ - mpu->state.command_byte=0; - mpu->clock.tempo=val; - return; - - case 0xe1: /* Set relative tempo */ - mpu->state.command_byte=0; - if (val!=0x40) //default value - mpu401_log("MPU-401:Relative tempo change not implemented\n"); - return; - - case 0xe7: /* Set internal clock to host interval */ - mpu->state.command_byte=0; - mpu->clock.cth_rate=val>>2; - return; - - case 0xec: /* Set active track mask */ - mpu->state.command_byte=0; - mpu->state.tmask=val; - return; - - case 0xed: /* Set play counter mask */ - mpu->state.command_byte=0; - mpu->state.cmask=val; - return; - - case 0xee: /* Set 1-8 MIDI channel mask */ - mpu->state.command_byte=0; - mpu->state.midi_mask&=0xff00; - mpu->state.midi_mask|=val; - return; - - case 0xef: /* Set 9-16 MIDI channel mask */ - mpu->state.command_byte=0; - mpu->state.midi_mask&=0x00ff; - mpu->state.midi_mask|=((uint16_t)val)<<8; - return; - - //case 0xe2: /* Set graduation for relative tempo */ - //case 0xe4: /* Set metronome */ - //case 0xe6: /* Set metronome measure length */ - default: - mpu->state.command_byte=0; - return; - } - - static int length,cnt,posd; - - if (mpu->state.wsd) { - /* Directly send MIDI message */ - if (mpu->state.wsd_start) { - mpu->state.wsd_start=0; - cnt=0; - switch (val&0xf0) { - case 0xc0:case 0xd0: - mpu->playbuf[mpu->state.channel].value[0]=val; - length=2; - break; - - case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0: - mpu->playbuf[mpu->state.channel].value[0]=val; - length=3; - break; - - case 0xf0: - //mpu401_log("MPU-401:Illegal WSD byte\n"); - mpu->state.wsd=0; - mpu->state.channel=mpu->state.old_chan; - return; - - default: /* MIDI with running status */ - cnt++; - midi_write(mpu->playbuf[mpu->state.channel].value[0]); - } - } - - if (cntstate.wsd=0; - mpu->state.channel=mpu->state.old_chan; - } - - return; - } - - if (mpu->state.wsm) { /* Directly send system message */ - if (val==MSG_EOX) {midi_write(MSG_EOX);mpu->state.wsm=0;return;} - if (mpu->state.wsd_start) { - mpu->state.wsd_start=0; - cnt=0; - switch (val) { - case 0xf2: - length=3; - break; - - case 0xf3: - length=2; - break; - - case 0xf6: - length=1; - break; - - case 0xf0: - length=0; - break; - - default: - length=0; - } - } - - if (!length || cntstate.wsm=0; - - return; - } - - if (mpu->state.cond_req) { - /* Command */ - switch (mpu->state.data_onoff) { - case -1: - return; - - case 0: /* Timing byte */ - mpu->condbuf.vlength=0; - if (val<0xf0) mpu->state.data_onoff++; - else { - mpu->state.data_onoff=-1; - MPU401_EOIHandlerDispatch(mpu); - return; - } - - if (val==0) mpu->state.send_now=1; - else mpu->state.send_now=0; - mpu->condbuf.counter=val; - break; - - case 1: /* Command byte #1 */ - mpu->condbuf.type=T_COMMAND; - if (val==0xf8 || val==0xf9) - mpu->condbuf.type=T_OVERFLOW; - mpu->condbuf.value[mpu->condbuf.vlength]=val; - mpu->condbuf.vlength++; - if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch(mpu); - else mpu->state.data_onoff++; - break; - - case 2:/* Command byte #2 */ - mpu->condbuf.value[mpu->condbuf.vlength]=val; - mpu->condbuf.vlength++; - MPU401_EOIHandlerDispatch(mpu); - break; - } - return; - } - - switch (mpu->state.data_onoff) { - /* Data */ - case -1: - return; - - case 0: /* Timing byte */ - if (val<0xf0) mpu->state.data_onoff=1; - else { - mpu->state.data_onoff=-1; - MPU401_EOIHandlerDispatch(mpu); - return; - } - if (val==0) mpu->state.send_now=1; - else mpu->state.send_now=0; - mpu->playbuf[mpu->state.channel].counter=val; - break; - - case 1: /* MIDI */ - mpu->playbuf[mpu->state.channel].vlength++; - posd=mpu->playbuf[mpu->state.channel].vlength; - if (posd==1) switch (val&0xf0) { - case 0xf0: /* System message or mark */ - if (val>0xf7) { - mpu->playbuf[mpu->state.channel].type=T_MARK; - mpu->playbuf[mpu->state.channel].sys_val=val; - length=1; - } else { - //LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); - mpu->playbuf[mpu->state.channel].type=T_MIDI_SYS; - mpu->playbuf[mpu->state.channel].sys_val=val; - length=1; - } - break; - - case 0xc0: case 0xd0: /* MIDI Message */ - mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; - length=mpu->playbuf[mpu->state.channel].length=2; - break; - - case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: - mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; - length=mpu->playbuf[mpu->state.channel].length=3; - break; - - default: /* MIDI data with running status */ - posd++; - mpu->playbuf[mpu->state.channel].vlength++; - mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; - length=mpu->playbuf[mpu->state.channel].length; - break; - } - - if (!(posd==1 && val>=0xf0)) - mpu->playbuf[mpu->state.channel].value[posd-1]=val; - if (posd==length) MPU401_EOIHandlerDispatch(mpu); - } -} - - -static void -MPU401_IntelligentOut(mpu_t *mpu, uint8_t chan) -{ - uint8_t val; - uint8_t i; - - switch (mpu->playbuf[chan].type) { - case T_OVERFLOW: - break; - - case T_MARK: - val=mpu->playbuf[chan].sys_val; - if (val==0xfc) { - midi_write(val); - mpu->state.amask&=~(1<state.req_mask&=~(1<playbuf[chan].vlength;i++) - midi_write(mpu->playbuf[chan].value[i]); - break; - - default: - break; - } -} - - -static void -UpdateTrack(mpu_t *mpu, uint8_t chan) -{ - MPU401_IntelligentOut(mpu, chan); - - if (mpu->state.amask&(1<playbuf[chan].vlength=0; - mpu->playbuf[chan].type=T_OVERFLOW; - mpu->playbuf[chan].counter=0xf0; - mpu->state.req_mask|=(1<state.amask==0 && !mpu->state.conductor) - mpu->state.req_mask|=(1<<12); - } -} - - -static void -UpdateConductor(mpu_t *mpu) -{ - if (mpu->condbuf.value[0]==0xfc) { - mpu->condbuf.value[0]=0; - mpu->state.conductor=0; - mpu->state.req_mask&=~(1<<9); - if (mpu->state.amask==0) - mpu->state.req_mask|=(1<<12); - return; - } - - mpu->condbuf.vlength=0; - mpu->condbuf.counter=0xf0; - mpu->state.req_mask|=(1<<9); -} - - -//Updates counters and requests new data on "End of Input" -static void -MPU401_EOIHandler(void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - uint8_t i; - - mpu401_log("MPU-401 end of input callback\n"); - - mpu401_eoi_callback = 0LL; - mpu->state.eoi_scheduled=0; - if (mpu->state.send_now) { - mpu->state.send_now=0; - if (mpu->state.cond_req) UpdateConductor(mpu); - else UpdateTrack(mpu, mpu->state.channel); - } - - mpu->state.irq_pending=0; - - if (!mpu->state.playing || !mpu->state.req_mask) return; - - i=0; - do { - if (mpu->state.req_mask&(1<state.req_mask&=~(1<state.send_now) { - mpu->state.eoi_scheduled=1; - mpu401_eoi_callback = 60LL * TIMER_USEC; /* Possible a bit longer */ - } else if (!mpu->state.eoi_scheduled) - MPU401_EOIHandler(mpu); -} - - -static void -imf_write(uint16_t addr, uint8_t val, void *priv) -{ - mpu401_log("IMF:Wr %4X,%X\n", addr, val); -} - - -uint8_t -MPU401_ReadData(mpu_t *mpu) -{ - uint8_t ret; - - ret = MSG_MPU_ACK; - if (mpu->queue_used) { - if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; - ret=mpu->queue[mpu->queue_pos]; - mpu->queue_pos++;mpu->queue_used--; - } - - if (!mpu->intelligent) return ret; - - if (mpu->queue_used == 0) picintc(1 << mpu->irq); - - if (ret>=0xf0 && ret<=0xf7) { - /* MIDI data request */ - mpu->state.channel=ret&7; - mpu->state.data_onoff=0; - mpu->state.cond_req=0; - } - - if (ret==MSG_MPU_COMMAND_REQ) { - mpu->state.data_onoff=0; - mpu->state.cond_req=1; - if (mpu->condbuf.type!=T_OVERFLOW) { - mpu->state.block_ack=1; - MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); - if (mpu->state.command_byte) - MPU401_WriteData(mpu, mpu->condbuf.value[1]); - } - mpu->condbuf.type=T_OVERFLOW; - } - - if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { - mpu->state.data_onoff=-1; - MPU401_EOIHandlerDispatch(mpu); - } - - return(ret); -} - - -static void -mpu401_write(uint16_t addr, uint8_t val, void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - - /* mpu401_log("MPU401 Write Port %04X, val %x\n", addr, val); */ - switch (addr & 1) { - case 0: /*Data*/ - MPU401_WriteData(mpu, val); - mpu401_log("Write Data (0x330) %X\n", val); - break; - - case 1: /*Command*/ - MPU401_WriteCommand(mpu, val); - mpu401_log("Write Command (0x331) %x\n", val); - break; - } -} - - -static uint8_t -mpu401_read(uint16_t addr, void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - uint8_t ret = 0; - - switch (addr & 1) { - case 0: //Read Data - ret = MPU401_ReadData(mpu); - mpu401_log("Read Data (0x330) %X\n", ret); - break; - - case 1: //Read Status - if (mpu->state.cmd_pending) ret=STATUS_OUTPUT_NOT_READY; - if (!mpu->queue_used) ret=STATUS_INPUT_NOT_READY; - ret |= 0x3f; //FIXME: check with MPU401 TechRef - - mpu401_log("Read Status (0x331) %x\n", ret); - break; - } - - /* mpu401_log("MPU401 Read Port %04X, ret %x\n", addr, ret); */ - return(ret); -} - - -static void -MPU401_Event(void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - int new_time; - uint8_t i; - - mpu401_log("MPU-401 event callback\n"); - - if (mpu->mode==M_UART) { - mpu401_event_callback = 0LL; - return; - } - - if (mpu->state.irq_pending) goto next_event; - - for (i=0;i<8;i++) { /* Decrease counters */ - if (mpu->state.amask&(1<playbuf[i].counter--; - if (mpu->playbuf[i].counter<=0) UpdateTrack(mpu, i); - } - } - - if (mpu->state.conductor) { - mpu->condbuf.counter--; - if (mpu->condbuf.counter<=0) UpdateConductor(mpu); - } - - if (mpu->clock.clock_to_host) { - mpu->clock.cth_counter++; - if (mpu->clock.cth_counter >= mpu->clock.cth_rate) { - mpu->clock.cth_counter=0; - mpu->state.req_mask|=(1<<13); - } - } - - if (!mpu->state.irq_pending && mpu->state.req_mask) - MPU401_EOIHandler(mpu); - -next_event: - /* mpu401_event_callback = 0LL; */ - new_time = (mpu->clock.tempo * mpu->clock.timebase); - if (new_time == 0) { - mpu401_event_callback = 0LL; - return; - } else { - mpu401_event_callback += (MPU401_TIMECONSTANT/new_time) * 1000LL * TIMER_USEC; - mpu401_log("Next event after %i us (time constant: %i)\n", (int) ((MPU401_TIMECONSTANT/new_time) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); - } -} - - -void -mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) -{ -#if 0 - if (mode != M_INTELLIGENT) { - mpu401_uart_init(mpu, addr); - return; - } -#endif - - mpu->status = STATUS_INPUT_NOT_READY; - mpu->irq = irq; - mpu->queue_used = 0; - mpu->queue_pos = 0; - mpu->mode = M_UART; - - 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"); - - mpu401_event_callback = 0LL; - mpu401_eoi_callback = 0LL; - mpu401_reset_callback = 0LL; - - io_sethandler(addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); - io_sethandler(0x2A20, 16, - NULL, NULL, NULL, imf_write, NULL, NULL, mpu); - timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); - timer_add(MPU401_EOIHandler, &mpu401_eoi_callback, &mpu401_eoi_callback, mpu); - timer_add(MPU401_ResetDone, &mpu401_reset_callback, &mpu401_reset_callback, mpu); - - MPU401_Reset(mpu); -} - - -void -mpu401_device_add(void) -{ - char *n; - - if (!mpu401_standalone_enable) return; - - n = sound_card_get_internal_name(sound_card_current); - if (n != NULL) { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) return; - } - - device_add(&mpu401_device); -} - - -static void * -mpu401_standalone_init(const device_t *info) -{ - mpu_t *mpu; - - mpu = malloc(sizeof(mpu_t)); - memset(mpu, 0, sizeof(mpu_t)); - - mpu401_log("mpu_init\n"); - mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode")); - - return(mpu); -} - - -static void -mpu401_standalone_close(void *priv) -{ - mpu_t *mpu = (mpu_t *)priv; - - free(mpu); -} - - -static const device_config_t mpu401_standalone_config[] = -{ - { - "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, - { - { - "0x300", 0x300 - }, - { - "0x330", 0x330 - }, - { - "" - } - } - }, - { - "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "mode", "Mode", CONFIG_SELECTION, "", 1, - { - { - "UART", M_UART - }, - { - "Intelligent", M_INTELLIGENT - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mpu401_device = { - "MPU-401 (Standalone)", - 0, 0, - mpu401_standalone_init, mpu401_standalone_close, NULL, - NULL, - NULL, - NULL, - mpu401_standalone_config -}; diff --git a/src - Cópia/sound/snd_mpu401.h b/src - Cópia/sound/snd_mpu401.h deleted file mode 100644 index 0dda1b25a..000000000 --- a/src - Cópia/sound/snd_mpu401.h +++ /dev/null @@ -1,94 +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. - * - * Roland MPU-401 emulation. - * - * Version: @(#)sound_mpu401.h 1.0.1 2018/03/18 - * - * Author: Sarah Walker, - * DOSBox Team, - * Miran Grca, - * TheCollector1995, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2008-2018 DOSBox Team. - * Copyright 2016-2018 Miran Grca. - * Copyright 2016-2018 TheCollector1995. - */ - -#define MPU401_VERSION 0x15 -#define MPU401_REVISION 0x01 -#define MPU401_QUEUE 32 -#define MPU401_TIMECONSTANT (60000000/1000.0f) -#define MPU401_RESETBUSY 27.0f - -typedef enum MpuMode { M_UART,M_INTELLIGENT } MpuMode; -typedef enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND} MpuDataType; - -/* Messages sent to MPU-401 from host */ -#define MSG_EOX 0xf7 -#define MSG_OVERFLOW 0xf8 -#define MSG_MARK 0xfc - -/* Messages sent to host from MPU-401 */ -#define MSG_MPU_OVERFLOW 0xf8 -#define MSG_MPU_COMMAND_REQ 0xf9 -#define MSG_MPU_END 0xfc -#define MSG_MPU_CLOCK 0xfd -#define MSG_MPU_ACK 0xfe - -typedef struct mpu_t -{ - int uart_mode; - uint8_t rx_data; - int intelligent; - MpuMode mode; - int irq; - uint8_t status; - uint8_t queue[MPU401_QUEUE]; - int queue_pos,queue_used; - struct track - { - int counter; - uint8_t value[8],sys_val; - uint8_t vlength,length; - MpuDataType type; - } playbuf[8],condbuf; - struct { - int conductor,cond_req,cond_set, block_ack; - int playing,reset; - int wsd,wsm,wsd_start; - int run_irq,irq_pending; - int send_now; - int eoi_scheduled; - int data_onoff; - uint32_t command_byte,cmd_pending; - uint8_t tmask,cmask,amask; - uint16_t midi_mask; - uint16_t req_mask; - uint8_t channel,old_chan; - } state; - struct { - uint8_t timebase,old_timebase; - uint8_t tempo,old_tempo; - uint8_t tempo_rel,old_tempo_rel; - uint8_t tempo_grad; - uint8_t cth_rate,cth_counter; - int clock_to_host,cth_active; - } clock; -} mpu_t; - -uint8_t MPU401_ReadData(mpu_t *mpu); - -void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); - -extern int mpu401_standalone_enable; - -void mpu401_device_add(void); -const device_t mpu401_device; - -void mpu401_uart_init(mpu_t *mpu, uint16_t addr); diff --git a/src - Cópia/sound/snd_opl.c b/src - Cópia/sound/snd_opl.c deleted file mode 100644 index 3daea480b..000000000 --- a/src - Cópia/sound/snd_opl.c +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "sound.h" -#include "snd_opl.h" -#include "snd_dbopl.h" - - -/*Interfaces between 86Box and the actual OPL emulator*/ - - -uint8_t opl2_read(uint16_t a, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(0, a); -} -void opl2_write(uint16_t a, uint8_t v, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - opl2_update2(opl); - opl_write(0, a, v); - opl_write(1, a, v); -} - -uint8_t opl2_l_read(uint16_t a, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(0, a); -} -void opl2_l_write(uint16_t a, uint8_t v, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - opl2_update2(opl); - opl_write(0, a, v); -} - -uint8_t opl2_r_read(uint16_t a, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(1, a); -} -void opl2_r_write(uint16_t a, uint8_t v, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - opl2_update2(opl); - opl_write(1, a, v); -} - -uint8_t opl3_read(uint16_t a, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - cycles -= (int)(isa_timing * 8); - opl3_update2(opl); - return opl_read(0, a); -} -void opl3_write(uint16_t a, uint8_t v, void *priv) -{ - opl_t *opl = (opl_t *)priv; - - opl3_update2(opl); - opl_write(0, a, v); -} - - -void opl2_update2(opl_t *opl) -{ - if (opl->pos < sound_pos_global) - { - opl2_update(0, &opl->buffer[opl->pos*2], sound_pos_global - opl->pos); - opl2_update(1, &opl->buffer[opl->pos*2 + 1], sound_pos_global - opl->pos); - for (; opl->pos < sound_pos_global; opl->pos++) - { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); - } - } -} - -void opl3_update2(opl_t *opl) -{ - if (opl->pos < sound_pos_global) - { - opl3_update(0, &opl->buffer[opl->pos*2], sound_pos_global - opl->pos); - for (; opl->pos < sound_pos_global; opl->pos++) - { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); - } - } -} - -void ym3812_timer_set_0(void *param, int timer, int64_t period) -{ - opl_t *opl = (opl_t *)param; - - opl->timers[0][timer] = period * TIMER_USEC * 20LL; - if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; - opl->timers_enable[0][timer] = period ? 1 : 0; -} -void ym3812_timer_set_1(void *param, int timer, int64_t period) -{ - opl_t *opl = (opl_t *)param; - - opl->timers[1][timer] = period * TIMER_USEC * 20LL; - if (!opl->timers[1][timer]) opl->timers[1][timer] = 1; - opl->timers_enable[1][timer] = period ? 1 : 0; -} - -void ymf262_timer_set(void *param, int timer, int64_t period) -{ - opl_t *opl = (opl_t *)param; - - opl->timers[0][timer] = period * TIMER_USEC * 20LL; - if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; - opl->timers_enable[0][timer] = period ? 1 : 0; -} - -static void opl_timer_callback00(void *p) -{ - opl_t *opl = (opl_t *)p; - - opl->timers_enable[0][0] = 0; - opl_timer_over(0, 0); -} -static void opl_timer_callback01(void *p) -{ - opl_t *opl = (opl_t *)p; - - opl->timers_enable[0][1] = 0; - opl_timer_over(0, 1); -} -static void opl_timer_callback10(void *p) -{ - opl_t *opl = (opl_t *)p; - - opl->timers_enable[1][0] = 0; - opl_timer_over(1, 0); -} -static void opl_timer_callback11(void *p) -{ - opl_t *opl = (opl_t *)p; - - opl->timers_enable[1][1] = 0; - opl_timer_over(1, 1); -} - -void opl2_init(opl_t *opl) -{ - opl_init(ym3812_timer_set_0, opl, 0, 0); - opl_init(ym3812_timer_set_1, opl, 1, 0); - timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); - timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); - timer_add(opl_timer_callback10, &opl->timers[1][0], &opl->timers_enable[1][0], (void *)opl); - timer_add(opl_timer_callback11, &opl->timers[1][1], &opl->timers_enable[1][1], (void *)opl); -} - -void opl3_init(opl_t *opl) -{ - opl_init(ymf262_timer_set, opl, 0, 1); - timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); - timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); -} - diff --git a/src - Cópia/sound/snd_opl.h b/src - Cópia/sound/snd_opl.h deleted file mode 100644 index e99f716f9..000000000 --- a/src - Cópia/sound/snd_opl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct opl_t -{ - int chip_nr[2]; - - int64_t timers[2][2]; - int64_t timers_enable[2][2]; - - int16_t filtbuf[2]; - - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; -} opl_t; - -uint8_t opl2_read(uint16_t a, void *priv); -void opl2_write(uint16_t a, uint8_t v, void *priv); -uint8_t opl2_l_read(uint16_t a, void *priv); -void opl2_l_write(uint16_t a, uint8_t v, void *priv); -uint8_t opl2_r_read(uint16_t a, void *priv); -void opl2_r_write(uint16_t a, uint8_t v, void *priv); -uint8_t opl3_read(uint16_t a, void *priv); -void opl3_write(uint16_t a, uint8_t v, void *priv); - -void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); -void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); - -void opl2_init(opl_t *opl); -void opl3_init(opl_t *opl); - -void opl2_update2(opl_t *opl); -void opl3_update2(opl_t *opl); diff --git a/src - Cópia/sound/snd_pas16.c b/src - Cópia/sound/snd_pas16.c deleted file mode 100644 index e93bdfcb6..000000000 --- a/src - Cópia/sound/snd_pas16.c +++ /dev/null @@ -1,780 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pic.h" -#include "../pit.h" -#include "../dma.h" -#include "../timer.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 - 2 x OPL2 - PIT - sample rate/count - LMC835N/LMC1982 - mixer - YM3802 - MIDI Control System - - - 9A01 - IO base - base >> 2 - - All below + IO base - - B89 - interrupt status / clear - bit 2 - sample rate - bit 3 - PCM - bit 4 - MIDI - - B88 - Audio mixer control register - - B8A - Audio filter control - bit 5 - mute? - - B8B - interrupt mask / board ID - bits 5-7 - board ID (read only on PAS16) - - F88 - PCM data (low) - - F89 - PCM data (high) - - F8A - PCM control? - bit 4 - input/output select (1 = output) - bit 5 - mono/stereo select - bit 6 - PCM enable - - 1388-138b - PIT clocked at 1193180 Hz - 1388 - sample rate - 1389 - sample count - - 178b - - 2789 - board revision - - 8389 - - bit 2 - 8/16 bit - - BF88 - wait states - - EF8B - - bit 3 - 16 bits okay ? - - F388 - - bit 6 - joystick enable - - F389 - - bits 0-2 - DMA - - F38A - - bits 0-3 - IRQ - - F788 - - bit 1 - SB emulation - bit 0 - MPU401 emulation - - F789 - SB base addr - bits 0-3 - addr bits 4-7 - - FB8A - SB IRQ/DMA - bits 3-5 - IRQ - bits 6-7 - DMA - - FF88 - board model - 3 = PAS16 -*/ - -typedef struct pas16_t -{ - uint16_t base; - - int irq, dma; - - uint8_t audiofilt; - - uint8_t audio_mixer; - - uint8_t compat, compat_base; - - uint8_t enhancedscsi; - - uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; - - uint8_t irq_stat, irq_ena; - - uint8_t pcm_ctrl; - uint16_t pcm_dat; - - uint16_t pcm_dat_l, pcm_dat_r; - - uint8_t sb_irqdma; - - int stereo_lr; - - uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; - - struct - { - uint32_t l[3]; - int64_t c[3]; - uint8_t m[3]; - uint8_t ctrl, ctrls[2]; - int wp, rm[3], wm[3]; - uint16_t rl[3]; - int thit[3]; - int delay[3]; - int rereadlatch[3]; - int64_t enable[3]; - } pit; - - opl_t opl; - sb_dsp_t dsp; - - int16_t pcm_buffer[2][SOUNDBUFLEN]; - - int pos; -} pas16_t; - -static uint8_t pas16_pit_in(uint16_t port, void *priv); -static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); -static void pas16_update(pas16_t *pas16); - -static int pas16_dmas[8] = {4, 1, 2, 3, 0, 5, 6, 7}; -static int pas16_irqs[16] = {0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0}; -static int pas16_sb_irqs[8] = {0, 2, 3, 5, 7, 10, 11, 12}; -static int pas16_sb_dmas[8] = {0, 1, 2, 3}; - -enum -{ - PAS16_INT_SAMP = 0x04, - PAS16_INT_PCM = 0x08 -}; - -enum -{ - PAS16_PCM_MONO = 0x20, - PAS16_PCM_ENA = 0x40 -}; - -enum -{ - PAS16_SC2_16BIT = 0x04, - PAS16_SC2_MSBINV = 0x10 -}; - -enum -{ - PAS16_FILT_MUTE = 0x20 -}; - - -#ifdef ENABLE_PAS16_LOG -int pas16_do_log = ENABLE_PAS16_LOG; -#endif - - -static void -pas16_log(const char *fmt, ...) -{ -#ifdef ENABLE_PAS16_LOG - va_list ap; - - if (pas16_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static uint8_t pas16_in(uint16_t port, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - uint8_t temp; -/* if (CS == 0xCA53 && pc == 0x3AFC) - fatal("here");*/ - switch ((port - pas16->base) + 0x388) - { - case 0x388: case 0x389: case 0x38a: case 0x38b: - temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl); - break; - - case 0xb88: - temp = pas16->audio_mixer; - break; - - case 0xb89: - temp = pas16->irq_stat; - break; - - case 0xb8a: - temp = pas16->audiofilt; - break; - - case 0xb8b: - temp = (pas16->irq_ena & ~0xe0) | 0x20; - break; - - case 0xf8a: - temp = pas16->pcm_ctrl; - break; - - case 0x1388: case 0x1389: case 0x138a: case 0x138b: - temp = pas16_pit_in(port, pas16); - break; - - case 0x2789: /*Board revision*/ - temp = 0; - break; - - case 0x7f89: - temp = pas16->enhancedscsi & ~1; - break; - - case 0x8388: - temp = pas16->sys_conf_1; - break; - case 0x8389: - temp = pas16->sys_conf_2; - break; - case 0x838b: - temp = pas16->sys_conf_3; - break; - case 0x838c: - temp = pas16->sys_conf_4; - break; - - case 0xef8b: - temp = 0x0c; - break; - - case 0xf388: - temp = pas16->io_conf_1; - break; - case 0xf389: - temp = pas16->io_conf_2; - break; - case 0xf38b: - temp = pas16->io_conf_3; - break; - case 0xf38c: - temp = pas16->io_conf_4; - break; - - case 0xf788: - temp = pas16->compat; - break; - case 0xf789: - temp = pas16->compat_base; - break; - - case 0xfb8a: - temp = pas16->sb_irqdma; - break; - - case 0xff88: /*Board model*/ - temp = 4; /*PAS16*/ - break; - case 0xff8b: /*Master mode read*/ - temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ - break; - - default: - temp = 0xff; - break; - } -/* if (port != 0x388 && port != 0x389 && port != 0xb8b) */pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS,cpu_state.pc); -/* if (CS == 0x1FF4 && pc == 0x0585) - { - if (output) - fatal("here"); - output = 3; - }*/ - return temp; -} - -static void pas16_out(uint16_t port, uint8_t val, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; -/* if (port != 0x388 && port != 0x389) */pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); -/* if (CS == 0x369 && pc == 0x2AC5) - fatal("here\n");*/ - switch ((port - pas16->base) + 0x388) - { - case 0x388: case 0x389: case 0x38a: case 0x38b: - opl3_write((port - pas16->base) + 0x388, val, &pas16->opl); - break; - - case 0xb88: - pas16->audio_mixer = val; - break; - - case 0xb89: - pas16->irq_stat &= ~val; - break; - - case 0xb8a: - pas16_update(pas16); - pas16->audiofilt = val; - break; - - case 0xb8b: - pas16->irq_ena = val; - break; - - case 0xf88: - pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; - break; - case 0xf89: - pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); - break; - case 0xf8a: - if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ - pas16->stereo_lr = 0; - pas16->pcm_ctrl = val; - break; - - case 0x1388: case 0x1389: case 0x138a: case 0x138b: - pas16_pit_out(port, val, pas16); - break; - - case 0x7f89: - pas16->enhancedscsi = val; - break; - - case 0x8388: - pas16->sys_conf_1 = val; - break; - case 0x8389: - pas16->sys_conf_2 = val; - break; - case 0x838a: - pas16->sys_conf_3 = val; - break; - case 0x838b: - pas16->sys_conf_4 = val; - break; - - case 0xf388: - pas16->io_conf_1 = val; - break; - case 0xf389: - pas16->io_conf_2 = val; - pas16->dma = pas16_dmas[val & 0x7]; - pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); - break; - case 0xf38a: - pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pas16_log("pas16_out : set PAS IRQ %i\n", pas16->irq); - break; - case 0xf38b: - pas16->io_conf_4 = val; - break; - - case 0xf788: - pas16->compat = val; - if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); - else - sb_dsp_setaddr(&pas16->dsp, 0); - break; - case 0xf789: - pas16->compat_base = val; - if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); - break; - - case 0xfb8a: - pas16->sb_irqdma = val; - sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); - sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); - break; - - default: - pas16_log("pas16_out : unknown %04X\n", port); - } - if (cpu_state.pc == 0x80048CF3) - { - if (output) - fatal("here\n"); - output = 3; - } -/* if (CS == 0x1FF4 && pc == 0x0431) - output = 3;*/ -} - -static void pas16_pit_out(uint16_t port, uint8_t val, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - int t; - switch (port & 3) - { - case 3: /*CTRL*/ - if ((val & 0xC0) == 0xC0) - { - if (!(val & 0x20)) - { - if (val & 2) pas16->pit.rl[0] = pas16->pit.c[0] / (PITCONST * (1 << TIMER_SHIFT)); - if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1]; - if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2]; - } - return; - } - t = val >> 6; - pas16->pit.ctrls[t] = pas16->pit.ctrl = val; - if (t == 3) - { - pas16_log("PAS16: bad PIT reg select\n"); - return; - } - if (!(pas16->pit.ctrl & 0x30)) - { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (!t) - pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); - if (pas16->pit.c[t] < 0) - pas16->pit.rl[t] = 0; - pas16->pit.ctrl |= 0x30; - pas16->pit.rereadlatch[t] = 0; - pas16->pit.rm[t] = 3; - } - else - { - pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; - pas16->pit.m[t] = (val >> 1) & 7; - if (pas16->pit.m[t] > 5) - pas16->pit.m[t] &= 3; - if (!pas16->pit.rm[t]) - { - pas16->pit.rm[t] = 3; - pas16->pit.rl[t] = pit.c[t]; - if (!t) - pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); - } - pas16->pit.rereadlatch[t] = 1; - } - pas16->pit.wp = 0; - pas16->pit.thit[t] = 0; - break; - case 0: case 1: case 2: /*Timers*/ - t = port & 3; - switch (pas16->pit.wm[t]) - { - case 1: - pas16->pit.l[t] = val; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); - pas16->pit.enable[t] = 1; - break; - case 2: - pas16->pit.l[t] = val << 8; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); - pas16->pit.enable[t] = 1; - break; - case 0: - pas16->pit.l[t] &= 0xFF; - pas16->pit.l[t] |= (val << 8); - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); - pas16->pit.thit[t] = 0; - pas16->pit.wm[t] = 3; - pas16->pit.enable[t] = 1; - break; - case 3: - pas16->pit.l[t] &= 0xFF00; - pas16->pit.l[t] |= val; - pas16->pit.wm[t] = 0; - break; - } - if (!pas16->pit.l[t]) - { - pas16->pit.l[t] |= 0x10000; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); - } - break; - } -} - -static uint8_t pas16_pit_in(uint16_t port, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - uint8_t temp = 0xff; - int t = port & 3; - switch (port & 3) - { - case 0: case 1: case 2: /*Timers*/ - if (pas16->pit.rereadlatch[t]) - { - pas16->pit.rereadlatch[t] = 0; - if (!t) - { - pas16->pit.rl[t] = pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT)); - if ((pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT))) > 65536) - pas16->pit.rl[t] = 0xFFFF; - } - else - { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] > 65536) - pas16->pit.rl[t] = 0xFFFF; - } - } - switch (pas16->pit.rm[t]) - { - case 0: - temp = pas16->pit.rl[t] >> 8; - pas16->pit.rm[t] = 3; - pas16->pit.rereadlatch[t] = 1; - break; - case 1: - temp = (pas16->pit.rl[t]) & 0xFF; - pas16->pit.rereadlatch[t] = 1; - break; - case 2: - temp = (pas16->pit.rl[t]) >> 8; - pas16->pit.rereadlatch[t] = 1; - break; - case 3: - temp = (pas16->pit.rl[t]) & 0xFF; - if (pas16->pit.m[t] & 0x80) pas16->pit.m[t] &= 7; - else pas16->pit.rm[t] = 0; - break; - } - break; - case 3: /*Control*/ - temp = pas16->pit.ctrl; - break; - } - return temp; -} - -static uint8_t pas16_readdma(pas16_t *pas16) -{ - return dma_channel_read(pas16->dma); -} - -static void pas16_pcm_poll(void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - - pas16_update(pas16); - if (pas16->pit.m[0] & 2) - { - if (pas16->pit.l[0]) - pas16->pit.c[0] += (pas16->pit.l[0] * PITCONST * (1 << TIMER_SHIFT)); - else - pas16->pit.c[0] += (0x10000 * PITCONST * (1 << TIMER_SHIFT)); - } - else - { - pas16->pit.c[0] = -1; - pas16->pit.enable[0] = 0; - } - - pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) - picint(1 << pas16->irq); - - /*Update sample rate counter*/ - if (pas16->pit.enable[1]) - { - if (pas16->pcm_ctrl & PAS16_PCM_ENA) - { - uint16_t temp; - - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - { - temp = pas16_readdma(pas16) << 8; - temp |= pas16_readdma(pas16); - } - else - temp = (pas16_readdma(pas16) ^ 0x80) << 8; - - if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) - temp ^= 0x8000; - if (pas16->pcm_ctrl & PAS16_PCM_MONO) - pas16->pcm_dat_l = pas16->pcm_dat_r = temp; - else - { - if (pas16->stereo_lr) - pas16->pcm_dat_r = temp; - else - pas16->pcm_dat_l = temp; - - pas16->stereo_lr = !pas16->stereo_lr; - } - } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pas16->pit.c[1] -= 2; - else - pas16->pit.c[1]--; - if (pas16->pit.c[1] == 0) - { - if (pas16->pit.m[1] & 2) - { - if (pas16->pit.l[1]) - pas16->pit.c[1] += pas16->pit.l[1]; - else - pas16->pit.c[1] += 0x10000; - } - else - { - pas16->pit.c[1] = -1; - pas16->pit.enable[1] = 0; - } - - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) - { - pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); - picint(1 << pas16->irq); - } - } - } -} - -static void pas16_out_base(uint16_t port, uint8_t val, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - - io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - - pas16->base = val << 2; - pas16_log("pas16_write_base : PAS16 base now at %04X\n", pas16->base); - - io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); -} - - -static void pas16_update(pas16_t *pas16) -{ - if (!(pas16->audiofilt & PAS16_FILT_MUTE)) - { - for (; pas16->pos < sound_pos_global; pas16->pos++) - { - pas16->pcm_buffer[0][pas16->pos] = 0; - pas16->pcm_buffer[1][pas16->pos] = 0; - } - } - else - { - for (; pas16->pos < sound_pos_global; pas16->pos++) - { - pas16->pcm_buffer[0][pas16->pos] = (int16_t)pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] = (int16_t)pas16->pcm_dat_r; - } - } -} - -void pas16_get_buffer(int32_t *buffer, int len, void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - int c; - - opl3_update2(&pas16->opl); - sb_dsp_update(&pas16->dsp); - pas16_update(pas16); - for (c = 0; c < len * 2; c++) - { - buffer[c] += pas16->opl.buffer[c]; - buffer[c] += (int16_t)(sb_iir(c & 1, (float)pas16->dsp.buffer[c]) / 1.3) / 2; - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); - } - - pas16->pos = 0; - pas16->opl.pos = 0; - pas16->dsp.pos = 0; -} - - -static void *pas16_init(const device_t *info) -{ - pas16_t *pas16 = malloc(sizeof(pas16_t)); - memset(pas16, 0, sizeof(pas16_t)); - - opl3_init(&pas16->opl); - sb_dsp_init(&pas16->dsp, SB2); - - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - - timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0], pas16); - - sound_add_handler(pas16_get_buffer, pas16); - - return pas16; -} - -static void pas16_close(void *p) -{ - pas16_t *pas16 = (pas16_t *)p; - - free(pas16); -} - -const device_t pas16_device = -{ - "Pro Audio Spectrum 16", - DEVICE_ISA | DEVICE_NOT_WORKING, - 0, - pas16_init, pas16_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_pas16.h b/src - Cópia/sound/snd_pas16.h deleted file mode 100644 index d7a208faa..000000000 --- a/src - Cópia/sound/snd_pas16.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pas16_device; diff --git a/src - Cópia/sound/snd_pssj.c b/src - Cópia/sound/snd_pssj.c deleted file mode 100644 index 1b6af8caf..000000000 --- a/src - Cópia/sound/snd_pssj.c +++ /dev/null @@ -1,218 +0,0 @@ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../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" - - -typedef struct pssj_t -{ - sn76489_t sn76489; - - uint8_t ctrl; - uint8_t wave; - uint8_t dac_val; - uint16_t freq; - int amplitude; - - int irq; - int64_t timer_count; - int64_t enable; - - int wave_pos; - int pulse_width; - - int16_t buffer[SOUNDBUFLEN]; - int pos; -} pssj_t; - -static void pssj_update_irq(pssj_t *pssj) -{ - if (pssj->irq && (pssj->ctrl & 0x10) && (pssj->ctrl & 0x08)) - picint(1 << 7); -} - -static void pssj_write(uint16_t port, uint8_t val, void *p) -{ - pssj_t *pssj = (pssj_t *)p; - - switch (port & 3) - { - case 0: - pssj->ctrl = val; - pssj->enable = (val & 4) && (pssj->ctrl & 3); - sn74689_set_extra_divide(&pssj->sn76489, val & 0x40); - if (!(val & 8)) - pssj->irq = 0; - pssj_update_irq(pssj); - break; - case 1: - switch (pssj->ctrl & 3) - { - case 1: /*Sound channel*/ - pssj->wave = val; - pssj->pulse_width = val & 7; - break; - case 3: /*Direct DAC*/ - pssj->dac_val = val; - break; - } - break; - case 2: - pssj->freq = (pssj->freq & 0xf00) | val; - break; - case 3: - pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); - pssj->amplitude = val >> 4; - break; - } -} -static uint8_t pssj_read(uint16_t port, void *p) -{ - pssj_t *pssj = (pssj_t *)p; - - switch (port & 3) - { - case 0: - return (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0); - case 1: - switch (pssj->ctrl & 3) - { - case 0: /*Joystick*/ - return 0; - case 1: /*Sound channel*/ - return pssj->wave; - case 2: /*Successive approximation*/ - return 0x80; - case 3: /*Direct DAC*/ - return pssj->dac_val; - } - break; - case 2: - return pssj->freq & 0xff; - case 3: - return (pssj->freq >> 8) | (pssj->amplitude << 4); - default: - return 0xff; - } - - return 0xff; -} - -static void pssj_update(pssj_t *pssj) -{ - for (; pssj->pos < sound_pos_global; pssj->pos++) - pssj->buffer[pssj->pos] = (((int8_t)(pssj->dac_val ^ 0x80) * 0x20) * pssj->amplitude) / 15; -} - -static void pssj_callback(void *p) -{ - pssj_t *pssj = (pssj_t *)p; - int data; - - pssj_update(pssj); - if (pssj->ctrl & 2) - { - if ((pssj->ctrl & 3) == 3) - { - data = dma_channel_read(1); - - if (data != DMA_NODATA) - { - pssj->dac_val = data & 0xff; - } - } - else - { - data = dma_channel_write(1, 0x80); - } - - if ((data & DMA_OVER) && data != DMA_NODATA) - { - if (pssj->ctrl & 0x08) - { - pssj->irq = 1; - pssj_update_irq(pssj); - } - } - } - else - { - switch (pssj->wave & 0xc0) - { - case 0x00: /*Pulse*/ - pssj->dac_val = (pssj->wave_pos > (pssj->pulse_width << 1)) ? 0xff : 0; - break; - case 0x40: /*Ramp*/ - pssj->dac_val = pssj->wave_pos << 3; - break; - case 0x80: /*Triangle*/ - if (pssj->wave_pos & 16) - pssj->dac_val = (pssj->wave_pos ^ 31) << 4; - else - pssj->dac_val = pssj->wave_pos << 4; - break; - case 0xc0: - pssj->dac_val = 0x80; - break; - } - pssj->wave_pos = (pssj->wave_pos + 1) & 31; - } - - pssj->timer_count += (int64_t)(TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400)); -} - -static void pssj_get_buffer(int32_t *buffer, int len, void *p) -{ - pssj_t *pssj = (pssj_t *)p; - int c; - - pssj_update(pssj); - - for (c = 0; c < len * 2; c++) - buffer[c] += pssj->buffer[c >> 1]; - - pssj->pos = 0; -} - -void *pssj_init(const device_t *info) -{ - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); - - sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); - - io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); - timer_add(pssj_callback, &pssj->timer_count, &pssj->enable, pssj); - sound_add_handler(pssj_get_buffer, pssj); - - return pssj; -} - -void pssj_close(void *p) -{ - pssj_t *pssj = (pssj_t *)p; - - free(pssj); -} - -const device_t pssj_device = -{ - "Tandy PSSJ", - 0, 0, - pssj_init, - pssj_close, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_pssj.h b/src - Cópia/sound/snd_pssj.h deleted file mode 100644 index 71126f615..000000000 --- a/src - Cópia/sound/snd_pssj.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pssj_device; diff --git a/src - Cópia/sound/snd_resid.cc b/src - Cópia/sound/snd_resid.cc deleted file mode 100644 index a984323bd..000000000 --- a/src - Cópia/sound/snd_resid.cc +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include "resid-fp/sid.h" -#include "../plat.h" -#include "snd_resid.h" - - -typedef struct psid_t -{ - /* resid sid implementation */ - SIDFP *sid; - int16_t last_sample; -} psid_t; - - -psid_t *psid; - - -void *sid_init(void) -{ -// psid_t *psid; - int c; - sampling_method method=SAMPLE_INTERPOLATE; - float cycles_per_sec = 14318180.0 / 16.0; - - psid = new psid_t; -// psid = (psid_t *)malloc(sizeof(sound_t)); - psid->sid = new SIDFP; - - psid->sid->set_chip_model(MOS8580FP); - - psid->sid->set_voice_nonlinearity(1.0f); - psid->sid->get_filter().set_distortion_properties(0.f, 0.f, 0.f); - psid->sid->get_filter().set_type4_properties(6.55f, 20.0f); - - psid->sid->enable_filter(true); - psid->sid->enable_external_filter(true); - - psid->sid->reset(); - - for (c=0;c<32;c++) - psid->sid->write(c,0); - - if (!psid->sid->set_sampling_parameters((float)cycles_per_sec, method, - (float)48000, 0.9*48000.0/2.0)) - { - // printf("reSID failed!\n"); - } - - psid->sid->set_chip_model(MOS6581FP); - psid->sid->set_voice_nonlinearity(0.96f); - psid->sid->get_filter().set_distortion_properties(3.7e-3f, 2048.f, 1.2e-4f); - - psid->sid->input(0); - psid->sid->get_filter().set_type3_properties(1.33e6f, 2.2e9f, 1.0056f, 7e3f); - - return (void *)psid; -} - -void sid_close(UNUSED(void *p)) -{ -// psid_t *psid = (psid_t *)p; - delete psid->sid; -// free(psid); -} - -void sid_reset(UNUSED(void *p)) -{ -// psid_t *psid = (psid_t *)p; - int c; - - psid->sid->reset(); - - for (c = 0; c < 32; c++) - psid->sid->write(c, 0); -} - - -uint8_t sid_read(uint16_t addr, UNUSED(void *p)) -{ -// psid_t *psid = (psid_t *)p; - - return psid->sid->read(addr & 0x1f); -// return 0xFF; -} - -void sid_write(uint16_t addr, uint8_t val, UNUSED(void *p)) -{ -// psid_t *psid = (psid_t *)p; - - psid->sid->write(addr & 0x1f,val); -} - -#define CLOCK_DELTA(n) (int)(((14318180.0 * n) / 16.0) / 48000.0) - -static void fillbuf2(int& count, int16_t *buf, int len) -{ - int c; - c = psid->sid->clock(count, buf, len, 1); - if (!c) - *buf = psid->last_sample; - psid->last_sample = *buf; -} -void sid_fillbuf(int16_t *buf, int len, UNUSED(void *p)) -{ -// psid_t *psid = (psid_t *)p; - int x = CLOCK_DELTA(len); - - fillbuf2(x, buf, len); -} diff --git a/src - Cópia/sound/snd_resid.h b/src - Cópia/sound/snd_resid.h deleted file mode 100644 index 402ee0ceb..000000000 --- a/src - Cópia/sound/snd_resid.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - void *sid_init(); - void sid_close(void *p); - void sid_reset(void *p); - uint8_t sid_read(uint16_t addr, void *p); - void sid_write(uint16_t addr, uint8_t val, void *p); - void sid_fillbuf(int16_t *buf, int len, void *p); -#ifdef __cplusplus -} -#endif diff --git a/src - Cópia/sound/snd_sb.c b/src - Cópia/sound/snd_sb.c deleted file mode 100644 index c2831ece9..000000000 --- a/src - Cópia/sound/snd_sb.c +++ /dev/null @@ -1,1954 +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.c 1.0.9 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "sound.h" -#include "filters.h" -#include "snd_dbopl.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 - -#ifdef SB_DSP_RECORD_DEBUG -FILE* soundfsb = 0/*NULL*/; -FILE* soundfsbin = 0/*NULL*/; -#endif - - - -/* SB 2.0 CD version */ -typedef struct sb_ct1335_mixer_t -{ - int32_t master; - int32_t voice; - int32_t fm; - int32_t cd; - - uint8_t index; - uint8_t regs[256]; -} sb_ct1335_mixer_t; -/* SB PRO */ -typedef struct sb_ct1345_mixer_t -{ - int32_t master_l, master_r; - int32_t voice_l, voice_r; - int32_t fm_l, fm_r; - int32_t cd_l, cd_r; - int32_t line_l, line_r; - int32_t mic; - /*see sb_ct1745_mixer for values for input selector*/ - int32_t input_selector; - - int input_filter; - int in_filter_freq; - int output_filter; - - int stereo; - int stereo_isleft; - - uint8_t index; - uint8_t regs[256]; - -} sb_ct1345_mixer_t; -/* SB16 and AWE32 */ -typedef struct sb_ct1745_mixer_t -{ - int32_t master_l, master_r; - int32_t voice_l, voice_r; - int32_t fm_l, fm_r; - int32_t cd_l, cd_r; - int32_t line_l, line_r; - int32_t mic; - int32_t speaker; - - int bass_l, bass_r; - int treble_l, treble_r; - - int output_selector; - #define OUTPUT_MIC 1 - #define OUTPUT_CD_R 2 - #define OUTPUT_CD_L 4 - #define OUTPUT_LINE_R 8 - #define OUTPUT_LINE_L 16 - - int input_selector_left; - int input_selector_right; - #define INPUT_MIC 1 - #define INPUT_CD_R 2 - #define INPUT_CD_L 4 - #define INPUT_LINE_R 8 - #define INPUT_LINE_L 16 - #define INPUT_MIDI_R 32 - #define INPUT_MIDI_L 64 - - int mic_agc; - - int32_t input_gain_L; - int32_t input_gain_R; - int32_t output_gain_L; - int32_t output_gain_R; - - uint8_t index; - uint8_t regs[256]; -} sb_ct1745_mixer_t; - -typedef struct sb_t -{ - uint8_t opl_enabled; - opl_t opl; - sb_dsp_t dsp; - union { - sb_ct1335_mixer_t mixer_sb2; - sb_ct1345_mixer_t mixer_sbpro; - sb_ct1745_mixer_t mixer_sb16; - }; - mpu_t mpu; - emu8k_t emu8k; -#if 0 - sb_ct1745_mixer_t temp_mixer_sb16; -#endif - - int pos; - - uint8_t pos_regs[8]; - - int opl_emu; -} sb_t; -/* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. - Note that for positive dB values, this is not amplitude, it is amplitude-1. */ -const float sb_bass_treble_4bits[]= { - 0.199526231, 0.25, 0.316227766, 0.398107170, 0.5, 0.63095734, 0.794328234, 1, - 0, 0.25892541, 0.584893192, 1, 1.511886431, 2.16227766, 3, 4.011872336 -}; - -/* Attenuation tables for the mixer. Max volume = 32767 in order to give 6dB of - * headroom and avoid integer overflow */ -const int32_t sb_att_2dbstep_5bits[]= -{ - 25,32,41,51,65,82,103,130,164,206,260,327,412,519,653, - 822,1036,1304,1641,2067,2602,3276,4125,5192,6537,8230,10362,13044, - 16422,20674,26027,32767 -}; -const int32_t sb_att_4dbstep_3bits[]= -{ - 164,2067,3276,5193,8230,13045,20675,32767 -}; -const int32_t sb_att_7dbstep_2bits[]= -{ - 164,6537,14637,32767 -}; - - -#ifdef ENABLE_SB_LOG -int sb_do_log = ENABLE_SB_LOG; -#endif - - -static void -sb_log(const char *fmt, ...) -{ -#ifdef ENABLE_SB_LOG - va_list ap; - - if (sb_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* sb 1, 1.5, 2, 2 mvc do not have a mixer, so signal is hardwired */ -static void sb_get_buffer_sb2(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - - int c; - - if (sb->opl_enabled) - opl2_update2(&sb->opl); - sb_dsp_update(&sb->dsp); - for (c = 0; c < len * 2; c += 2) - { - int32_t out = 0; - if (sb->opl_enabled) - out = ((sb->opl.buffer[c] * 51000) >> 16); - //TODO: Recording: Mic and line In with AGC - out += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * 65536) / 3) >> 16; - - buffer[c] += out; - buffer[c + 1] += out; - } - - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; -} - -static void sb_get_buffer_sb2_mixer(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - - int c; - - if (sb->opl_enabled) - opl2_update2(&sb->opl); - sb_dsp_update(&sb->dsp); - for (c = 0; c < len * 2; c += 2) - { - int32_t out = 0; - - if (sb->opl_enabled) - out = ((((sb->opl.buffer[c] * mixer->fm) >> 16) * 51000) >> 15); - /* TODO: Recording : I assume it has direct mic and line in like sb2 */ - /* It is unclear from the docs if it has a filter, but it probably does */ - out += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice) / 3) >> 15; - - out = (out * mixer->master) >> 15; - - buffer[c] += out; - buffer[c + 1] += out; - } - - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; -} - -static void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - - int c; - - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) - opl2_update2(&sb->opl); - else - opl3_update2(&sb->opl); - } - - sb_dsp_update(&sb->dsp); - for (c = 0; c < len * 2; c += 2) - { - int32_t out_l = 0, out_r = 0; - - if (sb->opl_enabled) { - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); - } - - /*TODO: Implement the stereo switch on the mixer instead of on the dsp? */ - if (mixer->output_filter) - { - out_l += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 15; - out_r += (int32_t)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 15; - } - else - { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 15; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; - } - //TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. - - out_l = (out_l * mixer->master_l) >> 15; - out_r = (out_r * mixer->master_r) >> 15; - - buffer[c] += out_l; - buffer[c + 1] += out_r; - } - - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; -} - -// FIXME: See why this causes weird audio glitches in some situations. -#if 0 -static void sb_process_buffer_sb16(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1745_mixer_t *mixer = &sb->temp_mixer_sb16; - - int c; - - for (c = 0; c < len * 2; c += 2) - { - int32_t out_l = 0, out_r = 0; - - out_l = ((int32_t)(low_fir_sb16(0, (float)buffer[c]) * mixer->cd_l) / 3) >> 15; - out_r = ((int32_t)(low_fir_sb16(1, (float)buffer[c + 1]) * mixer->cd_r) / 3) >> 15; - - out_l = (out_l * mixer->master_l) >> 15; - out_r = (out_r * mixer->master_r) >> 15; - - if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) - { - /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage */ - if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); - if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); - if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); - if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->treble_r])); - } - - buffer[c] = (out_l << mixer->output_gain_L); - buffer[c + 1] = (out_r << mixer->output_gain_R); - } -} -#endif - -static void sb_get_buffer_sb16(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - - int c; - - if (sb->opl_enabled) - opl3_update2(&sb->opl); - sb_dsp_update(&sb->dsp); - const int dsp_rec_pos = sb->dsp.record_pos_write; - for (c = 0; c < len * 2; c += 2) - { - int32_t out_l = 0, out_r = 0, in_l, in_r; - - if (sb->opl_enabled) { - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); - } - - /*TODO: multi-recording mic with agc/+20db, cd and line in with channel inversion */ - in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; - in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; - - out_l += ((int32_t)(low_fir_sb16(0, (float)sb->dsp.buffer[c]) * mixer->voice_l) / 3) >> 15; - out_r += ((int32_t)(low_fir_sb16(1, (float)sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3) >> 15; - - out_l = (out_l * mixer->master_l) >> 15; - out_r = (out_r * mixer->master_r) >> 15; - - if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) - { - /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage */ - if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); - if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); - if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); - if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->treble_r])); - } - if (sb->dsp.sb_enable_i) - { - int c_record = dsp_rec_pos; - c_record +=(((c/2) * sb->dsp.sb_freq) / 48000)*2; - in_l <<= mixer->input_gain_L; - in_r <<= mixer->input_gain_R; - // Clip signal - if (in_l < -32768) - in_l = -32768; - else if (in_l > 32767) - in_l = 32767; - - if (in_r < -32768) - in_r = -32768; - else if (in_r > 32767) - in_r = 32767; - sb->dsp.record_buffer[c_record&0xFFFF] = in_l; - sb->dsp.record_buffer[(c_record+1)&0xFFFF] = in_r; - } - - buffer[c] += (out_l << mixer->output_gain_L); - buffer[c + 1] += (out_r << mixer->output_gain_R); - } - sb->dsp.record_pos_write+=((len * sb->dsp.sb_freq) / 48000)*2; - sb->dsp.record_pos_write&=0xFFFF; - - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; -#if 0 - memcpy(&sb->temp_mixer_sb16, &sb->mixer_sb16, sizeof(sb_ct1745_mixer_t)); -#endif -} -#ifdef SB_DSP_RECORD_DEBUG -int old_dsp_rec_pos=0; -int buf_written=0; -int last_crecord=0; -#endif -static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - - int c; - - if (sb->opl_enabled) - opl3_update2(&sb->opl); - emu8k_update(&sb->emu8k); - sb_dsp_update(&sb->dsp); - const int dsp_rec_pos = sb->dsp.record_pos_write; - for (c = 0; c < len * 2; c += 2) - { - int32_t out_l = 0, out_r = 0, in_l, in_r; - int c_emu8k = (((c/2) * 44100) / 48000)*2; - - if (sb->opl_enabled) { - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 15) * (sb->opl_emu ? 47000 : 51000)) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 15) * (sb->opl_emu ? 47000 : 51000)) >> 16); - } - - out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 15); - out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_r) >> 15); - - /*TODO: multi-recording mic with agc/+20db, cd and line in with channel inversion */ - in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; - in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; - - out_l += ((int32_t)(low_fir_sb16(0, (float)sb->dsp.buffer[c]) * mixer->voice_l) / 3) >> 15; - out_r += ((int32_t)(low_fir_sb16(1, (float)sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3) >> 15; - - out_l = (out_l * mixer->master_l) >> 15; - out_r = (out_r * mixer->master_r) >> 15; - - if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) - { - /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage */ - if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); - if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); - if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); - if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)(out_l *sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)(out_r *sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)(out_l *sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)(out_r *sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->treble_r])); - } - if (sb->dsp.sb_enable_i) - { -// in_l += (mixer->input_selector_left&INPUT_CD_L) ? audio_cd_buffer[cd_read_pos+c_emu8k] : 0 + (mixer->input_selector_left&INPUT_CD_R) ? audio_cd_buffer[cd_read_pos+c_emu8k+1] : 0; -// in_r += (mixer->input_selector_right&INPUT_CD_L) ? audio_cd_buffer[cd_read_pos+c_emu8k]: 0 + (mixer->input_selector_right&INPUT_CD_R) ? audio_cd_buffer[cd_read_pos+c_emu8k+1] : 0; - - int c_record = dsp_rec_pos; - c_record +=(((c/2) * sb->dsp.sb_freq) / 48000)*2; - #ifdef SB_DSP_RECORD_DEBUG - if (c_record > 0xFFFF && !buf_written) - { - if (!soundfsb) soundfsb=plat_fopen(L"sound_sb.pcm",L"wb"); - fwrite(sb->dsp.record_buffer,2,0x10000,soundfsb); - old_dsp_rec_pos = dsp_rec_pos; - buf_written=1; - } - #endif - in_l <<= mixer->input_gain_L; - in_r <<= mixer->input_gain_R; - // Clip signal - if (in_l < -32768) - in_l = -32768; - else if (in_l > 32767) - in_l = 32767; - - if (in_r < -32768) - in_r = -32768; - else if (in_r > 32767) - in_r = 32767; - sb->dsp.record_buffer[c_record&0xFFFF] = in_l; - sb->dsp.record_buffer[(c_record+1)&0xFFFF] = in_r; - #ifdef SB_DSP_RECORD_DEBUG - if (c_record != last_crecord) - { - if (!soundfsbin) soundfsbin=plat_fopen(L"sound_sb_in.pcm",L"wb"); - fwrite(&sb->dsp.record_buffer[c_record&0xFFFF],2,2,soundfsbin); - last_crecord=c_record; - } - #endif - } - - buffer[c] += (out_l << mixer->output_gain_L); - buffer[c + 1] += (out_r << mixer->output_gain_R); - } - #ifdef SB_DSP_RECORD_DEBUG - if (old_dsp_rec_pos > dsp_rec_pos) - { - buf_written=0; - old_dsp_rec_pos=dsp_rec_pos; - } - #endif - - sb->dsp.record_pos_write+=((len * sb->dsp.sb_freq) / 48000)*2; - sb->dsp.record_pos_write&=0xFFFF; - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; - sb->emu8k.pos = 0; -#if 0 - memcpy(&sb->temp_mixer_sb16, &sb->mixer_sb16, sizeof(sb_ct1745_mixer_t)); -#endif -} - - -void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - - if (!(addr & 1)) - { - mixer->index = val; - mixer->regs[0x01] = val; - } - else - { - if (mixer->index == 0) - { - /* Reset */ - mixer->regs[0x02] = 4 << 1; - mixer->regs[0x06] = 4 << 1; - mixer->regs[0x08] = 0 << 1; - /* changed default from -46dB to 0dB*/ - mixer->regs[0x0A] = 3 << 1; - } - else - { - mixer->regs[mixer->index] = val; - switch (mixer->index) - { - case 0x00: case 0x02: case 0x06: case 0x08: case 0x0A: - break; - - default: - sb_log("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } - mixer->master = sb_att_4dbstep_3bits[(mixer->regs[0x02] >> 1)&0x7]; - mixer->fm = sb_att_4dbstep_3bits[(mixer->regs[0x06] >> 1)&0x7]; - mixer->cd = sb_att_4dbstep_3bits[(mixer->regs[0x08] >> 1)&0x7]; - mixer->voice = sb_att_7dbstep_2bits[(mixer->regs[0x0A] >> 1)&0x3]; - - sound_set_cd_volume(((uint32_t)mixer->master * (uint32_t)mixer->cd) / 65535, - ((uint32_t)mixer->master * (uint32_t)mixer->cd) / 65535); - } -} - -uint8_t sb_ct1335_mixer_read(uint16_t addr, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - - if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) - { - case 0x00: case 0x02: case 0x06: case 0x08: case 0x0A: - return mixer->regs[mixer->index]; - default: - sb_log("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0xff; -} - -void sb_ct1335_mixer_reset(sb_t* sb) -{ - sb_ct1335_mixer_write(0x254,0,sb); - sb_ct1335_mixer_write(0x255,0,sb); -} - -void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - - if (!(addr & 1)) - { - mixer->index = val; - mixer->regs[0x01] = val; - } - else - { - if (mixer->index == 0) - { - /* Reset */ - mixer->regs[0x0A] = 0 << 1; - mixer->regs[0x0C] = (0 << 5) | (0 << 3) | (0 << 1); - mixer->regs[0x0E] = (0 << 5) | (0 << 1); - /* changed default from -11dB to 0dB */ - mixer->regs[0x04] = (7 << 5) | (7 << 1); - mixer->regs[0x22] = (7 << 5) | (7 << 1); - mixer->regs[0x26] = (7 << 5) | (7 << 1); - mixer->regs[0x28] = (7 << 5) | (7 << 1); - mixer->regs[0x2E] = (0 << 5) | (0 << 1); - sb_dsp_set_stereo(&sb->dsp, mixer->regs[0x0E] & 2); - } - else - { - mixer->regs[mixer->index] = val; - switch (mixer->index) - { - /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ - case 0x02: case 0x06: case 0x08: - mixer->regs[mixer->index+0x20]=((val&0xE) << 4)|(val&0xE) << 4; - break; - - case 0x22: case 0x26: case 0x28: - mixer->regs[mixer->index-0x20]=(val&0xE); - break; - - /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h,028h for 038h. */ - case 0x30: case 0x32: case 0x36: case 0x38: - mixer->regs[mixer->index-0x10]=(val&0xEE); - break; - - case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: - case 0x2e: - break; - - - default: - sb_log("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } - - mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5)&0x7]; - mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1)&0x7]; - mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5)&0x7]; - mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1)&0x7]; - mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5)&0x7]; - mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1)&0x7]; - mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5)&0x7]; - mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1)&0x7]; - mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2E] >> 5)&0x7]; - mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2E] >> 1)&0x7]; - - mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0A] >> 1)&0x3]; - - mixer->output_filter = !(mixer->regs[0xE] & 0x20); - mixer->input_filter = !(mixer->regs[0xC] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xC] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xE] & 2; - if (mixer->index == 0xE) - sb_dsp_set_stereo(&sb->dsp, val & 2); - - switch ((mixer->regs[0xc]&6)) - { - case 2: - mixer->input_selector = INPUT_CD_L|INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L|INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } - - /* TODO: pcspeaker volume? Or is it not worth? */ - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); - } -} - -uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - - if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) - { - case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: - case 0x22: case 0x26: case 0x28: case 0x2e: case 0x02: case 0x06: - case 0x30: case 0x32: case 0x36: case 0x38: - return mixer->regs[mixer->index]; - - default: - sb_log("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0xff; -} -void sb_ct1345_mixer_reset(sb_t* sb) -{ - sb_ct1345_mixer_write(4,0,sb); - sb_ct1345_mixer_write(5,0,sb); -} - -void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) -{ - sb_t *sb = (sb_t *)p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - - if (!(addr & 1)) - { - mixer->index = val; - } - else - { - // TODO: and this? 001h: - /*DESCRIPTION - Contains previously selected register value. Mixer Data Register value - NOTES - * SoundBlaster 16 sets bit 7 if previous mixer index invalid. - * Status bytes initially 080h on startup for all but level bytes (SB16) - */ - - if (mixer->index == 0) - { - /* Reset */ - /* Changed defaults from -14dB to 0dB*/ - mixer->regs[0x30]=31 << 3; - mixer->regs[0x31]=31 << 3; - mixer->regs[0x32]=31 << 3; - mixer->regs[0x33]=31 << 3; - mixer->regs[0x34]=31 << 3; - mixer->regs[0x35]=31 << 3; - mixer->regs[0x36]=31 << 3; - mixer->regs[0x37]=31 << 3; - mixer->regs[0x38]=0 << 3; - mixer->regs[0x39]=0 << 3; - - mixer->regs[0x3A]=0 << 3; - - mixer->regs[0x3B]=0 << 6; - mixer->regs[0x3C] = OUTPUT_MIC|OUTPUT_CD_R|OUTPUT_CD_L|OUTPUT_LINE_R|OUTPUT_LINE_L; - mixer->regs[0x3D] = INPUT_MIC|INPUT_CD_L|INPUT_LINE_L|INPUT_MIDI_L; - mixer->regs[0x3E] = INPUT_MIC|INPUT_CD_R|INPUT_LINE_R|INPUT_MIDI_R; - - mixer->regs[0x3F] = mixer->regs[0x40] = 0 << 6; - mixer->regs[0x41] = mixer->regs[0x42] = 0 << 6; - - mixer->regs[0x44] = mixer->regs[0x45] = 8 << 4; - mixer->regs[0x46] = mixer->regs[0x47] = 8 << 4; - - mixer->regs[0x43] = 0; - } - else - { - mixer->regs[mixer->index] = val; - } - switch (mixer->index) - { - /* SBPro compatibility. Copy values to sb16 registers. */ - case 0x22: - mixer->regs[0x30] = (mixer->regs[0x22] & 0xF0) | 0x8; - mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) << 4) | 0x8; - break; - case 0x04: - mixer->regs[0x32] = (mixer->regs[0x04] & 0xF0) | 0x8; - mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) << 4) | 0x8; - break; - case 0x26: - mixer->regs[0x34] = (mixer->regs[0x26] & 0xF0) | 0x8; - mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) << 4) | 0x8; - break; - case 0x28: - mixer->regs[0x36] = (mixer->regs[0x28] & 0xF0) | 0x8; - mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; - break; - case 0x0A: - mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; - break; - case 0x2E: - mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; - mixer->regs[0x39] = ((mixer->regs[0x2E] & 0xf) << 4) | 0x8; - break; - - /* - (DSP 4.xx feature) The Interrupt Setup register, addressed as register 80h on the Mixer register map, is used to configure or determine the Interrupt request line. The DMA setup register, addressed as register 81h on the Mixer register map, is used to configure or determine the DMA channels. - - Note: Registers 80h and 81h are Read-only for PnP boards. - */ - case 0x80: - if (val & 1) sb_dsp_setirq(&sb->dsp,2); - if (val & 2) sb_dsp_setirq(&sb->dsp,5); - if (val & 4) sb_dsp_setirq(&sb->dsp,7); - if (val & 8) sb_dsp_setirq(&sb->dsp,10); - break; - - case 0x81: - /* The documentation is confusing. sounds as if multple dma8 channels could be set. */ - if (val & 1) sb_dsp_setdma8(&sb->dsp,0); - if (val & 2) sb_dsp_setdma8(&sb->dsp,1); - if (val & 8) sb_dsp_setdma8(&sb->dsp,3); - if (val & 0x20) sb_dsp_setdma16(&sb->dsp,5); - if (val & 0x40) sb_dsp_setdma16(&sb->dsp,6); - if (val & 0x80) sb_dsp_setdma16(&sb->dsp,7); - break; - } - - mixer->output_selector = mixer->regs[0x3C]; - mixer->input_selector_left = mixer->regs[0x3D]; - mixer->input_selector_right = mixer->regs[0x3E]; - - mixer->master_l = sb_att_2dbstep_5bits[mixer->regs[0x30] >> 3]; - mixer->master_r = sb_att_2dbstep_5bits[mixer->regs[0x31] >> 3]; - mixer->voice_l = sb_att_2dbstep_5bits[mixer->regs[0x32] >> 3]; - mixer->voice_r = sb_att_2dbstep_5bits[mixer->regs[0x33] >> 3]; - mixer->fm_l = sb_att_2dbstep_5bits[mixer->regs[0x34] >> 3]; - mixer->fm_r = sb_att_2dbstep_5bits[mixer->regs[0x35] >> 3]; - mixer->cd_l = (mixer->output_selector&OUTPUT_CD_L) ? sb_att_2dbstep_5bits[mixer->regs[0x36] >> 3] : 0; - mixer->cd_r = (mixer->output_selector&OUTPUT_CD_R) ? sb_att_2dbstep_5bits[mixer->regs[0x37] >> 3] : 0; - mixer->line_l = (mixer->output_selector&OUTPUT_LINE_L) ? sb_att_2dbstep_5bits[mixer->regs[0x38] >> 3] : 0; - mixer->line_r = (mixer->output_selector&OUTPUT_LINE_R) ? sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] : 0; - - mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3A] >> 3]; - mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3B]*3 + 22]; - - - mixer->input_gain_L = (mixer->regs[0x3F] >> 6); - mixer->input_gain_R = (mixer->regs[0x40] >> 6); - mixer->output_gain_L = (mixer->regs[0x41] >> 6); - mixer->output_gain_R = (mixer->regs[0x42] >> 6); - - mixer->bass_l = mixer->regs[0x46] >> 4; - mixer->bass_r = mixer->regs[0x47] >> 4; - mixer->treble_l = mixer->regs[0x44] >> 4; - mixer->treble_r = mixer->regs[0x45] >> 4; - - /*TODO: pcspeaker volume, with "output_selector" check? or better not? */ - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); - sb_log("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - } -} - -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; - - if (!(addr & 1)) - return mixer->index; - - 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) - { - case 0x00: - return mixer->regs[mixer->index]; - - /*SB Pro compatibility*/ - case 0x04: - return ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); - case 0x0a: - return (mixer->regs[0x3a] - 10) / 3; - case 0x22: - return ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); - case 0x26: - return ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); - case 0x28: - return ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); - case 0x2e: - return ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); - - 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]; - - case 0x80: - /*TODO: Unaffected by mixer reset or soft reboot. - * Enabling multiple bits enables multiple IRQs. - */ - - switch (sb->dsp.sb_irqnum) - { - case 2: return 1; - case 5: return 2; - case 7: return 4; - case 10: return 8; - } - 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.*/ - - 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; - } - - /* 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, - in which case it should chain to the previous routine. - */ - case 0x82: - /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ - /* 0x02000 DSP v4.04, 0x4000 DSP v4.05 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ - return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | 0x4000; - - /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - - - default: - sb_log("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0xff; -} - -void sb_ct1745_mixer_reset(sb_t* sb) -{ - sb_ct1745_mixer_write(4,0,sb); - sb_ct1745_mixer_write(5,0,sb); -} - - -static uint16_t sb_mcv_addr[8] = {0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270}; - -uint8_t sb_mcv_read(int port, void *p) -{ - sb_t *sb = (sb_t *)p; - - sb_log("sb_mcv_read: port=%04x\n", port); - - return sb->pos_regs[port & 7]; -} - -void sb_mcv_write(int port, uint8_t val, void *p) -{ - uint16_t addr; - sb_t *sb = (sb_t *)p; - - if (port < 0x102) - return; - - sb_log("sb_mcv_write: port=%04x val=%02x\n", port, val); - - addr = sb_mcv_addr[sb->pos_regs[4] & 7]; - if (sb->opl_enabled) { - io_removehandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, 0); - - sb->pos_regs[port & 7] = val; - - if (sb->pos_regs[2] & 1) - { - addr = sb_mcv_addr[sb->pos_regs[4] & 7]; - - if (sb->opl_enabled) { - io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, addr); - } -} - -static int sb_pro_mcv_irqs[4] = {7, 5, 3, 3}; - -uint8_t sb_pro_mcv_read(int port, void *p) -{ - sb_t *sb = (sb_t *)p; - - sb_log("sb_pro_mcv_read: port=%04x\n", port); - - return sb->pos_regs[port & 7]; -} - -void sb_pro_mcv_write(int port, uint8_t val, void *p) -{ - uint16_t addr; - sb_t *sb = (sb_t *)p; - - if (port < 0x102) - return; - - sb_log("sb_pro_mcv_write: port=%04x val=%02x\n", port, val); - - addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; - io_removehandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_removehandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, 0); - - sb->pos_regs[port & 7] = val; - - if (sb->pos_regs[2] & 1) - { - addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; - - io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, addr); - } - sb_dsp_setirq(&sb->dsp, sb_pro_mcv_irqs[(sb->pos_regs[5] >> 4) & 3]); - sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3); -} - -void *sb_1_init() -{ - /*sb1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB1); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_set_mpu(&sb->mpu); - /* CMS I/O handler is activated on the dedicated sound_cms module - DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - sound_add_handler(sb_get_buffer_sb2, sb); - return sb; -} -void *sb_15_init() -{ - /*sb1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - /* CMS I/O handler is activated on the dedicated sound_cms module - DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - sound_add_handler(sb_get_buffer_sb2, sb); - return sb; -} - -void *sb_mcv_init() -{ - /*sb1/2 port mappings, 210h to 260h in 10h steps - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15); - sb_dsp_setaddr(&sb->dsp, 0);//addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_set_mpu(&sb->mpu); - sound_add_handler(sb_get_buffer_sb2, sb); - /* I/O handlers activated in sb_mcv_write */ - mca_add(sb_mcv_read, sb_mcv_write, sb); - sb->pos_regs[0] = 0x84; - sb->pos_regs[1] = 0x50; - return sb; -} -void *sb_2_init() -{ - /*sb2 port mappings. 220h or 240h. - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip - "CD version" also uses 250h or 260h for - 2x0 to 2x3 -> CDROM interface - 2x4 to 2x5 -> Mixer interface*/ - /*My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is - disabled when the CMS chips are present. - This mirror may also exist on SB 1.5 & MCV, however I am unable to - test this. It shouldn't exist on SB 1.0 as the CMS chips are always - present there. - Syndicate requires this mirror for music to play.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB2); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_set_mpu(&sb->mpu); - sb_ct1335_mixer_reset(sb); - /* CMS I/O handler is activated on the dedicated sound_cms module - DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - if (!GAMEBLASTER) - io_sethandler(addr, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - - int mixer_addr = device_get_config_int("mixaddr"); - if (mixer_addr > 0) - { - io_sethandler(mixer_addr+4, 0x0002, sb_ct1335_mixer_read, NULL, NULL, sb_ct1335_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_sb2_mixer, sb); - } - else - sound_add_handler(sb_get_buffer_sb2, sb); - - return sb; -} - -void *sb_pro_v1_init() -{ - /*sbpro port mappings. 220h or 240h. - 2x0 to 2x3 -> FM chip, Left and Right (9*2 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SBPRO); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_set_mpu(&sb->mpu); - sb_ct1345_mixer_reset(sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl); - io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); - } - io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_sbpro, sb); - - return sb; -} - -void *sb_pro_v2_init() -{ - /*sbpro port mappings. 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl3_init(&sb->opl); - sb_dsp_init(&sb->dsp, SBPRO2); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_set_mpu(&sb->mpu); - sb_ct1345_mixer_reset(sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - } - io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_sbpro, sb); - - return sb; -} - -void *sb_pro_mcv_init() -{ - /*sbpro port mappings. 220h or 240h. - 2x0 to 2x3 -> FM chip, Left and Right (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices)*/ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = 1; - opl3_init(&sb->opl); - sb_dsp_init(&sb->dsp, SBPRO2); - sb_ct1345_mixer_reset(sb); - /* I/O handlers activated in sb_mcv_write */ - sound_add_handler(sb_get_buffer_sbpro, sb); - - /* I/O handlers activated in sb_pro_mcv_write */ - mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb); - sb->pos_regs[0] = 0x03; - sb->pos_regs[1] = 0x51; - - return sb; -} - -void *sb_16_init() -{ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl3_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB16); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); - sb_ct1745_mixer_reset(sb); - if (sb->opl_enabled) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - } - io_sethandler(addr+4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_sb16, sb); -#if 0 - sound_add_process_handler(sb_process_buffer_sb16, sb); -#endif - mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); - sb_dsp_set_mpu(&sb->mpu); -#if 0 - memcpy(&sb->temp_mixer_sb16, &sb->mixer_sb16, sizeof(sb_ct1745_mixer_t)); -#endif - - return sb; -} - -int sb_awe32_available() -{ - return rom_present(L"roms/sound/awe32.raw"); -} - -void *sb_awe32_init() -{ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t emu_addr = device_get_config_hex16("emu_base"); - int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0, sizeof(sb_t)); - - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - opl3_init(&sb->opl); - - sb_dsp_init(&sb->dsp, SB16 + 1); - sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); - sb_dsp_set_mpu(&sb->mpu); - sb_ct1745_mixer_reset(sb); - if (sb->opl_enabled) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - } - io_sethandler(addr+4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_emu8k, sb); -#if 0 - sound_add_process_handler(sb_process_buffer_sb16, sb); -#endif - mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); - sb_dsp_set_mpu(&sb->mpu); - emu8k_init(&sb->emu8k, emu_addr, onboard_ram); -#if 0 - memcpy(&sb->temp_mixer_sb16, &sb->mixer_sb16, sizeof(sb_ct1745_mixer_t)); -#endif - - return sb; -} - -void sb_close(void *p) -{ - sb_t *sb = (sb_t *)p; - sb_dsp_close(&sb->dsp); - #ifdef SB_DSP_RECORD_DEBUG - if (soundfsb != 0) - { - fclose(soundfsb); - soundfsb=0; - } - if (soundfsbin!= 0) - { - fclose(soundfsbin); - soundfsbin=0; - } - #endif - - free(sb); -} - -void sb_awe32_close(void *p) -{ - sb_t *sb = (sb_t *)p; - - emu8k_close(&sb->emu8k); - - sb_close(sb); -} - -void sb_speed_changed(void *p) -{ - sb_t *sb = (sb_t *)p; - - sb_dsp_speed_changed(&sb->dsp); -} - -static const device_config_t sb_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x220, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -static const device_config_t sb_mcv_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -static const device_config_t sb_pro_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x220, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -static const device_config_t sb_16_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x220, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "" - } - } - }, - { - "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, - { - { - "0x300", 0x300 - }, - { - "0x330", 0x330 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, - { - { - "DMA 0", 0 - }, - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - } - }, - { - "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, - { - { - "UART", M_UART - }, - { - "Intelligent", M_INTELLIGENT - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -static const device_config_t sb_awe32_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x220, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "" - } - } - }, - { - "emu_base", "EMU8000 Address", CONFIG_HEX16, "", 0x620, - { - { - "0x620", 0x620 - }, - { - "0x640", 0x640 - }, - { - "0x660", 0x660 - }, - { - "0x680", 0x680 - }, - { - .description = "" - } - } - }, - { - "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, - { - { - "0x300", 0x300 - }, - { - "0x330", 0x330 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, - { - { - "DMA 0", 0 - }, - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - } - }, - { - "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, - { - { - "UART", M_UART - }, - { - "Intelligent", M_INTELLIGENT - }, - { - "" - } - } - }, - { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, - { - { - "None", 0 - }, - { - "512 KB", 512 - }, - { - "2 MB", 2048 - }, - { - "8 MB", 8192 - }, - { - "28 MB", 28*1024 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -const device_t sb_1_device = -{ - "Sound Blaster v1.0", - DEVICE_ISA, - 0, - sb_1_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_config -}; -const device_t sb_15_device = -{ - "Sound Blaster v1.5", - DEVICE_ISA, - 0, - sb_15_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_config -}; -const device_t sb_mcv_device = -{ - "Sound Blaster MCV", - DEVICE_MCA, - 0, - sb_mcv_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_mcv_config -}; -const device_t sb_2_device = -{ - "Sound Blaster v2.0", - DEVICE_ISA, - 0, - sb_2_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_config -}; -const device_t sb_pro_v1_device = -{ - "Sound Blaster Pro v1", - DEVICE_ISA, - 0, - sb_pro_v1_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_pro_config -}; -const device_t sb_pro_v2_device = -{ - "Sound Blaster Pro v2", - DEVICE_ISA, - 0, - sb_pro_v2_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_pro_config -}; -const device_t sb_pro_mcv_device = -{ - "Sound Blaster Pro MCV", - DEVICE_MCA, - 0, - sb_pro_mcv_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - NULL -}; -const device_t sb_16_device = -{ - "Sound Blaster 16", - DEVICE_ISA, - 0, - sb_16_init, sb_close, NULL, NULL, - sb_speed_changed, - NULL, - sb_16_config -}; -const device_t sb_awe32_device = -{ - "Sound Blaster AWE32", - DEVICE_ISA, - 0, - sb_awe32_init, sb_close, NULL, - sb_awe32_available, - sb_speed_changed, - NULL, - sb_awe32_config -}; diff --git a/src - Cópia/sound/snd_sb.h b/src - Cópia/sound/snd_sb.h deleted file mode 100644 index feaec6c78..000000000 --- a/src - Cópia/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 - Cópia/sound/snd_sb_dsp.c b/src - Cópia/sound/snd_sb_dsp.c deleted file mode 100644 index d4dbf15e1..000000000 --- a/src - Cópia/sound/snd_sb_dsp.c +++ /dev/null @@ -1,1144 +0,0 @@ -/*Jazz sample rates : - 386-33 - 12kHz - 486-33 - 20kHz - 486-50 - 32kHz - Pentium - 45kHz*/ - -#include -#include -#include -#include -#include -#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 "filters.h" -#include "sound.h" -#include "midi.h" -#include "snd_mpu401.h" -#include "snd_sb.h" -#include "snd_sb_dsp.h" - -/*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ -#define SB_DSP_REC_SAFEFTY_MARGIN 4096 - -void pollsb(void *p); -void sb_poll_i(void *p); - -static int sbe2dat[4][9] = { - { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, - { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, - { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, - { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } -}; - -static mpu_t *mpu; - -static int sb_commands[256]= -{ - -1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, - 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, - 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, - 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, - 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, - 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 -}; - -char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d}; - -/*These tables were 'borrowed' from DOSBox*/ - int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, - 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 - }; - uint8_t adjustMap4[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 - }; - - int8_t scaleMap26[40] = { - 0, 1, 2, 3, 0, -1, -2, -3, - 1, 3, 5, 7, -1, -3, -5, -7, - 2, 6, 10, 14, -2, -6, -10, -14, - 4, 12, 20, 28, -4, -12, -20, -28, - 5, 15, 25, 35, -5, -15, -25, -35 - }; - uint8_t adjustMap26[40] = { - 0, 0, 0, 8, 0, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 0, 248, 0, 0, 0 - }; - - int8_t scaleMap2[24] = { - 0, 1, 0, -1, 1, 3, -1, -3, - 2, 6, -2, -6, 4, 12, -4, -12, - 8, 24, -8, -24, 6, 48, -16, -48 - }; - uint8_t adjustMap2[24] = { - 0, 4, 0, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 0, 252, 0 - }; - -float low_fir_sb16_coef[SB16_NCoef]; - - -#ifdef ENABLE_SB_DSP_LOG -int sb_dsp_do_log = ENABLE_SB_DSP_LOG; -#endif - - -static void -sb_dsp_log(const char *fmt, ...) -{ -#ifdef ENABLE_SB_DSP_LOG - va_list ap; - - if (sb_dsp_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static inline double sinc(double x) -{ - return sin(M_PI * x) / (M_PI * x); -} - -static void recalc_sb16_filter(int playback_freq) -{ - /*Cutoff frequency = playback / 2*/ - float fC = ((float)playback_freq / 2.0) / 48000.0; - float gain; - int n; - - for (n = 0; n < SB16_NCoef; n++) - { - /*Blackman window*/ - double w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(SB16_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(SB16_NCoef-1))); - /*Sinc filter*/ - double h = sinc(2.0 * fC * ((double)n - ((double)(SB16_NCoef-1) / 2.0))); - - /*Create windowed-sinc filter*/ - low_fir_sb16_coef[n] = w * h; - } - - low_fir_sb16_coef[(SB16_NCoef - 1) / 2] = 1.0; - - gain = 0.0; - for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_sb16_coef[n]; - - /*Normalise filter, to produce unity gain*/ - for (n = 0; n < SB16_NCoef; n++) - low_fir_sb16_coef[n] /= gain; -} - - -void sb_irq(sb_dsp_t *dsp, int irq8) -{ - sb_dsp_log("IRQ %i %02X\n",irq8,pic.mask); - if (irq8) dsp->sb_irq8 = 1; - else dsp->sb_irq16 = 1; - picint(1 << dsp->sb_irqnum); -} -void sb_irqc(sb_dsp_t *dsp, int irq8) -{ - if (irq8) dsp->sb_irq8 = 0; - else dsp->sb_irq16 = 0; - picintc(1 << dsp->sb_irqnum); -} - -void sb_dsp_reset(sb_dsp_t *dsp) -{ - dsp->sbenable = dsp->sb_enable_i = 0; - dsp->sb_command = 0; - - dsp->sb_8_length = 0xffff; - dsp->sb_8_autolen = 0xffff; - - sb_irqc(dsp, 0); - sb_irqc(dsp, 1); - dsp->sb_16_pause = 0; - dsp->sb_read_wp = dsp->sb_read_rp = 0; - dsp->sb_data_stat = -1; - dsp->sb_speaker = 0; - dsp->sb_pausetime = -1LL; - dsp->sbe2 = 0xAA; - dsp->sbe2count = 0; - - dsp->sbreset = 0; - dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0; - - dsp->record_pos_read=0; - dsp->record_pos_write=SB_DSP_REC_SAFEFTY_MARGIN; - - picintc(1 << dsp->sb_irqnum); - - dsp->asp_data_len = 0; -} - -void sb_doreset(sb_dsp_t *dsp) -{ - int c; - - sb_dsp_reset(dsp); - - if (dsp->sb_type==SB16) sb_commands[8] = 1; - else sb_commands[8] = -1; - - for (c = 0; c < 256; c++) - dsp->sb_asp_regs[c] = 0; - dsp->sb_asp_regs[5] = 0x01; - dsp->sb_asp_regs[9] = 0xf8; -} - -void sb_dsp_speed_changed(sb_dsp_t *dsp) -{ - if (dsp->sb_timeo < 256LL) - dsp->sblatcho = TIMER_USEC * (256LL - dsp->sb_timeo); - else - dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256LL))); - - if (dsp->sb_timei < 256LL) - dsp->sblatchi = TIMER_USEC * (256LL - dsp->sb_timei); - else - dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256LL))); -} - -void sb_add_data(sb_dsp_t *dsp, uint8_t v) -{ - dsp->sb_read_data[dsp->sb_read_wp++] = v; - dsp->sb_read_wp &= 0xff; -} - -#define ADPCM_4 1 -#define ADPCM_26 2 -#define ADPCM_2 3 - -void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) -{ - dsp->sb_pausetime = -1LL; - if (dma8) - { - dsp->sb_8_length = len; - dsp->sb_8_format = format; - dsp->sb_8_autoinit = autoinit; - dsp->sb_8_pause = 0; - dsp->sb_8_enable = 1; - if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0; - dsp->sb_8_output = 1; - timer_process(); - dsp->sbenable = dsp->sb_8_enable; - timer_update_outstanding(); - dsp->sbleftright = 0; - dsp->sbdacpos = 0; - } - else - { - dsp->sb_16_length = len; - dsp->sb_16_format = format; - dsp->sb_16_autoinit = autoinit; - dsp->sb_16_pause = 0; - dsp->sb_16_enable = 1; - if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0; - dsp->sb_16_output = 1; - timer_process(); - dsp->sbenable = dsp->sb_16_enable; - timer_update_outstanding(); - } -} - -void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) -{ - if (dma8) - { - dsp->sb_8_length = len; - dsp->sb_8_format = format; - dsp->sb_8_autoinit = autoinit; - dsp->sb_8_pause = 0; - dsp->sb_8_enable = 1; - if (dsp->sb_16_enable && !dsp->sb_16_output) dsp->sb_16_enable = 0; - dsp->sb_8_output = 0; - timer_process(); - dsp->sb_enable_i = dsp->sb_8_enable; - timer_update_outstanding(); - } - else - { - dsp->sb_16_length = len; - dsp->sb_16_format = format; - dsp->sb_16_autoinit = autoinit; - dsp->sb_16_pause = 0; - dsp->sb_16_enable = 1; - if (dsp->sb_8_enable && !dsp->sb_8_output) dsp->sb_8_enable = 0; - dsp->sb_16_output = 0; - timer_process(); - dsp->sb_enable_i = dsp->sb_16_enable; - timer_update_outstanding(); - } - memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); -} - -int sb_8_read_dma(sb_dsp_t *dsp) -{ - return dma_channel_read(dsp->sb_8_dmanum); -} -void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) -{ - dma_channel_write(dsp->sb_8_dmanum, val); -} -int sb_16_read_dma(sb_dsp_t *dsp) -{ - return dma_channel_read(dsp->sb_16_dmanum); -} -int sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) -{ - int ret = dma_channel_write(dsp->sb_16_dmanum, val); - return (ret == DMA_NODATA); -} - -void sb_dsp_setirq(sb_dsp_t *dsp, int irq) -{ - dsp->sb_irqnum = irq; -} - -void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) -{ - dsp->sb_8_dmanum = dma; -} - -void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) -{ - dsp->sb_16_dmanum = dma; -} -void sb_exec_command(sb_dsp_t *dsp) -{ - int temp,c; - sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command); - switch (dsp->sb_command) - { - case 0x01: /*???*/ - if (dsp->sb_type < SB16) break; - dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; - break; - case 0x03: /*ASP status*/ - sb_add_data(dsp, 0); - break; - case 0x10: /*8-bit direct mode*/ - sb_dsp_update(dsp); - dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; - break; - case 0x14: /*8-bit single cycle DMA output*/ - sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x17: /*2-bit ADPCM output with reference*/ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - case 0x16: /*2-bit ADPCM output*/ - sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x17) - dsp->sb_8_length--; - break; - case 0x1C: /*8-bit autoinit DMA output*/ - if (dsp->sb_type < SB15) break; - sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x1F: /*2-bit ADPCM autoinit output*/ - if (dsp->sb_type < SB15) break; - sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - break; - case 0x20: /*8-bit direct input*/ - sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); - /*Due to the current implementation, I need to emulate a samplerate, even if this - * mode does not imply such samplerate. Position is increased in sb_poll_i*/ - if (dsp->sb_enable_i==0) - { - dsp->sb_timei = 256LL - 22LL; - dsp->sblatchi = TIMER_USEC * 22LL; - temp = 1000000 / 22; - dsp->sb_freq = temp; - timer_process(); - dsp->sb_enable_i = 1; - timer_update_outstanding(); - } - break; - case 0x24: /*8-bit single cycle DMA input*/ - sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x2C: /*8-bit autoinit DMA input*/ - if (dsp->sb_type < SB15) break; - sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x30: - case 0x31: - break; - case 0x34: - dsp->uart_midi = 1; - dsp->uart_irq = 0; - break; - case 0x35: - dsp->uart_midi = 1; - dsp->uart_irq = 1; - break; - case 0x36: - case 0x37: - break; - case 0x38: - dsp->onebyte_midi = 1; - break; - case 0x40: /*Set time constant*/ - dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; - dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); - temp = 256 - dsp->sb_data[0]; - temp = 1000000 / temp; - sb_dsp_log("Sample rate - %ihz (%i)\n",temp, dsp->sblatcho); - if (dsp->sb_freq != temp && dsp->sb_type >= SB16) - recalc_sb16_filter(temp); - dsp->sb_freq = temp; - break; - case 0x41: /*Set output sampling rate*/ - case 0x42: /*Set input sampling rate*/ - if (dsp->sb_type < SB16) break; - dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); - sb_dsp_log("Sample rate - %ihz (%i)\n",dsp->sb_data[1]+(dsp->sb_data[0]<<8), dsp->sblatcho); - temp = dsp->sb_freq; - dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); - dsp->sb_timeo = 256LL + dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho; - dsp->sb_timei = dsp->sb_timeo; - if (dsp->sb_freq != temp && dsp->sb_type >= SB16) - recalc_sb16_filter(dsp->sb_freq); - break; - case 0x48: /*Set DSP block transfer size*/ - dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); - break; - case 0x75: /*4-bit ADPCM output with reference*/ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - case 0x74: /*4-bit ADPCM output*/ - sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x75) - dsp->sb_8_length--; - break; - case 0x77: /*2.6-bit ADPCM output with reference*/ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - case 0x76: /*2.6-bit ADPCM output*/ - sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x77) - dsp->sb_8_length--; - break; - case 0x7D: /*4-bit ADPCM autoinit output*/ - if (dsp->sb_type < SB15) break; - sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - break; - case 0x7F: /*2.6-bit ADPCM autoinit output*/ - if (dsp->sb_type < SB15) break; - sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - break; - case 0x80: /*Pause DAC*/ - dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); - timer_process(); - dsp->sbenable = 1; - timer_update_outstanding(); - break; - case 0x90: /*High speed 8-bit autoinit DMA output*/ - if (dsp->sb_type < SB2) break; - sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x91: /*High speed 8-bit single cycle DMA output*/ - if (dsp->sb_type < SB2) break; - sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); - break; - case 0x98: /*High speed 8-bit autoinit DMA input*/ - if (dsp->sb_type < SB2) break; - sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x99: /*High speed 8-bit single cycle DMA input*/ - if (dsp->sb_type < SB2) break; - sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); - break; - case 0xA0: /*Set input mode to mono*/ - case 0xA8: /*Set input mode to stereo*/ - if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; - /* TODO: Implement. 3.xx-only command. */ - break; - case 0xB0: case 0xB1: case 0xB2: case 0xB3: - case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/ - if (dsp->sb_type < SB16) break; - sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - break; - case 0xB8: case 0xB9: case 0xBA: case 0xBB: - case 0xBC: case 0xBD: case 0xBE: case 0xBF: /*16-bit DMA input*/ - if (dsp->sb_type < SB16) break; - sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - break; - case 0xC0: case 0xC1: case 0xC2: case 0xC3: - case 0xC4: case 0xC5: case 0xC6: case 0xC7: /*8-bit DMA output*/ - if (dsp->sb_type < SB16) break; - sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - break; - case 0xC8: case 0xC9: case 0xCA: case 0xCB: - case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*8-bit DMA input*/ - if (dsp->sb_type < SB16) break; - sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - break; - case 0xD0: /*Pause 8-bit DMA*/ - dsp->sb_8_pause = 1; - break; - case 0xD1: /*Speaker on*/ - if (dsp->sb_type < SB15 ) - dsp->sb_8_pause = 1; - else if ( dsp->sb_type < SB16 ) - dsp->muted = 0; - dsp->sb_speaker = 1; - break; - case 0xD3: /*Speaker off*/ - if (dsp->sb_type < SB15 ) - dsp->sb_8_pause = 1; - else if ( dsp->sb_type < SB16 ) - dsp->muted = 1; - dsp->sb_speaker = 0; - break; - case 0xD4: /*Continue 8-bit DMA*/ - dsp->sb_8_pause = 0; - break; - case 0xD5: /*Pause 16-bit DMA*/ - if (dsp->sb_type < SB16) break; - dsp->sb_16_pause = 1; - break; - case 0xD6: /*Continue 16-bit DMA*/ - if (dsp->sb_type < SB16) break; - dsp->sb_16_pause = 0; - break; - case 0xD8: /*Get speaker status*/ - sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); - break; - case 0xD9: /*Exit 16-bit auto-init mode*/ - if (dsp->sb_type < SB16) break; - dsp->sb_16_autoinit = 0; - break; - case 0xDA: /*Exit 8-bit auto-init mode*/ - dsp->sb_8_autoinit = 0; - break; - case 0xE0: /*DSP identification*/ - sb_add_data(dsp, ~dsp->sb_data[0]); - break; - case 0xE1: /*Get DSP version*/ - sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8); - sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff); - break; - case 0xE2: /*Stupid ID/protection*/ - for (c = 0; c < 8; c++) - if (dsp->sb_data[0] & (1 << c)) dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][c]; - dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; - dsp->sbe2count++; - sb_8_write_dma(dsp, dsp->sbe2); - break; - case 0xE3: /*DSP copyright*/ - if (dsp->sb_type < SB16) break; - c = 0; - while (sb16_copyright[c]) - sb_add_data(dsp, sb16_copyright[c++]); - sb_add_data(dsp, 0); - break; - case 0xE4: /*Write test register*/ - dsp->sb_test = dsp->sb_data[0]; - break; - case 0xE8: /*Read test register*/ - sb_add_data(dsp, dsp->sb_test); - break; - case 0xF2: /*Trigger 8-bit IRQ*/ - sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 1); - break; - case 0xF3: /*Trigger 16-bit IRQ*/ - sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 0); - break; - case 0xE7: /*???*/ - case 0xFA: /*???*/ - break; - case 0x07: /*No, that's not how you program auto-init DMA*/ - case 0xFF: - break; - case 0x08: /*ASP get version*/ - if (dsp->sb_type < SB16) break; - sb_add_data(dsp, 0x18); - break; - case 0x0E: /*ASP set register*/ - if (dsp->sb_type < SB16) break; - dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; - break; - case 0x0F: /*ASP get register*/ - if (dsp->sb_type < SB16) break; - sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); - break; - case 0xF8: - if (dsp->sb_type >= SB16) break; - sb_add_data(dsp, 0); - break; - case 0xF9: - if (dsp->sb_type < SB16) break; - if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); - else if (dsp->sb_data[0] == 0x0f) sb_add_data(dsp, 0x07); - else if (dsp->sb_data[0] == 0x37) sb_add_data(dsp, 0x38); - else sb_add_data(dsp, 0x00); - case 0x04: - case 0x05: - break; - - /*TODO: Some more data about the DSP registeres - * http://the.earth.li/~tfm/oldpage/sb_dsp.html - * http://www.synchrondata.com/pheaven/www/area19.htm - * http://www.dcee.net/Files/Programm/Sound/ - 0E3h DSP Copyright SBPro2??? - 0F0h Sine Generator SB - 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 - 0F2h IRQ Request, 8-bit SB - 0F3h IRQ Request, 16-bit SB16 - 0FBh DSP Status SB16 - 0FCh DSP Auxiliary Status SB16 - 0FDh DSP Command Status SB16 - */ - - } -} - -void sb_write(uint16_t a, uint8_t v, void *priv) -{ - sb_dsp_t *dsp = (sb_dsp_t *)priv; - switch (a&0xF) - { - case 6: /*Reset*/ - if (!(v & 1) && (dsp->sbreset & 1)) - { - sb_dsp_reset(dsp); - sb_add_data(dsp, 0xAA); - } - dsp->sbreset = v; - return; - case 0xC: /*Command/data write*/ - if (dsp->uart_midi || dsp->onebyte_midi) - { - midi_write(v); - dsp->onebyte_midi = 0; - return; - } - timer_process(); - dsp->wb_time = TIMER_USEC * 1LL; - dsp->wb_full = 1LL; - timer_update_outstanding(); - if (dsp->asp_data_len) - { - sb_dsp_log("ASP data %i\n", dsp->asp_data_len); - dsp->asp_data_len--; - if (!dsp->asp_data_len) - sb_add_data(dsp, 0); - return; - } - if (dsp->sb_data_stat == -1) - { - dsp->sb_command = v; - if (v == 0x01) - sb_add_data(dsp, 0); - dsp->sb_data_stat++; - } - else - dsp->sb_data[dsp->sb_data_stat++] = v; - if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) - { - sb_exec_command(dsp); - dsp->sb_data_stat = -1; - } - break; - } -} - -uint8_t sb_read(uint16_t a, void *priv) -{ - sb_dsp_t *dsp = (sb_dsp_t *)priv; - switch (a & 0xf) - { - case 0xA: /*Read data*/ - if (dsp->uart_midi) - { - return MPU401_ReadData(mpu); - } - dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; - if (dsp->sb_read_rp != dsp->sb_read_wp) - { - dsp->sb_read_rp++; - dsp->sb_read_rp &= 0xFF; - } - return dsp->sbreaddat; - case 0xC: /*Write data ready*/ - if (dsp->sb_8_enable || dsp->sb_type >= SB16) - dsp->busy_count = (dsp->busy_count + 1) & 3; - else - dsp->busy_count = 0; - if (dsp->wb_full || (dsp->busy_count & 2)) - { - dsp->wb_full = dsp->wb_time; - return 0xff; - } - return 0x7f; - case 0xE: /*Read data ready*/ - picintc(1 << dsp->sb_irqnum); - dsp->sb_irq8 = dsp->sb_irq16 = 0; - return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; - case 0xF: /*16-bit ack*/ - dsp->sb_irq16 = 0; - if (!dsp->sb_irq8) picintc(1 << dsp->sb_irqnum); - return 0xff; - } - return 0; -} - -static void sb_wb_clear(void *p) -{ - sb_dsp_t *dsp = (sb_dsp_t *)p; - - dsp->wb_time = 0LL; -} - -void sb_dsp_set_mpu(mpu_t *src_mpu) -{ - mpu = src_mpu; -} - -void sb_dsp_init(sb_dsp_t *dsp, int type) -{ - dsp->sb_type = type; - - // Default values. Use sb_dsp_setxxx() methods to change. - dsp->sb_irqnum = 7; - dsp->sb_8_dmanum = 1; - dsp->sb_16_dmanum = 5; - - sb_doreset(dsp); - - timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp); - timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp); - timer_add(sb_wb_clear, &dsp->wb_time, &dsp->wb_time, dsp); - - /*Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when - a set frequency command is sent.*/ - recalc_sb16_filter(3200*2); -} - -void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) -{ - sb_dsp_log("sb_dsp_setaddr : %04X\n", addr); - if (dsp->sb_addr != 0) { - io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - } - dsp->sb_addr = addr; - if (dsp->sb_addr != 0) { - io_sethandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - } -} - -void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) -{ - dsp->stereo = stereo; -} - -void pollsb(void *p) -{ - sb_dsp_t *dsp = (sb_dsp_t *)p; - int tempi,ref; - - dsp->sbcount += dsp->sblatcho; - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) - { - int data[2]; - - sb_dsp_update(dsp); - switch (dsp->sb_8_format) - { - case 0x00: /*Mono unsigned*/ - data[0] = sb_8_read_dma(dsp); - /*Needed to prevent clicking in Worms, which programs the DSP to - auto-init DMA but programs the DMA controller to single cycle*/ - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = (data[0] ^ 0x80) << 8; - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) - { - if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; - else dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } - else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - break; - case 0x10: /*Mono signed*/ - data[0] = sb_8_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = data[0] << 8; - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) - { - if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; - else dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } - else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - break; - case 0x20: /*Stereo unsigned*/ - data[0] = sb_8_read_dma(dsp); - data[1] = sb_8_read_dma(dsp); - if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) - break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; - dsp->sb_8_length -= 2; - break; - case 0x30: /*Stereo signed*/ - data[0] = sb_8_read_dma(dsp); - data[1] = sb_8_read_dma(dsp); - if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) - break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; - dsp->sb_8_length -= 2; - break; - - case ADPCM_4: - if (dsp->sbdacpos) tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; - else tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; - if (tempi < 0) tempi = 0; - if (tempi > 63) tempi = 63; - - ref = dsp->sbref + scaleMap4[tempi]; - if (ref > 0xff) dsp->sbref = 0xff; - else if (ref < 0x00) dsp->sbref = 0x00; - else dsp->sbref = ref; - - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 2) - { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } - - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) - { - if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; - else dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } - else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; - - case ADPCM_26: - if (!dsp->sbdacpos) tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; - else if (dsp->sbdacpos == 1) tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; - else tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; - - if (tempi < 0) tempi = 0; - if (tempi > 39) tempi = 39; - - ref = dsp->sbref + scaleMap26[tempi]; - if (ref > 0xff) dsp->sbref = 0xff; - else if (ref < 0x00) dsp->sbref = 0x00; - else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos>=3) - { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } - - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) - { - if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; - else dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } - else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; - - case ADPCM_2: - tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; - if (tempi < 0) tempi = 0; - if (tempi > 23) tempi = 23; - - ref = dsp->sbref + scaleMap2[tempi]; - if (ref > 0xff) dsp->sbref = 0xff; - else if (ref < 0x00) dsp->sbref = 0x00; - else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 4) - { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - } - - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) - { - if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; - else dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } - else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; - -// default: - //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format); - } - - if (dsp->sb_8_length < 0) - { - if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; - else dsp->sb_8_enable = dsp->sbenable=0; - sb_irq(dsp, 1); - } - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0LL && dsp->sb_16_output) - { - int data[2]; - - sb_dsp_update(dsp); - - switch (dsp->sb_16_format) - { - case 0x00: /*Mono unsigned*/ - data[0] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; - dsp->sb_16_length--; - break; - case 0x10: /*Mono signed*/ - data[0] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdatl = dsp->sbdatr = data[0]; - dsp->sb_16_length--; - break; - case 0x20: /*Stereo unsigned*/ - data[0] = sb_16_read_dma(dsp); - data[1] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) - break; - dsp->sbdatl = data[0] ^ 0x8000; - dsp->sbdatr = data[1] ^ 0x8000; - dsp->sb_16_length -= 2; - break; - case 0x30: /*Stereo signed*/ - data[0] = sb_16_read_dma(dsp); - data[1] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) - break; - dsp->sbdatl = data[0]; - dsp->sbdatr = data[1]; - dsp->sb_16_length -= 2; - break; - } - - if (dsp->sb_16_length < 0) - { - sb_dsp_log("16DMA over %i\n",dsp->sb_16_autoinit); - if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; - else dsp->sb_16_enable = dsp->sbenable = 0; - sb_irq(dsp, 0); - } - } - if (dsp->sb_pausetime > -1LL) - { - dsp->sb_pausetime--; - if (dsp->sb_pausetime < 0LL) - { - sb_irq(dsp, 1); - dsp->sbenable = dsp->sb_8_enable; - sb_dsp_log("SB pause over\n"); - } - } -} - -void sb_poll_i(void *p) -{ - sb_dsp_t *dsp = (sb_dsp_t *)p; - int processed=0; - dsp->sb_count_i += dsp->sblatchi; - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) - { - switch (dsp->sb_8_format) - { - case 0x00: /*Mono unsigned As the manual says, only the left channel is recorded*/ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); - dsp->sb_8_length--; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x10: /*Mono signed As the manual says, only the left channel is recorded*/ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); - dsp->sb_8_length--; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x20: /*Stereo unsigned*/ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)^0x80); - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)^0x80); - dsp->sb_8_length -= 2; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x30: /*Stereo signed*/ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)); - dsp->sb_8_length -= 2; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - } - - if (dsp->sb_8_length < 0) - { - if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; - else dsp->sb_8_enable = dsp->sb_enable_i = 0; - sb_irq(dsp, 1); - } - processed=1; - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0LL && !dsp->sb_16_output) - { - switch (dsp->sb_16_format) - { - case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) - return; - dsp->sb_16_length--; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) - return; - dsp->sb_16_length--; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x20: /*Unsigned stereo*/ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) - return; - sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]^0x8000); - dsp->sb_16_length -= 2; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - case 0x30: /*Signed stereo*/ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) - return; - sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]); - dsp->sb_16_length -= 2; - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - break; - } - - if (dsp->sb_16_length < 0) - { - if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; - else dsp->sb_16_enable = dsp->sb_enable_i = 0; - sb_irq(dsp, 0); - } - processed=1; - } - /* Assume this is direct mode */ - if (!processed) - { - dsp->record_pos_read+=2; - dsp->record_pos_read&=0xFFFF; - } -} - -void sb_dsp_update(sb_dsp_t *dsp) -{ - if (dsp->muted) - { - dsp->sbdatl=0; - dsp->sbdatr=0; - } - for (; dsp->pos < sound_pos_global; dsp->pos++) - { - dsp->buffer[dsp->pos*2] = dsp->sbdatl; - dsp->buffer[dsp->pos*2 + 1] = dsp->sbdatr; - } -} - -void sb_dsp_close(sb_dsp_t *dsp) -{ -} diff --git a/src - Cópia/sound/snd_sb_dsp.h b/src - Cópia/sound/snd_sb_dsp.h deleted file mode 100644 index e4587c529..000000000 --- a/src - Cópia/sound/snd_sb_dsp.h +++ /dev/null @@ -1,90 +0,0 @@ -typedef struct sb_dsp_t -{ - int sb_type; - - int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; - int sb_8_dmanum; - int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; - int sb_16_dmanum; - int64_t sb_pausetime; - - uint8_t sb_read_data[256]; - int sb_read_wp, sb_read_rp; - int sb_speaker; - int muted; - - int sb_data_stat; - int uart_midi; - int uart_irq; - int onebyte_midi; - - int sb_irqnum; - - uint8_t sbe2; - int sbe2count; - - uint8_t sb_data[8]; - - int sb_freq; - - int16_t sbdat; - int sbdat2; - int16_t sbdatl, sbdatr; - - uint8_t sbref; - int8_t sbstep; - - int sbdacpos; - - int sbleftright; - - int sbreset; - uint8_t sbreaddat; - uint8_t sb_command; - uint8_t sb_test; - int64_t sb_timei, sb_timeo; - - int sb_irq8, sb_irq16; - - uint8_t sb_asp_regs[256]; - - int64_t sbenable, sb_enable_i; - - int64_t sbcount, sb_count_i; - - int64_t sblatcho, sblatchi; - - uint16_t sb_addr; - - int stereo; - - int asp_data_len; - - int64_t wb_time, wb_full; - - int busy_count; - - int record_pos_read; - int record_pos_write; - int16_t record_buffer[0xFFFF]; - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; -} sb_dsp_t; - -void sb_dsp_set_mpu(mpu_t *src_mpu); - -void sb_dsp_init(sb_dsp_t *dsp, int type); -void sb_dsp_close(sb_dsp_t *dsp); - -void sb_dsp_setirq(sb_dsp_t *dsp, int irq); -void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); -void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); -void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); - -void sb_dsp_speed_changed(sb_dsp_t *dsp); - -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); diff --git a/src - Cópia/sound/snd_sn76489.c b/src - Cópia/sound/snd_sn76489.c deleted file mode 100644 index 0f1b64ac1..000000000 --- a/src - Cópia/sound/snd_sn76489.c +++ /dev/null @@ -1,253 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../device.h" -#include "sound.h" -#include "snd_sn76489.h" - - -int sn76489_mute; - - -static float volslog[16]= -{ - 0.00000f,0.59715f,0.75180f,0.94650f, - 1.19145f,1.50000f,1.88835f,2.37735f, - 2.99295f,3.76785f,4.74345f,5.97165f, - 7.51785f,9.46440f,11.9194f,15.0000f -}; - -void sn76489_update(sn76489_t *sn76489) -{ - for (; sn76489->pos < sound_pos_global; sn76489->pos++) - { - int c; - int16_t result = 0; - - for (c = 1; c < 4; c++) - { - if (sn76489->latch[c] > 256) result += (int16_t) (volslog[sn76489->vol[c]] * sn76489->stat[c]); - else result += (int16_t) (volslog[sn76489->vol[c]] * 127); - - sn76489->count[c] -= (256 * sn76489->psgconst); - while ((int)sn76489->count[c] < 0) - { - sn76489->count[c] += sn76489->latch[c]; - sn76489->stat[c] = -sn76489->stat[c]; - } - } - result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); - - sn76489->count[0] -= (512 * sn76489->psgconst); - while ((int)sn76489->count[0] < 0 && sn76489->latch[0]) - { - sn76489->count[0] += (sn76489->latch[0] * 4); - if (!(sn76489->noise & 4)) - { - if (sn76489->shift & 1) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; - } - else - { - if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; - } - } - - sn76489->buffer[sn76489->pos] = result; - } -} - -void sn76489_get_buffer(int32_t *buffer, int len, void *p) -{ - sn76489_t *sn76489 = (sn76489_t *)p; - - int c; - - sn76489_update(sn76489); - - if (!sn76489_mute) - { - for (c = 0; c < len * 2; c++) - buffer[c] += sn76489->buffer[c >> 1]; - } - - sn76489->pos = 0; -} - -void sn76489_write(uint16_t addr, uint8_t data, void *p) -{ - sn76489_t *sn76489 = (sn76489_t *)p; - int freq; - - sn76489_update(sn76489); - - if (data & 0x80) - { - sn76489->firstdat = data; - switch (data & 0x70) - { - case 0: - sn76489->freqlo[3] = data & 0xf; - sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[3] &= 0x3ff; - if (!sn76489->latch[3]) - sn76489->latch[3] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 3; - break; - case 0x10: - data &= 0xf; - sn76489->vol[3] = 0xf - data; - break; - case 0x20: - sn76489->freqlo[2] = data & 0xf; - sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[2] &= 0x3ff; - if (!sn76489->latch[2]) - sn76489->latch[2] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 2; - break; - case 0x30: - data &= 0xf; - sn76489->vol[2] = 0xf - data; - break; - case 0x40: - sn76489->freqlo[1] = data & 0xf; - sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[1] &= 0x3ff; - if (!sn76489->latch[1]) - sn76489->latch[1] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 1; - break; - case 0x50: - data &= 0xf; - sn76489->vol[1] = 0xf - data; - break; - case 0x60: - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; - sn76489->noise = data & 0xf; - if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; - else sn76489->latch[0] = 0x400 << (data & 3); - if (sn76489->extra_divide) - sn76489->latch[0] &= 0x3ff; - if (!sn76489->latch[0]) - sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; - break; - case 0x70: - data &= 0xf; - sn76489->vol[0] = 0xf - data; - break; - } - } - else - { - if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) - { - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; - sn76489->noise = data & 0xf; - if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; - else sn76489->latch[0] = 0x400 << (data & 3); - if (!sn76489->latch[0]) - sn76489->latch[0] = 1024 << 6; - } - else if ((sn76489->firstdat & 0x70) != 0x60) - { - sn76489->freqhi[sn76489->lasttone] = data & 0x7F; - freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); - if (sn76489->extra_divide) - freq &= 0x3ff; - if (!freq) - freq = sn76489->extra_divide ? 2048 : 1024; - if ((sn76489->noise & 3) == 3 && sn76489->lasttone == 1) - sn76489->latch[0] = freq << 6; - sn76489->latch[sn76489->lasttone] = freq << 6; - } - } -} - -void sn74689_set_extra_divide(sn76489_t *sn76489, int enable) -{ - sn76489->extra_divide = enable; -} - -void sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int freq) -{ - sound_add_handler(sn76489_get_buffer, sn76489); - - sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6; - sn76489->vol[0] = 0; - sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; - sn76489->stat[0] = sn76489->stat[1] = sn76489->stat[2] = sn76489->stat[3] = 127; - srand(time(NULL)); - sn76489->count[0] = 0; - sn76489->count[1] = (rand()&0x3FF)<<6; - sn76489->count[2] = (rand()&0x3FF)<<6; - sn76489->count[3] = (rand()&0x3FF)<<6; - sn76489->noise = 3; - sn76489->shift = 0x4000; - sn76489->type = type; - sn76489->psgconst = (((double)freq / 64.0) / 48000.0); - - sn76489_mute = 0; - - io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); -} - -void *sn76489_device_init(const device_t *info) -{ - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); - - sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); - - return sn76489; -} -void *ncr8496_device_init(const device_t *info) -{ - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); - - sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); - - return sn76489; -} - -void sn76489_device_close(void *p) -{ - sn76489_t *sn76489 = (sn76489_t *)p; - - free(sn76489); -} - -const device_t sn76489_device = -{ - "TI SN74689 PSG", - 0, - 0, - sn76489_device_init, - sn76489_device_close, - NULL, NULL, NULL, - NULL -}; -const device_t ncr8496_device = -{ - "NCR8496 PSG", - 0, - 0, - ncr8496_device_init, - sn76489_device_close, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_sn76489.h b/src - Cópia/sound/snd_sn76489.h deleted file mode 100644 index 01d19e0e5..000000000 --- a/src - Cópia/sound/snd_sn76489.h +++ /dev/null @@ -1,33 +0,0 @@ -enum -{ - SN76496, - NCR8496, - PSSJ -}; - -extern const device_t sn76489_device; -extern const device_t ncr8496_device; - -extern int sn76489_mute; - -typedef struct sn76489_t -{ - int stat[4]; - int latch[4], count[4]; - int freqlo[4], freqhi[4]; - int vol[4]; - uint32_t shift; - uint8_t noise; - int lasttone; - uint8_t firstdat; - int type; - int extra_divide; - - int16_t buffer[SOUNDBUFLEN]; - int pos; - - double psgconst; -} sn76489_t; - -void sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int freq); -void sn74689_set_extra_divide(sn76489_t *sn76489, int enable); diff --git a/src - Cópia/sound/snd_speaker.c b/src - Cópia/sound/snd_speaker.c deleted file mode 100644 index 5defaa2c1..000000000 --- a/src - Cópia/sound/snd_speaker.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "../pit.h" -#include "sound.h" -#include "snd_speaker.h" - - -int speaker_mute = 0; -int speaker_gated = 0; -int speaker_enable = 0, was_speaker_enable = 0; - - -int gated,speakval,speakon; - - -static int16_t speaker_buffer[SOUNDBUFLEN]; -static int speaker_pos = 0; - - -void speaker_update(void) -{ - int16_t val; - - for (; speaker_pos < sound_pos_global; speaker_pos++) - { - if (speaker_gated && was_speaker_enable) - { - if (!pit.m[2] || pit.m[2]==4) - val = speakval; - else if (pit.l[2] < 0x40) - val = 0xa00; - else - val = speakon ? 0x1400 : 0; - } - else - val = was_speaker_enable ? 0x1400 : 0; - - if (!speaker_enable) - was_speaker_enable = 0; - - speaker_buffer[speaker_pos] = val; - } -} - -static void speaker_get_buffer(int32_t *buffer, int len, void *p) -{ - int c; - - speaker_update(); - - if (!speaker_mute) - { - for (c = 0; c < len * 2; c++) - buffer[c] += speaker_buffer[c >> 1]; - } - - speaker_pos = 0; -} - - -void speaker_init(void) -{ - sound_add_handler(speaker_get_buffer, NULL); - speaker_mute = 0; -} diff --git a/src - Cópia/sound/snd_speaker.h b/src - Cópia/sound/snd_speaker.h deleted file mode 100644 index 409a7c4e6..000000000 --- a/src - Cópia/sound/snd_speaker.h +++ /dev/null @@ -1,8 +0,0 @@ -void speaker_init(); - -extern int speaker_mute; - -extern int speaker_gated; -extern int speaker_enable, was_speaker_enable; - -void speaker_update(); diff --git a/src - Cópia/sound/snd_ssi2001.c b/src - Cópia/sound/snd_ssi2001.c deleted file mode 100644 index e20a08333..000000000 --- a/src - Cópia/sound/snd_ssi2001.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" -#include "sound.h" -#include "snd_resid.h" -#include "snd_ssi2001.h" - - -typedef struct ssi2001_t -{ - void *psid; - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; -} ssi2001_t; - -static void ssi2001_update(ssi2001_t *ssi2001) -{ - if (ssi2001->pos >= sound_pos_global) - return; - - sid_fillbuf(&ssi2001->buffer[ssi2001->pos], sound_pos_global - ssi2001->pos, ssi2001->psid); - ssi2001->pos = sound_pos_global; -} - -static void ssi2001_get_buffer(int32_t *buffer, int len, void *p) -{ - ssi2001_t *ssi2001 = (ssi2001_t *)p; - int c; - - ssi2001_update(ssi2001); - - for (c = 0; c < len * 2; c++) - buffer[c] += ssi2001->buffer[c >> 1] / 2; - - ssi2001->pos = 0; -} - -static uint8_t ssi2001_read(uint16_t addr, void *p) -{ - ssi2001_t *ssi2001 = (ssi2001_t *)p; - - ssi2001_update(ssi2001); - - return sid_read(addr, p); -} - -static void ssi2001_write(uint16_t addr, uint8_t val, void *p) -{ - ssi2001_t *ssi2001 = (ssi2001_t *)p; - - ssi2001_update(ssi2001); - sid_write(addr, val, p); -} - -void *ssi2001_init(const device_t *info) -{ - ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); - memset(ssi2001, 0, sizeof(ssi2001_t)); - - ssi2001->psid = sid_init(); - sid_reset(ssi2001->psid); - io_sethandler(0x0280, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001); - sound_add_handler(ssi2001_get_buffer, ssi2001); - return ssi2001; -} - -void ssi2001_close(void *p) -{ - ssi2001_t *ssi2001 = (ssi2001_t *)p; - - sid_close(ssi2001->psid); - - free(ssi2001); -} - -const device_t ssi2001_device = -{ - "Innovation SSI-2001", - 0, 0, - ssi2001_init, ssi2001_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_ssi2001.h b/src - Cópia/sound/snd_ssi2001.h deleted file mode 100644 index 83af6838a..000000000 --- a/src - Cópia/sound/snd_ssi2001.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t ssi2001_device; diff --git a/src - Cópia/sound/snd_wss.c b/src - Cópia/sound/snd_wss.c deleted file mode 100644 index 14725b5af..000000000 --- a/src - Cópia/sound/snd_wss.c +++ /dev/null @@ -1,124 +0,0 @@ -/*PCem v0.8 by Tom Walker - - Windows Sound System emulation*/ - -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.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*/ -/*530, 11, 1 - 530=22*/ -/*530, 11, 0 - 530=21*/ -/*530, 10, 1 - 530=1a*/ -/*530, 9, 1 - 530=12*/ -/*530, 7, 1 - 530=0a*/ -/*604, 11, 1 - 530=22*/ -/*e80, 11, 1 - 530=22*/ -/*f40, 11, 1 - 530=22*/ - - -static int wss_dma[4] = {0, 0, 1, 3}; -static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/ - - -typedef struct wss_t -{ - uint8_t config; - - ad1848_t ad1848; - opl_t opl; -} wss_t; - -uint8_t wss_read(uint16_t addr, void *p) -{ - wss_t *wss = (wss_t *)p; - uint8_t temp; - temp = 4 | (wss->config & 0x40); - return temp; -} - -void wss_write(uint16_t addr, uint8_t val, void *p) -{ - wss_t *wss = (wss_t *)p; - - wss->config = val; - ad1848_setdma(&wss->ad1848, wss_dma[val & 3]); - ad1848_setirq(&wss->ad1848, wss_irq[(val >> 3) & 7]); -} - -static void wss_get_buffer(int32_t *buffer, int len, void *p) -{ - wss_t *wss = (wss_t *)p; - - int c; - - opl3_update2(&wss->opl); - ad1848_update(&wss->ad1848); - for (c = 0; c < len * 2; c++) - { - buffer[c] += wss->opl.buffer[c]; - buffer[c] += (wss->ad1848.buffer[c] / 2); - } - - wss->opl.pos = 0; - wss->ad1848.pos = 0; -} - -void *wss_init(const device_t *info) -{ - wss_t *wss = malloc(sizeof(wss_t)); - - memset(wss, 0, sizeof(wss_t)); - - opl3_init(&wss->opl); - ad1848_init(&wss->ad1848); - - ad1848_setirq(&wss->ad1848, 7); - ad1848_setdma(&wss->ad1848, 3); - - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl); - io_sethandler(0x0530, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss); - io_sethandler(0x0534, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848); - - sound_add_handler(wss_get_buffer, wss); - - return wss; -} - -void wss_close(void *p) -{ - wss_t *wss = (wss_t *)p; - - free(wss); -} - -void wss_speed_changed(void *p) -{ - wss_t *wss = (wss_t *)p; - - ad1848_speed_changed(&wss->ad1848); -} - -const device_t wss_device = -{ - "Windows Sound System", - DEVICE_ISA, 0, - wss_init, wss_close, NULL, - NULL, - wss_speed_changed, - NULL, - NULL -}; diff --git a/src - Cópia/sound/snd_wss.h b/src - Cópia/sound/snd_wss.h deleted file mode 100644 index 0836e5808..000000000 --- a/src - Cópia/sound/snd_wss.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t wss_device; diff --git a/src - Cópia/sound/snd_ym7128.c b/src - Cópia/sound/snd_ym7128.c deleted file mode 100644 index c255295c6..000000000 --- a/src - Cópia/sound/snd_ym7128.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include "../86box.h" -#include "snd_ym7128.h" - - -static int attenuation[32]; -static int tap_position[32]; - - -void ym7128_init(ym7128_t *ym7128) -{ - int c; - double out = 65536.0; - - for (c = 0; c < 32; c++) - tap_position[c] = c * (2400 / 31); - - for (c = 31; c >= 1; c--) - { - attenuation[c] = (int)out; - out /= 1.25963; /*2 dB steps*/ - } - attenuation[0] = 0; -} - -#define GET_ATTENUATION(val) (val & 0x20) ? -attenuation[val & 0x1f] : attenuation[val & 0x1f] - -void ym7128_write(ym7128_t *ym7128, uint8_t val) -{ - int new_dat = val & 1; - int new_sci = val & 2; - int new_a0 = val & 4; - if (!ym7128->sci && new_sci) - ym7128->dat = (ym7128->dat << 1) | new_dat; - - if (ym7128->a0 != new_a0) - { - if (!ym7128->a0) - ym7128->reg_sel = ym7128->dat & 0x1f; - else - { - switch (ym7128->reg_sel) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - ym7128->gl[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - ym7128->gr[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); - break; - - case 0x10: - ym7128->vm = GET_ATTENUATION(ym7128->dat); - break; - case 0x11: - ym7128->vc = GET_ATTENUATION(ym7128->dat); - break; - case 0x12: - ym7128->vl = GET_ATTENUATION(ym7128->dat); - break; - case 0x13: - ym7128->vr = GET_ATTENUATION(ym7128->dat); - break; - - case 0x14: - ym7128->c0 = (ym7128->dat & 0x3f) << 6; - if (ym7128->dat & 0x20) - ym7128->c0 |= 0xfffff000; - break; - case 0x15: - ym7128->c1 = (ym7128->dat & 0x3f) << 6; - if (ym7128->dat & 0x20) - ym7128->c1 |= 0xfffff000; - break; - - case 0x16: case 0x17: case 0x18: case 0x19: - case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: - ym7128->t[ym7128->reg_sel - 0x16] = tap_position[ym7128->dat & 0x1f]; - break; - } - ym7128->regs[ym7128->reg_sel] = ym7128->dat; - } - ym7128->dat = 0; - } - - ym7128->sci = new_sci; - ym7128->a0 = new_a0; -} - -#define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos - offset) < 0) ? ym7128->delay_buffer[(ym7128->delay_pos - offset) + 2400] : ym7128->delay_buffer[ym7128->delay_pos - offset]) - -void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) -{ - int c, d; - - for (c = 0; c < len*2; c += 4) - { - /*YM7128 samples a mono stream at ~24 kHz, so downsample*/ - int32_t samp = ((int32_t)buffer[c] + (int32_t)buffer[c+1] + (int32_t)buffer[c+2] + (int32_t)buffer[c+3]) / 4; - int32_t filter_temp, filter_out; - int32_t samp_l = 0, samp_r = 0; - - filter_temp = GET_DELAY_SAMPLE(ym7128, ym7128->t[0]); - filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat * ym7128->c1) >> 11); - filter_out = (filter_out * ym7128->vc) >> 16; - - samp = (samp * ym7128->vm) >> 16; - samp += filter_out; - - ym7128->delay_buffer[ym7128->delay_pos] = samp; - - for (d = 0; d < 8; d++) - { - samp_l += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d+1]) * ym7128->gl[d]) >> 16; - samp_r += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d+1]) * ym7128->gr[d]) >> 16; - } - - samp_l = (samp_l * ym7128->vl*2) >> 16; - samp_r = (samp_r * ym7128->vr*2) >> 16; - - buffer[c] += ((int32_t)samp_l + (int32_t)ym7128->prev_l) / 2; - buffer[c+1] += ((int32_t)samp_r + (int32_t)ym7128->prev_r) / 2; - buffer[c+2] += samp_l; - buffer[c+3] += samp_r; - - ym7128->delay_pos++; - if (ym7128->delay_pos >= 2400) - ym7128->delay_pos = 0; - - ym7128->filter_dat = filter_temp; - ym7128->prev_l = samp_l; - ym7128->prev_r = samp_r; - } -} diff --git a/src - Cópia/sound/snd_ym7128.h b/src - Cópia/sound/snd_ym7128.h deleted file mode 100644 index f71aa2f86..000000000 --- a/src - Cópia/sound/snd_ym7128.h +++ /dev/null @@ -1,25 +0,0 @@ -typedef struct ym7128_t -{ - int a0, sci; - uint8_t dat; - - int reg_sel; - uint8_t regs[32]; - - int gl[8], gr[8]; - int vm, vc, vl, vr; - int c0, c1; - int t[9]; - - int16_t filter_dat; - int16_t prev_l, prev_r; - - int16_t delay_buffer[2400]; - int delay_pos; - - int16_t last_samp; -} ym7128_t; - -void ym7128_init(ym7128_t *ym7128); -void ym7128_write(ym7128_t *ym7128, uint8_t val); -void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len); diff --git a/src - Cópia/sound/sound.c b/src - Cópia/sound/sound.c deleted file mode 100644 index 75145468e..000000000 --- a/src - Cópia/sound/sound.c +++ /dev/null @@ -1,573 +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 emulation core. - * - * Version: @(#)sound.c 1.0.17 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../scsi/scsi.h" -#include "../cdrom/cdrom.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" - - -typedef struct { - const char *name; - const char *internal_name; - const device_t *device; -} SOUND_CARD; - -typedef struct { - void (*get_buffer)(int32_t *buffer, int len, void *p); - void *priv; -} sound_handler_t; - - -int sound_card_current = 0; -int sound_pos_global = 0; -volatile int soundon = 1; -int sound_gain = 0; - - -static int sound_card_last = 0; -static sound_handler_t sound_handlers[8]; -static sound_handler_t sound_process_handlers[8]; -static int sound_handlers_num; -static int sound_process_handlers_num; -static int64_t sound_poll_time = 0LL, sound_poll_latch; -static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; -static float cd_out_buffer[CD_BUFLEN * 2]; -static int16_t cd_out_buffer_int16[CD_BUFLEN * 2]; -static thread_t *sound_cd_thread_h; -static event_t *sound_cd_event; -static event_t *sound_cd_start_event; -static unsigned int cd_vol_l, cd_vol_r; -static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; -static volatile int cdaudioon = 0; - - -static const SOUND_CARD sound_cards[] = -{ - { "None", "none", NULL }, - { "[ISA] Adlib", "adlib", &adlib_device }, - { "[ISA] Adlib Gold", "adlibgold",&adgold_device }, - { "[ISA] Sound Blaster 1.0", "sb", &sb_1_device }, - { "[ISA] Sound Blaster 1.5", "sb1.5", &sb_15_device }, - { "[ISA] Sound Blaster 2.0", "sb2.0", &sb_2_device }, - { "[ISA] Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device }, - { "[ISA] Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device }, - { "[ISA] Sound Blaster 16", "sb16", &sb_16_device }, - { "[ISA] Sound Blaster AWE32", "sbawe32", &sb_awe32_device }, -#if defined(DEV_BRANCH) && defined(USE_PAS16) - { "[ISA] Pro Audio Spectrum 16","pas16", &pas16_device }, -#endif - { "[ISA] Windows Sound System", "wss", &wss_device }, - { "[MCA] Adlib", "adlib_mca", &adlib_mca_device }, - { "[MCA] Sound Blaster MCV", "sbmcv", &sb_mcv_device }, - { "[MCA] Sound Blaster Pro MCV","sbpromcv", &sb_pro_mcv_device }, - { "[PCI] Ensoniq AudioPCI (ES1371)","es1371", &es1371_device}, - { "[PCI] Sound Blaster PCI 128", "sbpci128", &es1371_device}, - { "", "", NULL } -}; - - -#ifdef ENABLE_SOUND_LOG -int sound_do_log = ENABLE_SOUND_LOG; -#endif - - -static void -sound_log(const char *fmt, ...) -{ -#ifdef ENABLE_SOUND_LOG - va_list ap; - - if (sound_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -int sound_card_available(int card) -{ - if (sound_cards[card].device) - return device_available(sound_cards[card].device); - - return 1; -} - -char *sound_card_getname(int card) -{ - return (char *) sound_cards[card].name; -} - -const device_t *sound_card_getdevice(int card) -{ - return sound_cards[card].device; -} - -int sound_card_has_config(int card) -{ - if (!sound_cards[card].device) - return 0; - return sound_cards[card].device->config ? 1 : 0; -} - -char *sound_card_get_internal_name(int card) -{ - return (char *) sound_cards[card].internal_name; -} - -int sound_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen((char *) sound_cards[c].internal_name)) - { - if (!strcmp((char *) sound_cards[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -void sound_card_init(void) -{ - if (sound_cards[sound_card_current].device) - device_add(sound_cards[sound_card_current].device); - sound_card_last = sound_card_current; -} - -void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) -{ - cd_vol_l = vol_l; - cd_vol_r = vol_r; -} - -static void sound_cd_thread(void *param) -{ - int i = 0; - - float cd_buffer_temp[2] = {0.0, 0.0}; - float cd_buffer_temp2[2] = {0.0, 0.0}; - - int32_t cd_buffer_temp4[2] = {0, 0}; - - int c, has_audio; - int d, r; - - thread_set_event(sound_cd_start_event); - - while (cdaudioon) - { - thread_wait_event(sound_cd_event, -1); - thread_reset_event(sound_cd_event); - if (!soundon || !cdaudioon) - return; - for (c = 0; c < CD_BUFLEN*2; c += 2) - { - if (sound_is_float) - { - cd_out_buffer[c] = 0.0; - cd_out_buffer[c+1] = 0.0; - } - else - { - cd_out_buffer_int16[c] = 0; - cd_out_buffer_int16[c+1] = 0; - } - } - for (i = 0; i < CDROM_NUM; i++) - { - has_audio = 0; - if ((cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) || !cdrom[i] || !cdrom[i]->handler) - continue; - if (cdrom[i]->handler->audio_callback) - { - r = cdrom[i]->handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2); - has_audio = (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on/* && r*/); - } else - continue; - if (soundon && has_audio) - { - int32_t audio_vol_l = cdrom_mode_sense_get_volume(cdrom[i], 0); - int32_t audio_vol_r = cdrom_mode_sense_get_volume(cdrom[i], 1); - int channel_select[2]; - - channel_select[0] = cdrom_mode_sense_get_channel(cdrom[i], 0); - channel_select[1] = cdrom_mode_sense_get_channel(cdrom[i], 1); - - if (!r) - { - for (c = 0; c < CD_BUFLEN*2; c += 2) - { - if (sound_is_float) - { - cd_out_buffer[c] += 0.0; - cd_out_buffer[c+1] += 0.0; - } - else - { - cd_out_buffer_int16[c] += 0; - cd_out_buffer_int16[c+1] += 0; - } - } - continue; - } - - for (c = 0; c < CD_BUFLEN*2; c += 2) - { - /* First, transfer the CD audio data to the temporary buffer. */ - cd_buffer_temp[0] = (float) cd_buffer[i][c]; - cd_buffer_temp[1] = (float) cd_buffer[i][c+1]; - - /* Then, adjust input from drive according to ATAPI/SCSI volume. */ - cd_buffer_temp[0] *= (float) audio_vol_l; - cd_buffer_temp[0] /= 511.0; - cd_buffer_temp[1] *= (float) audio_vol_r; - cd_buffer_temp[1] /= 511.0; - - /*Apply ATAPI channel select*/ - cd_buffer_temp2[0] = cd_buffer_temp2[1] = 0.0; - if (channel_select[0] & 1) - { - cd_buffer_temp2[0] += cd_buffer_temp[0]; - } - if (channel_select[0] & 2) - { - cd_buffer_temp2[1] += cd_buffer_temp[0]; - } - if (channel_select[1] & 1) - { - cd_buffer_temp2[0] += cd_buffer_temp[1]; - } - if (channel_select[1] & 2) - { - cd_buffer_temp2[1] += cd_buffer_temp[1]; - } - - if (sound_process_handlers_num) - { - cd_buffer_temp4[0] = (int32_t) cd_buffer_temp2[0]; - cd_buffer_temp4[1] = (int32_t) cd_buffer_temp2[1]; - - for (d = 0; d < sound_process_handlers_num; d++) - sound_process_handlers[d].get_buffer(cd_buffer_temp4, 1, sound_process_handlers[d].priv); - - cd_buffer_temp2[0] = (float) cd_buffer_temp4[0]; - cd_buffer_temp2[1] = (float) cd_buffer_temp4[1]; - } - else - { - /*Apply sound card CD volume*/ - cd_buffer_temp2[0] *= (float) cd_vol_l; - cd_buffer_temp2[0] /= 65535.0; - - cd_buffer_temp2[1] *= (float) cd_vol_r; - cd_buffer_temp2[1] /= 65535.0; - } - - if (sound_is_float) - { - cd_out_buffer[c] += (cd_buffer_temp2[0] / 32768.0); - cd_out_buffer[c+1] += (cd_buffer_temp2[1] / 32768.0); - } - else - { - if (cd_buffer_temp2[0] > 32767) - cd_buffer_temp2[0] = 32767; - if (cd_buffer_temp2[0] < -32768) - cd_buffer_temp2[0] = -32768; - if (cd_buffer_temp2[1] > 32767) - cd_buffer_temp2[1] = 32767; - if (cd_buffer_temp2[1] < -32768) - cd_buffer_temp2[1] = -32768; - - cd_out_buffer_int16[c] += cd_buffer_temp2[0]; - cd_out_buffer_int16[c+1] += cd_buffer_temp2[1]; - } - } - } - } - if (sound_is_float) - givealbuffer_cd(cd_out_buffer); - else - givealbuffer_cd(cd_out_buffer_int16); - } -} - -static int32_t *outbuffer; -static float *outbuffer_ex; -static int16_t *outbuffer_ex_int16; - -static int cd_thread_enable = 0; - -static void sound_realloc_buffers(void) -{ - if (outbuffer_ex != NULL) - { - free(outbuffer_ex); - } - - if (outbuffer_ex_int16 != NULL) - { - free(outbuffer_ex_int16); - } - - if (sound_is_float) - { - outbuffer_ex = malloc(SOUNDBUFLEN * 2 * sizeof(float)); - } - else - { - outbuffer_ex_int16 = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t)); - } -} - -void sound_init(void) -{ - int i = 0; - int available_cdrom_drives = 0; - - outbuffer_ex = NULL; - outbuffer_ex_int16 = NULL; - - outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int32_t)); - - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) - { - available_cdrom_drives++; - } - } - - if (available_cdrom_drives) - { - cdaudioon = 1; - - sound_cd_start_event = thread_create_event(); - - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); - - sound_log("Waiting for CD start event...\n"); - thread_wait_event(sound_cd_start_event, -1); - thread_reset_event(sound_cd_start_event); - sound_log("Done!\n"); - } - else - cdaudioon = 0; - - cd_thread_enable = available_cdrom_drives ? 1 : 0; -} - -void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) -{ - sound_handlers[sound_handlers_num].get_buffer = get_buffer; - sound_handlers[sound_handlers_num].priv = p; - sound_handlers_num++; -} - -void sound_add_process_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) -{ - sound_process_handlers[sound_process_handlers_num].get_buffer = get_buffer; - sound_process_handlers[sound_process_handlers_num].priv = p; - sound_process_handlers_num++; -} - -void sound_poll(void *priv) -{ - sound_poll_time += sound_poll_latch; - - midi_poll(); - - sound_pos_global++; - if (sound_pos_global == SOUNDBUFLEN) - { - int c; - - memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int32_t)); - - for (c = 0; c < sound_handlers_num; c++) - sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); - - - for (c = 0; c < SOUNDBUFLEN * 2; c++) - { - if (sound_is_float) - { - outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; - } - else - { - if (outbuffer[c] > 32767) - outbuffer[c] = 32767; - if (outbuffer[c] < -32768) - outbuffer[c] = -32768; - - outbuffer_ex_int16[c] = outbuffer[c]; - } - } - - if (soundon) - { - if (sound_is_float) - { - givealbuffer(outbuffer_ex); - } - else - { - givealbuffer(outbuffer_ex_int16); - } - } - - if (cd_thread_enable) - { - cd_buf_update--; - if (!cd_buf_update) - { - cd_buf_update = (48000 / SOUNDBUFLEN) / (CD_FREQ / CD_BUFLEN); - thread_set_event(sound_cd_event); - } - } - - sound_pos_global = 0; - } -} - -void sound_speed_changed(void) -{ - sound_poll_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); -} - -void sound_reset(void) -{ - sound_realloc_buffers(); - - midi_device_init(); - inital(); - - timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); - - sound_handlers_num = 0; - sound_process_handlers_num = 0; - - sound_set_cd_volume(65535, 65535); -} - -void sound_card_reset(void) -{ - sound_card_init(); - if (mpu401_standalone_enable) - mpu401_device_add(); - if (GUS) - device_add(&gus_device); - if (GAMEBLASTER) - device_add(&cms_device); - if (SSI2001) - device_add(&ssi2001_device); -} - -void sound_cd_thread_end(void) -{ - if (cdaudioon) { - cdaudioon = 0; - - sound_log("Waiting for CD Audio thread to terminate...\n"); - thread_set_event(sound_cd_event); - thread_wait(sound_cd_thread_h, -1); - sound_log("CD Audio thread terminated...\n"); - - if (sound_cd_event) { - thread_destroy_event(sound_cd_event); - sound_cd_event = NULL; - } - - sound_cd_thread_h = NULL; - - if (sound_cd_start_event) { - thread_destroy_event(sound_cd_start_event); - sound_cd_event = NULL; - } - } -} - -void sound_cd_thread_reset(void) -{ - int i = 0; - int available_cdrom_drives = 0; - - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom[i] && cdrom[i]->handler && cdrom[i]->handler->audio_stop) - { - cdrom[i]->handler->audio_stop(i); - } - - if ((cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) && cdrom[i]) - { - available_cdrom_drives++; - } - } - - if (available_cdrom_drives && !cd_thread_enable) - { - cdaudioon = 1; - - sound_cd_start_event = thread_create_event(); - - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); - - thread_wait_event(sound_cd_start_event, -1); - thread_reset_event(sound_cd_start_event); - } - else if (!available_cdrom_drives && cd_thread_enable) - { - sound_cd_thread_end(); - } - - cd_thread_enable = available_cdrom_drives ? 1 : 0; -} diff --git a/src - Cópia/sound/sound.h b/src - Cópia/sound/sound.h deleted file mode 100644 index cf49dbf1c..000000000 --- a/src - Cópia/sound/sound.h +++ /dev/null @@ -1,72 +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 emulation core. - * - * Version: @(#)sound.h 1.0.7 2018/04/23 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef EMU_SOUND_H -# define EMU_SOUND_H - - -extern int sound_gain; - -#define SOUNDBUFLEN (48000/50) - -#define CD_FREQ 44100 -#define CD_BUFLEN (CD_FREQ / 10) - - -extern int ppispeakon; -extern int gated, - speakval, - speakon; - -extern int sound_pos_global; -extern int sound_card_current; - - -extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, \ - int len, void *p), void *p); -extern void sound_add_process_handler(void (*get_buffer)(int32_t *buffer, \ - int len, void *p), void *p); - -extern int sound_card_available(int card); -extern char *sound_card_getname(int card); -#ifdef EMU_DEVICE_H -extern const device_t *sound_card_getdevice(int card); -#endif -extern int sound_card_has_config(int card); -extern char *sound_card_get_internal_name(int card); -extern int sound_card_get_from_internal_name(char *s); -extern void sound_card_init(void); -extern void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); - -extern void sound_speed_changed(void); - -extern void sound_init(void); -extern void sound_reset(void); - -extern void sound_card_reset(void); - -extern void sound_cd_thread_end(void); -extern void sound_cd_thread_reset(void); - -extern void closeal(void); -extern void inital(void); -extern void givealbuffer(void *buf); -extern void givealbuffer_cd(void *buf); - - -#endif /*EMU_SOUND_H*/ diff --git a/src - Cópia/src_20170607.rar b/src - Cópia/src_20170607.rar deleted file mode 100644 index bf0f21320054fa8e6384e14fd09e0bcfd00ae2cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1983925 zcmYJaQ;;TI*R@-=ZQDk7*|zQKvTfV8?y_y$w%KKyyPx-uFZNNMWMssOiE)iNS1K7g z65~Ju19^AK_`m~$Ljyqp1OFX)_4fzDCViBn1p$S9i~|Bo9Rnijl{SX-M+Jg+var*) zH|FAGW#V8kh5-d36&F84K3@c$G`ocq0B2=o<7YS1zi&_LpSeD<bm*XPCJY$+nl*61;{?_Y}{ev1|kEj3d+g0Xz$BOEC|HL0tu3#l*S+i+5=!T zfcD9NA~m{5u3L9sa5ZMEZ-tje-s+!*K7EiR;mq7PKpk(rWZ!Nx<=V;psPiWCNE=d; z+eY(~QPc9>$Ot#@ap1<3>V`ZX%m_Zk!ib6oq!Kv9Ba;A9L+V_nXRe&n{)+j-8F!?? zsbHf@LDJ0PwZf?+iVsH=1X!be(>7f5oMD}ObVj0Uq~j}wYCPW-D!G91w7{^L%i#Vn zW@1nMfZ8&@a(@m z`**KVN+1T@XEr%W-cCu63^}{*aUa22O0pjjn$Wm5ak{na4OhLW;{vN5q0Q^7e=hM; zvpZ&nS27nOdgw3hN2q+~J-0F9j&WzUIIeX>muL0pYQk@o4JW(uXW^J#!Ur*!9mW+K zUx~FWq0Yc`32WJ~bI0?5VqQddFeCB3y_O?RQrji^j36GPIxc;x?%Nw@5fu=rsNrZ# zAU_Hr^D30dl$J?TK6^ECgU(qf3mW)HN*&ey^ixh;^B`)Z_Cmn)U2+pgGIX}t8#L5a zRZX1k+L~WauheNOpc5uav3TF^Ehy6n*mdV}?GCq>%yMgS`-b#HNq!PqWhod(5*wW2 zjeN>Jm{%qx?nm7OH3YoDLA_`>9o%QmL{{0QywPA-nMB1*??z%B(-ME4hQgt30PrRe zg`cah8Jf`XP)a77wwe9WV(6Tit}P%Qf5&^Hgpw+9p0>~+rhnJV-UtDAome2&6QW|) z!$mA{kK)K8f%(J8e<<0zA8xM*DK<%Y1G>? zx~|V4ogwsVE)YC^^$nC;tHM!4{nCcTL+*gE3DiSKh)|;hr?YEZT7_3Y-)sDX10CFc zIAuD9if^GE2{#L~CS$*;huGhMJ0yd&2W3+qo9F>CuaLgzO=lb%n_#OzE)L0aoevZQ zf~{)TFlWDwmYh$%nImr7K&q{?UF7CGDzpPfi!TSX*U>;R?9oxg>W_*6d9=1qF^=}w z7P5$Vl<<^V9q5XUF<~IN2v%#1K|&yzY0dMi8~S>~YqbpaFISN6n;VIICI|`S>43}R zVkpNWcEVf1p>O#&l^yp1F$)I2+^&$kA?6@rA=A)2;MU7lX1ObHYlP=*L2?D6qV82> ziA<+jg)~VgVo9zgt@yHu=6pD3m&dX$7KKqTIwIC?B;za8Y|B$8vLa-UCS+HzDf&3j z8&!Se3S$O!HpKCI4BEvc<214tTaQLKx!gg$)4y~rnYfc<6l~0(aja3`?ll&nJu(BX zm_Y0oj#o}W+fs(D2uTQGJ61SER&jN$nl`BPtHXW9nG1JFW{Y&ydun2nb~5t-h6pjEBqg4;fYBv{zac8mvP!|G&-JPHS`Bs>mYUUc z=6E;&cxkalzFSi+lv})gA}40YEQvP0&RXH1H)GR2OXN{5uj8>ONs6OWs108`B@T;J z1MpQ?+MuU0E)90OehGM^y+di4kpJj_8qyHti{S?3`!1tDyQnsaiaWUg@>zU%pm9iC;u-oHVjJ3`u5*e ziey;=imNrbhGkHHqd*&aeLmN2j>AAcGsVr!%chB7xga7X3QjP51^42{P8a7_4O3K4 ztf*FF!qPYD4$_DH7)}bb=2rz=*ME#wnsk3AS&#Q>z;7S{*e1yLitX?D9iP6Z6{~TH z-HbgnmnyDYf;;>L{NaC#4V%F20RHK=dzDQjEwjx|7>ti>*BZ55I47ygy0gH|46!5R zn`#x2i^@Lml`b3w@&jRdz3@lY@{1aDlL;&6G%@VS3^HOX?B%|xf+((pdHF~5>xESE6X1iPWWzMt!;e9&VxbpR%s2mQ2F8T< zc!q&bJFN};4#UYijn*u@y$tRE#=BNKedCEBioh-TeK$VA$tBe#xogar!8p^A46XP$ zy%-y@@PPhhHbHI8z>P`FKcAf@EUNfh0mO{l^IM{}|yhUmsGP35K-rxVqh3baH`V({%&9J&ja_eQU(x{=1&T%GmL}p56H5{*`;$ zX2Z6@RNiz{f-$J2ram-OJSOTSJQ14C0EKaO3W6m{#0`5YwwZb}c|=Rii`oX2+YoHk-g* z#|^X+tbEy=qrR)!aKFLu2mSHN5$;qlW_Qp}U<76uzXl7VU!^Ch=@%B}gn}otxT__d!RPbpQ1A-2 z9z1OX0&%%(Yjb}oL@F~mltihN8Z_1sG#~{;wocC0*WkaJcEjY~dwSU1wFG4*2B}G%7edV7bPu^boLoTRMs9Hh zI$Um2Mv<#=VbufzLE!r@c$&Wt60tQ6vpDM|@uL;$;)0cpj5r0ncpo@38+zlOJyt@~ zBZb2d74=+JQmLDdl_(1%Vj@ZPS1Yo8TiRI0Zl@0f;@c%9^OuoL;t{n|O}XbDFik}edV0TpUe&@(Z|hB)qBRp0KpyP*+aL}6Y%l>0<>hp?h%#ng ze_{w6Qz$&;dJm11OA_BT!>G2_N$1m5lIzcQ_`eI$2589ac~YZ9OO=(C3pj^8dvsYj z572M@2>eBUXoYOA9334IPZ>G6#v!=dyQCEOu=~-Hrh{Fae~v6KTx*sI-EEAE4Sfm6 zeQ=IlMMWaSy`kqnO25DGzr4Gnaq`G|3S=f4amgJLE6HbxJOUQl)8VKMMb5*15o8L! zQ7%R}qdAFIh;PlmLg$noH8x_CxjQc2OU%wK;eJNoRtinhb6yJ!wRKx`3SHezlb|3T zzwobIYlL!Q2%9H97QpxrYDb3u~D~12DUdO>*w>ff6g1;Xe>;l65I^38X0ed z%?zE=gj1Dg(F>G%v4NO$!=+J3wAuV`;P!SeZ(R&S-ub7HmNbOG5rg4Ii4q)g} zvXf|m^=V@$&{#W;JQytEhJwW*(9@Ig8-WmBMsmEa!taDn4#Bw z*$;>&iHU1u0~HPr1yjxrvaCC_H=oQ8_VIu!8ismhT7{iP_U3QtnVB!>jm68QgEoU= zwfyC=NXmo8*ZD3{FqZ zmOToHjAh<36%-{_u$$!GB`&=DpY)!qR5Ckh5*9eW($y=d;E)5}0ud1NtK;;;MVUiL z_XS5hd|6PKZ_$ulpE+yXF1p|3DKEUbhSR$>DA~`=mllaoH9lzlFm*HTizj z?@7g1Rc*jyF$1h1RQ`xvCa6=y=<71UCis!Cr8k(*7mWsC;L%nvk;&o;=s)KOyWoKa z`^XS1-oS7mCS$p$ED!GDI}xm4YrsOZ83xtEe3<|}oe3QH@DK9AFP=x5f#T8y$y69| z4gnq|66G1lvYhlCpQ8_h9qGI9hUs0H5GN2(fxJR|+$-*m@jSxSqDu&0T)o|0TfPpa z&x72nrR5S*Xh!|49Jc+4Ua{PY1j4R!g}@QJKdC8+g6ezen2d0nn9YhOqi1ruIk2CY z-=f%gfvQ1EaJR3CoW-kuZS~{O7=wfD57A!RN$b!ljaB+UG}&I-j03hm8EgN^oR^(#yxBy|kFQ zfGt-Cs+)`cl>MrlodUUhtf`*2i@j>veh0RVa-P9vy1>8c8|H%Ef|vRWW_9Jg6LXZaG=N+<13@PYSOX-Ii{I_;~{}HhO9kX@ZEB` z;`Pa}IWYCsNwXz!QDYKOG@)$2YEtrgC)+H%>9NWWS^5A0=OT;aFIM_pwVt zfa|jX<}Blha1@(}1g2ewwZprQ#jA&D#!474NGZ{evyqpMo7jDh`q)cdX6b9yh8C7l zoOl=9*R^=r9o|nDIF{_;XsF%vyHO_Yi;>O9-Q?|H)F>s7J{T99SWw--91p40mM!PC z1Sxa2(Fw349ndA!$5MY?u9C>qRN#ED$QCa?iq2w8uii^Sn?l%6^Vri>!aw&{FL6l_pY#*sr?dv1pYyg)1>->@10zLvIewR>?lam;2yg*6vhN!}j zCZxh!6k@qT<8 z=u|k1mqrg2AThfOBwBwkSp019Jd1|tJiBf>za36WQ=X!Xc-l`zM&3-Uo6qn<06yeI zKHFLJ?V{zcQgT270pl;^8k#VrB=^CYa6K#QpB~i?KNON*xpQ|-DF>4-U~;s9XCRQK z3OkMc1_Q@r8${)B#SHlab+(Eheie3O$D;e~-ed`rw)Q)%$c&67kjM~89c z5!R=c{4~a0_>eOjMCz~9;f}pWZptCdqS<0)4)nSAuUGaIqjLsHoynZO@(m zNe=-wV@a0@e_`0_Om*35i=nuU2t_CV5jFlBktHF|G7Z2S0RP+^$Xw7POzGedpsPa_)gLpKq47&{6jTb|@ z*cGelF?>sWeA)W=899`I`$&@Bal+;SKA8Y8VnhNV&dNs>;T}c&RMXe!zaUgd6cHg1 zy53EQrVspv0{Zp2QXG(RZyAK!XJI|okVnvZYk~t1f~(PbL?ZaCwvDypx2{U!Bp>@L zVfFa4SUwV*=26$bC!wMuw24h@o|Gz~Y2u5$&lCPoEX8D1v$%;irOzU_eL#UCC#ke4 z&#*9#yYN&h73wTZQkIUpp)c5U29nPFYnHM&G1C#^Vh^0`JeyVe;#f_`1d zd8Kt;=3R6tC&~F(H8k(VJKU*V+`eylqWS?sEw3aK&BByR*oY*mNecW>YkvUf)3o&4 z+R`EtU2=w>!*&f?&r@?{6V3zr0F}(OZR08){;GD{eUXK}*yQVgOfo;<*#P$>wU47IxF~9a9Vd>fhB^KV;zkd(H zC+@Vdy6#No!7xg8q|r1GiJbc@ihCXv0WgVE4_*!kW2D2EHc1B&os72gH^vuDVijDN zi<_jtlGQvI2}{@lB06k3+m1L>wehip*Xh~X^QDo_bdGr$eY^$_y8t2e98XQj`Iz zATIeH(k#3%>8S>3VgptQ#NR-Pr{0SMUi2^8dRm$GJaQszSKIdVp4Kb*cs_PtZM~sG z6&F%oZDq4ETyP{6A4{&BYsJ^vJq=ZkMmexlV}UNOI~LivGbkNH9_G!pQB>3 z?DS3IweB>6yQj5P?)CGv+4GB?`}6bHZ(rVxa1vi1)y~JmNzN3rD+d{$!`vRm={?bObP(Gb+gSa-(%Xb~r)}R_@q&2} zZD10n3d&^ zDHDSP)bg86%m(28at?zRCiq>HIA8)my*}Qb*HMdeQq|0{ z!?9^ZeZTwiQ3G}g7fi2cppy1?jvV5feZp-yqG2#h3pVaf=25(R#&-3X(iDu_95=xT z>Eqd4Hls@`8aMF&TgA14@S`;RKAIXT&2|i8dVHZLu~gEF*e0 zkfe?}s&yJ;zK_d0wFTeE>f%S6en*#!0@5Aw^j$oYw1%v2)k}53t2OF;YoYW3cCxC( zMkpb7jh9vQRvG$?xmJ4UNmjLQ?Wi^*?%E#*7E0(bX(`eMBgs3Ibm3-TVuy|^io?BY zw0J{w8HiqTd8?d<<#UG*sDQZ@({^i-stOw)FC#1ULB;#-YyD7622X`OlrK{Bp9_Hi zwdE%Ywr#G)_q9!u9F5ckFB{y@zaAL74|5*_mHJPc3wWhCq)GST9CJtmyM8OZIa4+kFJSayCmG8HcUZ%pMfBm$ezl|OMb5x zQ!aoQblPVz*)HttGI3V!;=qn9M0Hxna&xB%7#wEOhptj zq?8wRcgq-9IEcD)!|T`r4ZvR?^TXq zkI+vHO(O%EkbV)JDf+Z7X-H}#HSOvC1v_x2O7f9RS2m1l8RsX$F5_)?Z{ktXyL(}^==6)NXlBO zJhCY0X5Ti&&_U)&hbgHjrY0l5EN*y+SR#KeFIn{B0PQpG>`87=Rve64b=|P#foUcL zu&1MFw$Yq%m=<|9zoU*d#ikoygcSo1gO&uZQQ|?jpbV>Y5zAk@diSCKGA2Xd_HUAM zi%<@=jd|7?9%G%^73v$@jR7IFfhB9*7khFEz{Js+fRPQ2Xs!CkVW(_H-aF+ zz7UD>+iKVU_cN21ASKIZ6-s8UpSEe)XADOn2k6Jdxj-)W<*NVSK0s12X^=cT*i3MKOGL9E5K z$uR_22YoiRQvTsHMrOscx_@W5h_eH2xPDj=IsUuIpfz}%0b4r-M~_7>VM$C|v4sg4 zC{;(e#+_Wu;i<50NQv)tWyxnwd20gCF?^gDQqbf4 zOixzu3;lKG`IX46*h0Hht<)X*%SydbtvRxrgA4eNq_#i&jv+kL8|ND;)hXxWgJ?`{ zOD;m1B`oIGte}2)W?Kc?BlHWTHSxOuWY%w;+lwv#IEZJ5RiZHa3LIA z&+Pczod~xCs&rk&@2B?aJC+rzHD^42#5D!cC*AY{Xg>h4;f$-Ht0?2Eu)McLIJIYu zXUsj3pt=I|U+g0G!{--8gLK23N6d_BiKnL)F z6l!>|J4ZJJ#u>t4FX0*+B;#C%eMRa#bMO1c`puctUDOoNZt?4E3dWc-9_y) zD-3IJoY}>oEt`>{So~vlfKpSGWDy~L2Ydr0bZ~g)vmcun1Ipu|@ob~tZXAXD=i)cab+aAc)nvQF zK3lbi`5=U_o%i!^Usv5u#wuxMz1ht;#tyx&;*9#!Vb=hBrKy+B#(B->`QEFlmhd=& z`}DRCx6J$vwszd|;^RhHQELZ%a)yIk2^Tnl;^9IRUlFyW6!5a+{iChq&~`~JZ^dwd z%9JPadr%lx>?A!2JYL}w;PKPX(nV+aFcEK$FkllzHD1zAq?^qOJTu7G=&yP5ZRi7r zfDNCB6C5RDp8RN^F0P*@FYZ$~K)rCXQ_xvLLDB-$BMOZ5`*t9f8_eLe5^`uK<^G?j z+)#b0PQ%mt3m2Am1-H3---Xqn_-~wE#ufe?LLr{UIN491Y(|j2KN$WO#Q*BF7ZmIV zng~EDJ@cO2sNW;NhBgKf z+5v&903=x<`$boG0)_NESmdN;Njmqr6T+paT3yUPcpvl<*>Vzc{FT$sbF^?g`KH3Yr6?huQQy1mOMYAEqD^1$A>AmE%WoJYl-JmYnmWri^*I}cqXvkP(!hDITYE7VL zDCr84WO}3vZAh~Vi#2lJhm};59*CpFh8N%Vt-Sl&t&S)~e=qa>tW?Jvcqt#5N5Ag{nRxZ0;*``>A=*C<6sRoGcy15sl zFwjIEdYIV-#(kX1U4qjsy}nqdlulc&ydyx0jcf6K8|`+vC?k zN(J~S@jB{`76J~DcS$5)-H`cCEDQK6l%B5vQ1l3HD)vOf%ODRjM8c&2ZezmVLtM+0 zlEL|BAwyWM?ObYnuGJf%{Ddp897L0S6#LS|zIyz{M(T6ieSGQ{Tjk!AW-CV7pXth3xB zaj6Gh3(}fRxiNX~6C$SDdf$(OjN5;qD?|g!VIkt)8HV~Vbgs6>|EtfDCKKPJ$A5$s zN&q9^BFy@4rzLLsL02&gi6E5(M)8gw(`r9wSMVZsW6h7RHjf4AD;9# zWmn-}hCWCsId!l7yP*UOM)x{z$DiOYZ@l`#;kkkXT&>>P(-;+7FZaA@qXXtiQ2SSI z)Z2ozI?}AD0(_o7ks3vIB)H?GRU_JphlKt_*cKzYPUl+^4u>pj^>A@KJa@z|g4#zG zAfv^i^JE8zT*ebq^hH1vPN>uVToQW{E?87zR4%3W0%E_f6A|G^h3J2(Crxq*l#E7z z8jcty{H-loixfShFucLs*2Ci&yF>&@5WV}r60FlF!n~M60oXc_OPHr3Lf8T|fInOI zEN$@d!AAiC5I81X{mNk6&}0d<=chUacZASJpP#^ugkuwX>*8G0^gVSCVc&ssJZvIj zSDOSUJkQ<)R;HC0&o6(ZKc-x=2Y%LDjbPLevs6tLbY^)MPFZQ4J^1DFiZL) zpC|!58iPDiaW^%V4QvsQ4ZnpiX7&uWtq=EWkk~sE?8Fa^YxHN=lnCay zP1)Zq2SdN-y%iKdq1J%;IQeV-Im+CR9G%u4wo#t`ww`YT_LDL=?^}nGi(sIz%@55x zee>>i!Dt?-{RVzAEeHv4Y;|zbls>eebky%0Ulcd5qRgwCoH(`Ziv1ezhd$Vgtp!9k zB#-J(>VzLrtYV6Id_Qf4md&kML%$L(Ya}pxk{dgIz9*1CG!0nNTrvkTa$vF`;FZ4` zweOpB9T#uf{ST{Oe$uF?*Hz>|Vms3{L7!>A(Z*kcz8~6y)0!N0+lObz-B-W;{w70^ zm_W*UfxZNcBGWwuLp9D&KcX-H=^}Ijnll*^83~f zyD1QFj_S5whL)hP`a-O~31B52-vzGUk98g=>KgveIvQZJkh|Y06a{_U@tul6a6lfwy>@1c zd$^(Y8QjD7Q9-xn;bHv3L~mL_NfIjso+`Wj@CiilVVSzbcTC-B1&*<%GTD54E}o5W znrh#O+2gZ024|#}H`p#z>Ytj4WTYt@SjDabb)8R`<2}Q9&}zXCi2=@Q1#xW(>h$>Z zd|1DjJ+uwgG6BZiSbLn&{7%+-X${H1r)qVAKoE|1if1Mq@ zc}W+~S)vMV??B&z&Wz~-qAX;5eMz79!sFTvKi7&JRc%cez!tW`tTZF=)K{u7&vVy@$yKuCyl>>TPw`-)E-{D| z$TnISS8hrHj&iQbQ@sez&VYg1wxiKg9f=HCc+Uk!tMsq~RO!*Nr05Fq6v7q3#gWZ0 zZ;B~acClfLUvtc49DfBBQ2B`_NP#p9TFT);RpL?xJ>`sPBwshpOWL<;Yb7(b=IP1~ zZFw@vs?v2bT;W|Xlxg0jfa`kO6T8gv$1S_C7O1XQYvt1Z)MZj~#^k{$S&?qyu-IGk z??DHAl_V31mnOxE_dX?gd0aNMM6#+!h+EB2tmoLzWxvZobn4?#tbz3uCP(8u zQ%7CB53L*has=By2AG#WOoOvx^^($>}AuE_FmwzxKB=H&-_g&Hr zto9(T4&Zy>OW&%iN}#CkO9k@$%Xx`~H2kzJCO zB-#16R0Mv)OfOFeYz(4vuVV=#x9GTFywwiTWN#hv;XY{R)QB1TVxv1%x$VO#Zn-{3 z^ARkPDa`w9uG?1^M=!Zzpw2GKjUqWThKOv2`&jzEsn0L`%~H@b_zY$?y8*{b>;hOb z;JTkZVK!)w4r<1m9(8Am!;?FAlU+7g&INaAy6YhzQe!dagySS+L_Gaj)KEUoDV@Xbn9? zDP!bfgQ#hI@b~0WjP(*9p20=gvOi+{cBKcODyP{1o*yrhYa=BYsnc08#D@;9dZF2r z=X)1RDz}5~O;eV-X1+vM=FPBe7tW!nbYPn&Vzj^=SSKM!9)j12t${PXCOa zb-!pDTQ}!b8a@s4Z?}#tm*<-+qjYKM&TbvRq&6kswy^sHY>xFMDh5F)1HTPkJ<6PSEPN1TaFaR#*pBD1WQA!%tLhVMXhzX2_CFk> z{12n|BoV^*eor%c`9x| z)jD_t79F+new80_wP_dXCVV=0y-JpNa%r``W? zSpwq!apZp%ApKM5e->cI`wW=F^dCn)DyTfGz!uy}9vq^PEuv{N3KU9Q z750k+zH0I+&<$jeP)LCRHkF`zDVd6K?IGC;;Q@6I{4-75&&gSYy;~ZS zX~%O{iB5^v)$&VY+()4=nDXL^evN1hA(0DGi#8H<|1MQt(tx21smy{4q_2e~if^pM z@q(R)EJgzr^0ny=+#5t%uY{F#h77W?3&l`K++70O4)4`7ENX_#D(+jjKT>~ZH|9Ef zXcrhoV!hW8(bL$Z>l?bAT5J6kL4-KT$sZ5WB?+lZr7~#zt|tPm!y~vw5t5%Y0$}tRnQX0PZtOpy2&$eCRXhV#d`il~B%~-QQ61-LCx0DJ zBm3bl9p}*LOmT`9>Z>b#e(-pj&9H^NEFUdWMx!cVU$!QFRaTn>V?sZe9@3+T zJ{DwC^;8GGj6ZTFNQhES$69;i+iW)$`ZifQrTO;bAygowIA9j7lRezHdcw6&Dcrv8 z0{VIzK;OVR>A2k)@Iv0HAWBF^LedVLw$LJ=2^*##m<%fD>Q=_}KFT84_V(%toxX3R z`Iiy_c|c&hVZcOVzg;B%B?a6+bD?i#>S1GO|38o6vhZp?@o!@@`_~6iz)gjfmGxfT zvPaXf)+F=A!GHhHr_+YApM2O1d!*Z?V!<>)1B26P&?RN$8c z^}6ZkK7H38;9igQuAO+yXs26Q?%C|O4!)oc$omc+(xkI*{{Fb)Xw3HF+r49BhU}B9 z4(j8KFq42daZY7|8CS|hz92J$^|F|4$cFjkUhpGg#-U3G-_V?JK-pw}KRb$qt_M~s z3vKdABD}h#bgAG_9MkEIt1&Y$s%WAxW+-YlLYQP=laW|2gY{qLZtOYxDcxxHFi>%M zOjT@_w2-xuIB76z?}a~-p3>}jP%(eae?e#>h)AOFzQgv5d}{>*>{_YW$xOrJstE5T zA|jH>T|g=vhD^g_l29B26`%%9(x!|^;>QqQJw3XH=V|fd5;te5$)#&-G_rGu$6O4T zYW|vkeR)62KwcRnJFTl3U2!Ben=_U|@(wFHT$xIC@|3C}fSsEZzeG=W6tqUO3LvU3NoGb3nV7JQ z`BhWQzft4J@C{KZh9CrYN|0dJyjeMsb$eKPQZoL6zM`}y$xW`yWn`>Kx(l<*=f6wkYkZ~iyqWpbLSQOPEewX7tb?ry{2_`j;dW(#!!N=*rU|1EE z8kiVJUP|DoJI=d${2T7y`;92h#f|TYu|MAWrQ5{|kc`Q-g3rZvC#$aIIX5E5-Nn%& z&BwpNU$Qezo=o~Zf41Y3p^B=i$&cpD7Xpa&_I+W>mzW;b7p|tB-q?Bl;PfN%TbJOQUPyQO!Y|EDg$L)XJo~rwu4%~)* zTc}hqIA3GY0c)tFm~l9_N){Dnk6WN1jZJ2zgTJQ(Lo-Z>y*!{&Nko1VRqRtJo?<*& zM7O4I2jK9KSGRssIvk~`z`4fFlfN8;;i#4@1k4=LsST!-*Vpo{3y$~ z&?OyW6a2QYG}c@VY;vy;J(HSasv>A)<*_goyuSio2u?`g3fzC*=Rgo-6Y9v*&@mL|-@|DEax{fcQhd zg0)Lg9-zDy`sHM8H(k+_F8=zlXkrZJR%kwk@&*m7*T$KC3ibE2wXf?bpuqK|%8N9b zt7?l}Lz7rW5zy%BrJFPYxWwrs?0}NZykNU{Pk=2bRcg}&x%s;rIJrZPSkVIloVWW# zbhYqyK#)$oEGHGo-Z(Z_`jOpPebkl`7<@aR@^V=ANL-_Lz`0Q1IJKU$L)oTnCdg<+ z|2vfc`SQ97ZV!Y*s;Z6TEw(i>1$HnpC3Xi?CWIXbIVfn>o|`hsE@+n*f?dGgzt33c z{(2?x&Ej;&+l7a3%?we&?tz=kxBvz^Ys-(U_3?I@N3*AQ3`2)QCced2nXe)^lpsJ% zKXdPYz?abww&MR@$YZh86@4d5Ihab=Y%VV~ka!H#d!r93{E0eyT?5JbNwspHG_6^q zU&=U5Z(8gv$r;PHP0}u3O>!*UtWU5iyM*XL)AsxDn4mt5MCeBabf-SB9d<(DJU3Sd zk%Tl%gOTTtwa(J#ZBW@Ih8IN#PqvL!8YqOcGxc=w`iB?1*}a;!xJN&F#)6vnVkQ$sw>iS zm$kHZ*BWXrOz7q@tl1dWuC2y;C8|BQ3M*yyl;!x}f~KtPw?J9$hc>!21zMl4*Cc!-*cIx%xnb8^gQBK+5ixE7#9Z2p zIYa6~`?idZE2Z<@o1}b(!ZLS?8FwTYqO6>y)A)u8uY(G;e{s&_!3f52iVzBqBOh|H zNmCa2Rtdx#PYoazqJ?8`MFgO<&R?A|kaJDOveZmtw0;JlOs;k(go8a*tuVmXaZZ~+ zr6Ov)^&N=VElc;g*Oh=tD>|W{M)7!xdjokMdvZm-x{fSKn|FF21iv71Cc^n30>on% zNwoR#-xcKT&UKGXLO|7uW~e#TDiOJOXS)FkE|jf_{?lbI2(ve4h;Cj9Ee|% zdzcV53xmCRqJe`F>Ht{xtc8dfxe@{QOvrZ2;q0I@iNue>Wf(hYbN*JA8UtVf6G-F; z3N7)*|DK3kIubGO)m62I;@39DhUM;m*togBRD?Z&As{<@v>$tXQewajMW-T0=Nd>*{7 zi62Ho5T?o<$`-B_o;1E$`CJhnsn6cg_k(;ArFID0!XU$WD#(c5_ZiV%&S^<;!~Uf4 z)k=}LQak-tIufy_tXOl35Es#EiXb?LLSMHQ^U$?;y3So_?^5$cH_VNOkto{IM}PD z+=kmpxX>u9Pg%S)SR1)NLJBJl(Ivj*Yk+eW@RyB}hyQ-U{@L!>=8fzsd_QYQE6r^M zL2QRc8i>fLYz-J>bdU`8z)^)SG5Cf5ddjrw$cKX5$F8 zR|^T07js-)euw55Yj3yShx?)YPKOrns3M@}R>u3vp5c@sP)C*ucRHv6*kkf$=wFdO z>#7p~W{0#)?Y1(GnzzLKS)E(d)p0@Vfkn3;0QXc{c~ui;(ovpO{aUo2XO(|Ti_Q9g zs{U=-Ua93@$$R*|pd*(CUrSM)=`LO=a1UlCW>s9ch zY9*=7A~~;DHq_=JO})*mJ}F;iAX{9*ZJt{->e$>Wx3~iD;gMSbckIx&K)w@j7XV%O zHZ9;Vgxv=C4KuYo_tXmjTSuwysd>u4px8q01zg|q%nln0Y&Sd?bSmg>d@aDI2f%T7 zD)4UCCD+EUhUh}@1z@MhgkcK9YHxuuhjEdnnYIsbE~pWSt6;?{NDXu2YXTs;HZ_Ph zK;YQcAl(Jwv8+M53*%#0g7-o&1>Xv_fly)9V_2{b=R);XAl{jDY-$|XgO-rcu{maOJpnH;0-pFi~yosIb+eZ(O3lN zXBPjK*RZ`(rHuOl9}R8ID3&grBh1w5KSkvQ1aSPvGekfA_TLQ6_O+oAbXz&v5y*UB zSR^nPHOEI^FE^{BAHT1kAE%@7>g6pUp1;5N{{!+XtL(tX1i0guBOhg;ASjNTk7P)grb9C_Go6!z46{cJNIs#&`%qtQv8 zjaWOWFI+o~9I!NF0GpZ$Mi$r!(#QHS!Wdf-2}o`fom~ z1tEg^(*et%azj7|Gea{)RRC93_FSsx!S5!kQxcK67gK4s9L=WMlO1XF<8EeaT%2^N zG?Q&+CX>?Wl0E89echJe=sk9B(oMNHt@C@Xboled z0D3?rT~qgdzMnV!f9V&RD!N-3K2s}2(bv^;55n#&7-F-2+*^Aav2bj~i?0?toiSYL z$$HK)@nh%@(02eP)!R3&|E+m0+2#>|#OV++EJ$sv9X&!L<-9Q;HW28FhNW5q9|zkfKR|YD-NSpXAQoD= ze;Q%whA4OtK3h13A;ElLK^TDVY&#h-dI%*UynO(4fR^YFVjtK=7(mnlbi#^5fJ<}* zm_j_r1ONzIg6)AO5FU|?gqac2pj$gyJUjcL0|*DeIzBf;wHFr87Tnz%*MEzXlL!+x zq)l8}26^(}5IWp-xHin{AlQJNv(IsnR9~&kIEEtCnf{Z1lhJGU+f{jeaf z!G_+u%7^@IbOcY@fz`|%;O%~OzgqSd6!+PU46s_ob#%vP~oKZqVH{|H0dxWA82MY~d-8y9WDk3x{$xo~8^ zZ9gzPnIjTriO_pt8FY$5Lh#?odhz%R{`C2x*t?Gqr~l)KC>N6#;%Hu(oUg;e6E|Cq zWXb<2^cwH&aQ>Z@Vi7jbLo9_cf4)nACv-)%#j=ago`rD$@Acc+uMfw=UbffvXNH;= zvF_q)!BrG^!?}bGEH4;Uwm5j~36I)z$g0^oVMS+@0`c6o=x*-M3PTudZh#HYHbE_~ z^W1dcZV9)%1f6>S)3S{D^V{#%{-{Wg@|R}~45HVGq+kWH3@IFANHBbSFCl9LakE?3(MXwk5ihs-5 z?9k2rV)`~T8YR3lp{2-Ud7t8EcpT^;rXT13wL+#1Gzg}k3Kx~$QTu<;ZLaF@DJir!9B-oBw;>p$2 zRx{YR1;}=>HcB62$3@FFz}1o`O3nT|Ai3z-!DjX2S&>Ua63)Q2)!Z?21ar;{OJBGV zQdf~4`1O26a63w~2hv4wNZN=R|ZFjiE^zs8dF52LNhiW(+Q455}fkQCm8iS{n%2K&1<7 zJQvr@rgn$16r)c&9Z{($RZ-IVjWkS@N(v|xQQ1WqJDakBU&5nhA7pr!HUB6IVj_yTYk zxyAbJ?N`y++S>GSe{LhT*kXH;g7TmvRI`LWS3!njCejkn8R{%r| zJHVD0g6;p{zCn)QSW^*PyEYxn8HIh}1nL1PG2|!*I0Tyn{SvVJiO7+0wPxMZ5&Uj_ zXbee)Gq}*SqHK6{Zqd5Z3&6=Z*=uDl8&+_N>+JI0-7dML){mR zW;G|GT}m0?bs0$dr6dfsnAJNfAXG;>m82@(NE$%)2vy;02hu>&@WNd*4K#aIK&p>z zL=8l0YEUZ>MQrY#Ri!P3tbtokJQw!92-i^qWfL}}Y7VX8t$D5N%N9EWD*F_(IH0Vv zSp87ya>^iVR3Yw~JL>0Bld-9u2STj{v~<|m&juSP=d_8H{<9?&A=yCL%qwJh5tR+2 znbV!9x{?OUJGPM$G-+KF+L1s`p0lqB{bdk}`lJuEo}|E85S z-}UJRHWo2lzl!CKp=`ic|3R=U-){!){?&d995z2;Zb`l$z6##j@qE(BUL^i36x%T7 z05!eaTYLFHdcoz`+uYmZ+pong5DIi3pNest%s35(+vdJ0BfvZWwB4MSv6Bv=A0>x( z_=-pHC5*mFn+pOGNxda~$D~s$Q2tXiQK6Z%9+DGIqBw%3g$$qa zADVg#Ltg5bwkkCT=|@37x$Ff0+NinRhyOc-Dy~=UrO+nLYN{TCR(2Is!mzq~%J25F zdq2Sx4he^8eKov2x)ui-FaM=2)u@|xC{e51|C{{mBmKc{sbn;VA~*l|`*hsQB!))z z#j8D5ZC%IK8JORF3L~Cb45w~e0|V&meD8(}w&ppQp&#E>>zM9MPk1A5HM^e)+R_k4 zlt{gR34G2587jEp2j@@+S4EK*fyH|FC}wZq48ube%nTwTuf1DiaaJ|%Z~J?QB&jk_ zZvc{9;Uf`&1V#LSv9@W@O*Oz&9l%G2!xf}zjE}|qB45tD>V4O05Q*sdkZmz0cf7k_zMO zHRiXVkh{s~<;V*(b@c+tI_iRKd$_C?GN?g(zF4EcE`lMblqed>@hB!t!*d=?H^MP! z@h{T5v;JJ%+RQ%Aa6&!1cn{XJFWn*bo0dB|Zgk=SoY>kMT?2^&=B(){7^-q0C2RgV|GrL8;^0G^lOzjFNF_l*R9WT$!ecNzjV}W~ zrXD%k|jiG1bSWM^V zNutm-Sb%2a!*W!${1e$q9Hv8#AS)F@PpCQEJv1$g*Dv$q=oyIlSJWblN)I$C?5EEkRz#0kccmREkd6|_;fR=t&Xs~`8 zw)rPH9qj}*$mo3lX*44Hwt(yS-4Zs<>_M7I|67(g>&K0TgnAuT$w?CMZ%Au|ZEE z>ovcf-B`8&CLViPqR;ek<5MabZhkHRu0i(jiV^-^uC~ExxA6WSl*|Un% zpMUN>1}exDH4A02f@=nGrTC)OK&vCF<;!ahDIPw`fuXG4l$v&xg=$(u&q!s8$52L+ z6thig;6D+ zS->(H-5EwvR!%CGe@xKs%nsTpiQmq}z=gs9>C61_IZ{xlDH2g5n&Daxh?0gc$}b>E z50W4mc>+d!iV1-uk`T%x2x?88RgJ`;hw+BvhIE%rpWnN=S z){>bm2ERJoRqOy!DS;@Jt<{U=R=pXip(v>PVP1h|G&Xnlwu1bSe5lpAdlkt5{r~Bd zI1NKdpjdvI5pDWHkb6Fzrj7M^cX++0;4mrC&f~Z$VSUr;njm8M-N$R8UPBa*j*=2( zqUxWjUuNkE+R-sXGOP zhD`c#b6B%zD&7g2nm%ZUzSNr!W4O9{tOb}l&33v%iJ^U6cA+c^EpmrN=L62C*1%?K zwdVeRQmL%`3rAiqXx+a`34s`%5NS_FTwR^F>Fr*#(ls_{d3{50=5SkcHxYg6m)n`E z4~FI~DmE7<4O&spa~khCHjerqQ;fhhQK3%XP9)(E;x|0-P1U(S}v;HFE$@~sX*yNf+FCrB=B z9e@c`N+w0FuDP;v9v8(7Aljs68AV?Zgb}0XHCJXXr~e%)yc`X}fmN-zg9}6>#WoFN zI*?5$%Crd1X1^E5s|X}VGlTIS2gc`-rVanjeH*SAe79azv8z<&Mmfl^YkvnmC@|0h z>ipaP0602>r=g*w;uvA&@;G{PC5jlg5SyRWAb63#Dgi6yT0jZ`tFROkd9x-cjhZDE zcshsw<@x&fqesLD40k@)KW!-(<_pW#Rw<${m@nS9(oTqE_9;;=$Y0rYOOc(o8a*qp zW~sQ9^nGRAnyEUAL=~?M6i(jn2LBHoZSFl-zhGpE_~K2Y;e8(NB4ayx$Y4b7Y*vVv z#2V9WBVx(<>1k$OB=*gNG}4X5oi!R^bD6vU>II;N(9%YVC~a8)N=OC=3(KT|S6Mnh z>NDxpCK40svBn?fHYW97RR)7=@{;#kqkad7Qd%u9O$qH^PfXpwr$EpAg!>MUbljzH zcU$SfiIeiB^jw4*YB7A~myOFQ>|Z>HAc(mN&rVS)|BYpc=pmV0pblg)qpP2&Rg{n5 zTaft!+kDJXlreIbAX-4EYg)+D^b)bEb_{ISjAUu9lB95zV0U4=)r=eCIZ(V5RvI9i zP`_M7Mruv0vNQ|Odjkz(UYuP*J!g2to?UZT#k@)wWSJzGn!_l5e>pT?)+#{l1cQZO z;M$JbTK_x^Jqf*&rbtddKYYPbg3GtF~ZhK8B!GJ-1XdXY+e5ZQ!`jYY*@ct64S;1Qf& z@KEde@+xj$Zl*CpMrw;+!$nV!@Y0hZ#=^en%Up&=i9d2? zY_7w{MAoYeHrbwF3e#PpN-J8cBR3EgrizCpj3#zyP@>tRLY97MF}(M8WO#bb28{&$ z`}$ka3#uQwhCxb%{Cy$U(rj4d*WAg~Y#B6IcMx&|3DNK;=yjaAUJ|SW<;DqHcKUF1 zXS;);(`V!WLeb0=;ZOzaUu;bS8XmVm>!WmF9U$yZVyyN+{~E&AknDjkqw-ip5-{V%B@V4@p__;y zH-hfV5FiXvno&UsLx8Y|1kgw=oNpRGf-}k$VP{QBl&QF|B9kT@1ms|-O|Gi7Ss`!a zQz3}gKZ;fcTW^)D) zMduXPpYn*pqheMs2A|PB9okAX-0@NDp{3bL4XB1w0s#MY5nV3LKE_v1sIJWk>-suI z2Td0WdMgB^zokCPjzP5QIR(;1wEHUdY9W;>xO^;-qJme_iY-Zn^)-Ui?5EjH3#N-y z?9%MhLaMq(CR5w1ELc8M(WDHy>QVERADA6YCyHvz%A>XH7y19n(bk1JdR@Bb&yq)d zN$B|WokSkk)ZHU=;a6;@V zBS^|DR>@Wq=$#bQziDF8Q}-fsmM$2})Yp-t0iyYU{U}Z7q8I+jufGvQ zK{FuS#@H$`e6kVAx*RGhwu5Yyr?KzjO|Zdd;QJJV8kauY!a6tE^cMPm9Tqdb3<|R;q6RV zv4-;|ZFu(gYp5DNZHf+BjuC`kycgt*Qbu!M3ddE#OBHeINuK4JM(BrKuM$bEP>EAiJl6+zJ)re0=97f(<{ z>szB<_&Vu*yc;{aRyb?_+P`sF_it_S>a)Zb#W`H*qJ%0}g-Y=aZeqX4FVT^gVNP$B z!?Bglth|wCXk#?PLRS2daB%J9(x(u8G7ebXFJJ}BY}0m4PE-*?#z*SzX%+> zRrXXE?4)_cj{JbuPJqjAf2`b`RYP6rvV{ML$}*%rq8Uz)b7^){Ln=^1U4z-ShH};I zZl`6$8CYWigM&$8B?`j`Ce<19h?My0wErnZZtwM{Rw@HYUG8X~>5)tU0wlZE4+s9~6GwAVlRwgkW1$n|= zd=#XNOY2DHpf&_1C0{y}pdL{_AScmF_^cxHABob0XBEpswx#%TIIR23sSztkV-m9< z8{!u2$JDB_-PjrS*fw^kk%XbfZblPyZu&$6+lI#8_F_Y@Tuic#G#g&?a)fiJo)D!E z-tBL;l_ipb@I^NNyN|t2tWZdg4JKknW|C;U>8O!f>sPTf(k(u$TYE_qn?G}I61s64 zJam99vWSCjAAELNKx!l(d&tMEg*w)Dbe+V3 zwDFT$>sD#y?)kT89`bNu+2M_$;F@42C;9y4uWNS`QB(`?(X|clDH@p;64}KvR}}P<tZEFrPunvT8U_oD&>&GIex~=FM4pC%IdEDik~rQb4L1uj)}ey}JjF zJ7^)caKNdpGCci(Ktuch%LHIom{#yl*FMwm&&rdy&iu?gsj5x~@}GyS*mF=K-noNX z3;=b=@-Pwc$6(2rQK4(ZCKO%mqZs1%sHEigt~})Qa3zXan$qea^xLpIn>>ZKPs#B~ zsYj`{#I%@>R@7qQ$h^sRPSzQI3Zl}fPY(i#6P zPs5u`({tl5IU}pf182Cf=2XYcD@keu%7`-8cJJWER+4q*oVPg-vKGn(-{9Hb+OOkf=xS83WXIZE)&l3>KiLcY&4av^zw7{t+uqv$ zVnaS_w=Y}!G8+3f>+Wq2*1)&$;H|U$EBBQ7k6Bo4V)?Jy5#Ly2Rn0(HT=sA8o&|Gvg zDd4r5NMB zG_7?N#zd510XgxSv(0=P>1R2sk~75~LN2F)T?r^uMmixThu&2uIiVA|vjYT$B!y4pU@@*a$BN4PRG=6^30!&Esyj?Az zo+ft&P+@x5g`D1JVCtm-BW%|x#rSKaEM5DJ(8ZXld8`6npIKVlo2x%wLbR9x#b2*( z$#)TPN*>qiv>1iha#|2eke)CnG@k(f@hlz!m&twWIl+ni#@p@30%NsC-m}&ilbY$o zngwwbbE|fBES36C7L8QubkiHPuA^3E{(h)srg%C!@m&VyswhS?Ptb8@3oR(@Ks7UD zUR1{@s3gX<;^{J2>UEg~p3+c3=XSc#IlsrrpI@xlgq||<<*RY1o{Ff_LAPR$iI2Bs zmL|(tjZEAngAsxpikx}{#MOQU#IeK1q1gshH?E>N7b5aL0eiQCz? z{da4Ik!p};8N)8NVz0>yCH_n4sEbgZ&#eT+@gjv=bVo6b!>Aq6mu9KkqvZ`1fgnQZ zBSY6R%qp5RRe%yxB=AE3m@(hamLG(*KRG;&&m1?QPxPEpvpT! zCeF#>q4~zIP+^urXN0{pB?_sLDN7<61dy^2XxMSi>}oN_vBx|qYUWeDLsC|E{1r9Q zi{NveEF}?jU{Ry8rhy#+5nswvV8lwMvUEg4C477PTl%S?b|o^HO1mQDgS&?2Eb_9K zT7tWXt%wP!97LONU+Oa31$l9o)QzF!xKnemo#NYKJ{~=wRnL*FA28w$d8{A8@ZCgO zB^<{HWS2_4i|+stxoMQiNpC-pFlmeAzG3C7vAtMB6EEd*)prnRjAPQi1* zxm){f?|V(Kv@i<6@VXwVtkHk-bKn#E7x8zf*kv7K5N3hmh#ijEI!)+NZG}|kNJ&_> z=FnVm3@i+;w~olfeyR~}li}JK((EEWC4@cvD(#nR7uJGpe-|!w7l~|%BzT+1SU?s( z2HwH~FOA5F0WxB^Zk7(4IDdu+*~WfxI_Y&XFURKr~Mh%Y0<86~Dq;RZ$9v zIwUBwewTTkx$S(*9-#5!R~5HT)v+@%ux&g}4JoulTs+>Z#Bf+86&F~zdxT^ zPS+P^m^$`bsNHiNaIr8PIpEsV)k*4$ULqy!Q#==GNw1>CAX5~IjOoZt4pyeYD(T)O zE_x#+J0mC%F<=da-Wu8v0(B^vHG_gkgGH`jWU*hM@2Za3f9CEkKQhzaUWi=8?g$Da zx}7reF1oi`(Xo=pY@3!D+t)r=(-MZeD43#&Kw0tVH5x73G%L<8J?*<(+eOwAGk1UW ztd|vV&uoke3IGa~WGddT`y^c!s(SbAZ2o7PmS~d7QQ4e8tgVw#gDGo%@~fylL|#(V zi0#(oZ9|ZYwm|R;cENofa^+49+nXgFWigYTx#MyT!_>ZdJ5?n_F>y5k8&wY|X0%Q1 z=j9ca7XW^1o6@!ovSTpMsEj;=vSbeHcDBkKg}4PsUUl(k`VJmWylgth?)W9sHgAe3 z7tDs-%>Qwjbor9bXiB-kvf3w%rrw_dm(2i4-r)=$z)uC^g-dJofaCaBb!Yol)!201 zw_`S1m31CXfe}e9U6l$_*8;!9*U2Bk7|?=c!W1%O{*^l;ZG&_2lpQ^5JljH=9e+3na&8!Qo9kP z2tE~`yeTNYtLy0Oy1ig9?-I;!uk~D4cs`bxxLktka94?Cb5d2wt9uaebm8#ed+M;EJ#@OU)MMDs#GoDvf{f*VQlPdF+8BHmFk-A{yok)`EbK)H6$&(kFB^R9vJhahM(r_g) zk%|e*7W~+5N^d8Oh^23Q`vgWcx1=dKmX@C}YKc}WF4KkP_qlH>C{=qV_U3JcoJdX& z(xdtXFfF?0&=(|EPA+X`pl6$x1oc0W#hS1L56F7M;s%8*_l1S`ub(>63Xp8{hNN)Q zJ!9Ns8>cc7y`kmY>mV*Zo(eS|!)Ebj(7`TF>`J_&!EDszBN~r+y2~JG{v!Np{viPT zbc^F-vd3o6X4ho&T6|wgQD|Z+CmvTg82&LA$HTIRXQDyxw1%KX1| zVZa-CrZ0UIlRLY+BCIHG5Mia$9K-vau*SNuf%NZ~nyaca%F~oWLCaUkBjFb*mcb{% zI{n6hP46Iq5P#v<5|c|5v_f*GvgX`jQLJo)>C9(^Rwuoll6@1j`4w&mcB1o+WL`)t zP_jTeL@=^dwfBA2KTtjRg4ocz87dn^7*R&*NWzyUwp%|Uo5_*0+6VC00JUP5S@Q&_ zEo5iP*2<>t)BZxb#)0H5|DaqGPhD(Qn)?5BeVuKP$4&Hh@|mNTw?Y!L5>GC!6Glc^ zp+1|}1);lCB;+S+Vf&2v-^6_?BP0kkM@jwBMQL_Z?5WwM*{8_ZlBz4Hv110bIU_KA zEf}g}FyJH*8WzUW!sd>0g{<6I2j-C{fc7n_czZo0gVm8}ixMdC4u%1Uw9+bt4n-h& zfR|Pax8qkbNBE509iyczVZy<9rnlw2bV9SrM5;)W0!OSk>p}={%Fk~#;ICCxgJfn+nDN^8#n7HOdv_#?sM29kRzGIn} zkrR5E9El}jl+rGlZfB3LwqhDJG?N04bu9eqx^v}F$-u}LZ&tV_giv4*9&2X?p;bTn zs+FHBJ0Nxh>hM>uwW}lFv0HG{mEF4YTBPpW{)3C{$1BmQ4R{-Zb4^tn* zNJ_Jv^7iart7%Qp+D8QMAd?w(D6^rI6#~j6B~$+lMU+SJa0&76g7G`Gft}Xh274zl z=|iT3Uvt&!Jxl{TKQx2YmXu)I19X=VGVJ=IFiyeEt1HeaUf>#R%zhCx=JCDS(1BHF zBSDF4gq@>oEvMct{p7zxNX3H8*BVRLb)jrhKy@Vwz4D#PkZWR8(lTk69?(GD$$K5p zX^D#w=D)I}C4~h;BRiP5)t+SFwre#2Ed?C^m1z=!iU$p!j$}(h*A>SjTZo%~i_2#+ zn?!)>+hqRiASxG;%Chz`n!oj7vy}N{Ms;cz!M&mmV%oE`e)SQ#(W`b53b?*ub<>keD$1G+y5u$6{MU9h+lMs!DlB0RiaU&c@9u0?kA%GWY_~c4TK&?Q{gnu{uA zB&E^VM0TwGqCzv#*Nk?^6NjGIn8!p0UO^RK93LNek;KTONL%-6f#v7@HrYmK>sw=p zcA=mZO(F+H){w`i4R^N`8I2%WCq~|O#>j1MlE*g)>{=^m#H`gYjNs?%CTAN{ynVAy zjCbrFQ*Zr^EzDt(^oy7zha68-7g;T3em6f95h%1c?&BJpqm*^$!6BUZ6UI+8057Ag z^fb7zFO06;#-^^D+x%^?CoQ3%8n<E!-D`o@YsaxCbEN*BNaXbJpW{; zh%5vE_?#RkBISg%MI;g%Ld#=uNAUECd}gRbEt)k_f97)^Gg?WHEPb|2g5PyDoS-HL z<#QlTZ#3~t!h?F3hfyfNK05&HtnEl0&zzZs{VA%++Jc|bC+<;tXCp_tL9fg+9hO2p z3!b>d;G^SEeSvb=Du9REPib<~0+oM+J=93!yq7>5l`hEpp@BO$i(t5TR9`k)cR}5q zM>K+&i!X3%^B;=*J>{m;)+Nn{VD#xU;agzn_C3(njo;5KQx3OmQ8}CKq06FjQqr$# zxJpYdU|SJKu?{maVR4o(g=q#)YY4bIhNB3~#v5dm?@>6fABYLXJi6A z8~ikx+zlFD#?_qgd^P_vcW37olET8LN?As%tbU#HY92h}V#ZU@R!9YiE|Lo?NGR>{ zjqd{qz16q#tTstD!<2D1kVP|vvMu}-N?ePmjsh-a&kCsg`tIOdKs{Rk@`VIyMggPX zq+Lg|^}?NfajS4qJ@oH*CK3%T61=F(Xz<&E!76t)EU9nLtBP)4vr6RmE9~*e*C>8G z=DA(}cO2}!9Sm*b)sIG0S30b7IGvko-N&A(v0giP4zN(-(v4+ssB1{q5Y}OnJ+~`ZTo%2q-gIpu?6LS>K~f1S}U=E6ygV%;9gA%^ZD722SmQ%7&|pE+ysAFPt**7ZD`J2BqO#P9o)= zXPqKghXClZY=@O8FX#?y#t?wND&CCD#Y%Ul9I(o0?_H-Pv)o=|c;cebxOg`H&mR8| z66?8A=I}GOk@3Q&CcKzIu7jQb1ltPbOc3K8oa!*ylZ)rKV+2icoiSve4FhVTzI6ST zoU5YR)0%4PcLlb+O($Y@H<{&kglMupz2Ea&!M~^;@}YkM`8h~Zf=Xsk(uwER=|UvE zJ!FF~?tL#m{b;fO!a;|S*j9ex?<6^1B}Nhx{5z8cXPc-BBC*9$iDp*l$Bb_?#7Y|3kPqa6phhDN+@*%dMz1Kex8hx zja9Q2tF_y^lVEleq7NK6J2e8M8C5>q zhInR#k_%EBaHuL?*Zphnai?134Wst`n|nR^OqguQ;`67HD?jY0GnWZZviJyHtBXU`_Q1l?di&mJp|HaidW8jbs(OB@c zUd&fKrExEOg$4fC6;N=PB(P$n)h(bgCybYVB&E0FI}sX$ac?u(*Wy971{#`Qj?x8l z5tDqkarB2uTWkogl(W)3Y4T*ddm9ye#b>7Bz9Gd`;_Z1a$Bz7p6qKR*8dZWaEol1Q z_J6Ui+-pDf*W%tMM%vM(l2R(}g`ixZKEd%6WCv;y5oaEzHr6j;>mziR$1EMuYLcNT z8;SOkv2}W+_Ag=w5&t$p<2Y8s{0T6hVaQ6$0yt2Wf)k9w5FEja4pi}t?IC2ML+39D z^MT=-F^w5Hcy1nwsb1&guNWwd0`UK1>jk>_*iXQU)t{RyS-_Xc(od>5ldwQyY~EPU zR1a>T*Yh7ZzDWKa` zZ#vU8rYGD%^z>n9n&h-Tepcu*afTIC~=n!_; z%)G{7UDWFCVY1uIyVtoImoi=_JZr)?(;mDyj6M3W9PO7t^$0>#|PojHjN)je_KiJozk1(K6^0h~y?DA5Cjviu!*1sG3-0zMY0lLWZ_T!O4Fj zcA{EBs~qqo%UpQpd}g?5l@Ge%8A>8J?-V`-5yQf^x>c zSG|@#ZGf9D!U6(P7uvFKT_zrVemu+w<*t^LwHY+CiX>A;W4t<(9W1`4?s05RjX+9G z2C9wn;q@5AZlVHy)X;R$0WFJV84Z-*q#E9X!ru+h`r!x3uUB4yV>u|Aj6KpqwEHxg z`&5nHp!{aFPtG7Mfa{j^o9g=(L{MM*;J$);eAj+L9-j({(qA@&I+zn4&}fM5sk%@A z`dT2Y|9eW3*9WPxA{>LL{lBuCOjD!I73 zPm*1zEU2G3(i%Y087s@0X$_qY@H#`R+QC&uSxW{*+HOwNBf^@I@zF-Z&16V<6=SB= zf9sv=lrs$WJaYB?%pZv7crutMGFh%@(u4N$e@ZZuG1Y(OW(xC`32=0e`p;KYl(00n zbE^%)bgUKb^M8Pq-GbLDG#HUQLHGy=7n4N4#1K0{$WC=C0~l%Eh`%xS6HULzq(Hs~ z|5@h?#{$If5dQ)|y2d9?=N#IVPX8!*eBusTOrKBHl@w8v#F6cqO7@#-hG*=(9}X{4 zl(Tu}s?)|KmGWl6=_$FX$w$uDEDtuTIW675u4iEyyOsejRHhO-s&iY8wMB(#CeG0$#*9FO}2hxs5Hbn2T(wH_F|~R;p4| z{5x2R;{%;1-qfj^7{qvc-zKuWOq*B&L3>Wh2!g$uR7Ph}$_y5lXVL2Se+jJ2 za?^7p5>In)`muD1Zr1A~pKOz2ao!go%2eg5>%`VJI*lqN`}4xr&!09$&NcGaTJ#*& zOQqKJd_x#TLO*7YWiCk(X!z;J4XO3VOS4bI>lWo&VSb{P{66iTKX(m(5zpM`x`?SO zNFd_J<{35xP%UcB1p=*4Uogn^YrT_pbrN83z3&#yM^> zq+LwBb+|_#3x9!b(_a03TA1XOUQ@WYHC%W)itZ@4MrGESM{NFC+d~CX)kU^&<78ZJ z$SWnaN&(Zd)PI=1$~BjIh$1|NjLt$q7~a4GHidDV-=;;^{q9;q#PJ0!aSbW_UO|p* zE)-Lhk{U=&%n6X=B_@xeD~l~|xy=%)q?sJjgJjfi-ko!sd*7$KZ-@JMd!JO17M^c_ zcGXrMRxD=I;F*itCGhBcVD06XN5GY}YHLY&jZi5+H1&;7vc86%FmzE-{9gesPh2s8 z`L&U{tQBsSIu9pphDk{H1r}+?Y4}hWTt?YwF)vulwT-PCWX(D#-<3S2{M1?G4_X@P zvurG*s>?~jKn3*Z0KxzHDpKL0PKS`{IpPm3+c%d*S%oF47sixLIw+!Wl-1-d#2~#! zdj?E;-U$Doj}0oQhgU#e_WRYhYn}wx>vH|P7-OH=pthX-2=9UPjyN#jwjQ-F7;{g& z%|x)krl&7+>1*gJtw^@c+a_p}347J(kS1l_mol^*mr&j6s;VOzXtbljk^BnUgC%El zEizFW@2O;MctB}@4Ka`7gAQePHQlj?H0`Rqa>DOuhhVH>yJr44GSdyE_ErTvZStW2FoGvfDd*Gt+WN6ns+Evolb z4S}N3#gnGuZ7GG~d24p79hbm{Ve1ODm;^^q+!=;LpNGZ>ZvQqR&YhpsCZBSI|FB}F zwHG^uH499%>C+-l<#9LtUa5Bo6W1-fR9-Eb+uh+hJOlX+s&r=fp1IN_ zHncRZ`_jlG+g7YL+*}9C4Ta-jh3$wbj?I#kD0>iDTekMV+XL5{6U&$5%plHWBw{_G zw3y8;<9K}AkjJreWWGEsQNQBkXX^93y44oM_RIq3smYhhMjZhkr|1_6L*O`-*VOGE2XmgUh}OeDFX?1G=Um)1ln1MT z7psMCc?B}@9Hf7!5w*!=Wjm4886URwJ$y&3|V@OB* z6yp!`MfG#CJ&RbngU-3QHKBpAmJELv&Br*59azkyVWf{;G+EtP)Og6#u~ynDUi|M+ ztw5h1i=ojqYV?YHI$DU4j!;zq$2QB29#B)g2>RKmbIu&6Cxh@@P|$!UEy`%!{?B#$ zss2o}aPRc8|3Sf%DoW*)5OtX^;utL5b5{}(zd@bZ$E%Eo(-HyKzcKjE&brrIqJ$b4Nm|1&|*kYXlWK;5Y^rUj$uw7H>dozu1`T975TZQHhS zwr$(CZQHhO+qP}nw(8bfcaQ#q^)_>4t{G7*F2@W)8N)l2#NvS6Bm`uEl0DMC>hr5cRWevZdr&|{vr`c+$T7Ie`tZR$1Kq#y!?xi&o!y^bEXC>9bv9&fa+ue08< z$ArOBXx+P_QYy-F%5!1|Jei$lsC+*NaKf9|KPhmU3H-~)(xXCH>|;`JnG&AJd4B#4 z&RzjXDE{$GcN?6%mFX5N^_{6s%S&bG@8Ac2+c6~iXPa-^00;p#%a;A-0p2St+ooz( zYQZdzVJlCRo54h?#i38{EJ`37V;;i%&go(52&5cL{r=rU{3IUiw9#>#=9F#z_3=qs zuvLS2VGTV$M;S^Cn1IStKen{_AGDi3&FXvnNOi7!Tl=nL_Z4H}lw)H7!dk4G{rxm~ zK@MPr?=WaRZh(Vd7EbU-@mWG%*lx&VpK~qGb4DL8bSzlEEVTCVsgv=4Wa$`?2k9`u zD0gwVadX9Cq(|4Pg7I+4_yOsQ`X2G)QeU-|O@nCT)~{M{sE6x5H!$Q&i}D1fEdtf- zG6Am%oH_opmjYIX9xxBXauu3szeOKYv){zPmEZSy^d8xn6ogamyrcBq5=}Lk40_LY z+X3-4fAAcfv9}CVHMrC3$rGCbsHoLG4-&U+-b7f!;pQc{_BA$4>K1TykCh4NIo3Wm zBrXTdDJ&u3Bw%lyWpehO0Xsqs$uUM;%n_~9)f>YaVNk<508+itnT2EIu%4U8ZM_JV zFy+7n)fcMud0U2ROO=ddgceQvj}C1*)cVdTyf<8kZ@5yub-Mzh{HpCks*|4^HM;1B zp3_!#ZVWfKeciW=leDu)xZ9&%lH?ne?lkZF@dqYy%%K&zWk}=3a;TfUs_03Gul;Eo zTRP>vjf>W#NRBGT17@JAU2Jv-Njuk$$bK8@N2z`{14K`!x*I0DfCR-#*UE2yazAi$8(=Q@-5&m zw9b9ApphHDnHy&d=C3@sDu-VOeo3@22lfpvsekiLT6#t4ZaqV%O7@R|TmkJqreaW~ zymWgwtA>*N%=VKwIj4k$5y}ZGGDwxgRT4-UJhUoqX_aw5uQf^6k$i@%ITg!|P3p^cT_4YqQ{wg`Nb->k5&rwk3P z+9p7&Y(v&rY_DxtQv#!$MWCX#j$6hbH?PnMOfGu#}l2(>> z3W8J7etfwWTGZ`v2`SDy)h?mXwnGWU2P!Cblxc{QCN3Hy7Q-!EH5-l;;p%IKMTk++ z!_RT(W@UP;S#6C5)3SG^hJjvQ8*Jjz*)Y_=0*Yo1%nIYZ=LyM>`0Z5#dQ z|8%^fOeGlq;Y^%mNV0zG9zssv@7~ee=b`akQ1fC&97f5{X*Qd3e7oBdJ<=FE-A$tT z!BDGtUFGyScfM~c-na5Y5sz2@k`5a5-;ACWtk)6ZDRA1RRBr!`#BCfU<}s*rMgPUH zz#mwr5l+l>(!98U3DYnUp*sMA$(!?DqiIKd>$9nh$j^YvyrR@Pm!7h25hMSS@FSuq z!<(oD+?m#BGf4AP1qYvLNq^FldR)dNc710WQPunMFJW`q`^}wMRaBdxy5)O4uX^Bq zD>zwk;rPoMH3EXIg&bmK{<9-&Rw&G5eJ!)uoYQB?psdj2cug%n7bba>2mKbjMiOoh zb#y;b(rq>2En*^_b33CCABZs!BI|^eD8geL_||c?c6yixZPWCJzY4nzwQ;00*H9JS zjKs7Ve)P#AD*u-?B$S}jyqH`GuJS(IjQ{Ve$fVPzF3j);QyF7CDO%KtGYZd3YwK*k z6rJ%jhol$!Mc@`m2jF}1t9Y}+7 za6>L_z#&B5vmU`3Uf?7y2ko&`)=THQ$DKY9-h&@bJKYzxpk2Z`2}bQ=-#1162o}&j zwb}#Z(oNj``1k;1^(KO6w-{J}z8OEF>s-n)w{na>T1yG_J1)FTF=-iJyrX8!x3G%J zRow?T7Qar5xQ&8&0-b0_-S^b4stsFzbzd}Nc*oRD(JE_MeXSZnxT7#*nfs!xyeJAC zQM&k;mGpM_dz|TMUp!*7J4m?^vEw$n6b8?++LS%`3qp?ee!R?mYGE_hVkqT2 zs?O*a61F|wn&H5#XN!8tkBYwY#^sTz*%qcJU;ZELt+anxz0;3HE40{&-iwRaYL1uc~*h^F~pHarFtT2 z5GlbUz@ueLG0!GVkMQdG#tspbNC`wDz##_DG@RC4Q3st=5hWAkO-Ig*Li7iwmpBIB zz7#S5Jmr6sjs1>%{}>%wGvEv^!h+0ltgd{J$ zWdAvvA?f~Y&HjZ&&-VIjDi@}_jdF_y?6(1e1RI+uK3gCHa~R*-5@!LZ zx*?x|*vAJjE(4aN7q1aaKmzW$r@I?s!s@*>X=e?gv^NCOb|G&>1LJT#Qu;_m;Xt`< zMW-|HN(vN$-3B6!bq1%9?T!+~L!IL?`oM$-Q{XO_5DWQJ=Q9y(CvyORS=P*7gx~}( zk{gGnmW)l@U7nvp83<8K?4Og^_VRW$|J-rydPb^KuoDV4+>$Z(0TOQY*p*%y7L%oO z)g1DsD)beNU^4VY>Ph-u#scQ|b;YLmY;Lt&D>i8M04khX2XY z_KocN)pHr~xQ-p35pee97CaS|mCe}8^WyS(85mS`XSYGFJ=AFF`$Zd^w#|(vQ+?dQ zqfSkNHRKKt8-gs<{B$CGVqS>u&%G5jKFa@M-izyoAIzD|7Q|HmyjsaD+|tce>A3lI zh3+*x95mIHq4Srm<1}ct09N&{Gs_)JO_D{n^UH0zOr1>~8)IKu)!n&Wd6o!ILhhvz z_AStde9MC)iu>$#d26?E!hUDAo;D0WpkVILo{Z=?2K@{}`qoh95R^s8-k&MgijVgD z8J9@rsK@TYtWZvBR5!zM1(sBtJ%W}AZ7!v6`5}JK2@tl%Pg(3ZdtA^?W&1<4KCNvz z^*X8^B2?X{{;QWFA^uJTbH8iINCk*0h7d#$s-9R04TR2&1~aPi^>qJ2*yboRUX}BDi>)b6d1jK7AUK&z5p=fj+H`BXC9+{+ht(9&A{V~P>8Oy;;GIB>24X|nE=dy*)naIE+F=%Vc%8BJoNKYU<%F@m z53(udxLS%5Ea;(`Yqnl4@S;H#EMQ>B=D9+9Sz1le8_9f&)nQ0QL)>t&MW-5x)1h$6 zQelkZQyh!}W*h|O&Toehq(}tZ36xzwfD)jdEwFBhjNk$zpqT>+UT-^VI_qI%Z;U_@ zlw)7s*1^X$KniKj^-oHPPx>}otHuMiSAE!z*t;8RW=%5!lf(7Ywa3Yys7hxPO3yO$Y4_8&3 zs0}(_4)k~Pn`h&**3Sw}ns3W!A7ai;LDi4=iNZF7aA;f6Xq$=-sBqzZA~i575+fT- zQz>qCAwr%9;fZ z(b)pCp1&Ar^O;Zrz_6zj;XYymnDEu?QSxFxRkW~PzaW*X{9y7CF+&f4)&m4WE!4sf zqrTKZ`G7tyJr+J8cu0oio=Jvv#EM89co3;Dge2-&8{U{yp%|3}Tz>92vwU|VOtt2vYs#@Qg{*BU$CjcEeN<@p3%63avJBpe8yX$Vte`UZx%4E?GP~6- zjm0vC)hAt12jnz%qfksluB-?Ojgnes3yL>0hA72oDOS&KhJ?$?%^HboF4K`U`gYxB zmcLFk=p#3zFK6iz$Q$4m?q-L_rD}$&T~ZZx*g6Tpi8T*#?Lda+fLAtyXzQ@oSV6;?@MnE!0D9MjZN^QC}r&iy~E+91*o_{xHc zM>jMA4$HiyrSx(}Hf(`7ZN0)oZ@h5;)zXe6s|d&VWs#_abFz&ps+>dykzkb;s0-uT z>i5e{ZX3!S)0v887Izn<**a4Kn={n(g&4Kxelixf9H)7GZ%^qq>Ibf_l4L$Tj|gl; z4_*(T@a0vM;uCIV3`!uq062t?==6Ux_C>Ik#ii1kfugbtp_Q=wqkW)f^M3 z1bB&WR4^!gbv?TUFE%Wxa7*374GLknNZOVMT96I%YX5|R1N^L5erDLv&H@S-vEI2e?YqQjP0BZ?cC{%?Ct-X1WuK_ zZgy6d0H`t&5!_Wn0 zaUqF-NIKGvf84$&=c(ukG|eZ;kz>qr?k|y8XLfd8^+r}T4~fLeZXHfr_03_F|wK!Bzc@?u~Bv@C0BklcEM1#L`^RUK=# zK+hdOB-Np|Grht;gWjUajagC3ePb+(+H1q|0m~h7O&`iI6~05PJch;uHMfE2TvIZ* z1aea28mo|2oxj|dYTS}DUJkuoxLl4&3E&v)&@;R z#OV*CE7B%*!*Li)N>YV;r&O!FqAr%zMMWd^?pt>QzfEb*WG;iQj++##DnN^G-C;MwieA-kLZQGi;QRZ?BT0A@1sFjx_zE81|HNsDw-ai0 zc|;Ne%pF`x?g}li{xfhu|E3?}^;Ymefe>Yro%QsV<# zZ$D6u6W6>Ag8j8J_8-}l?{uNhZRl<7~0aE%oAs0?fm zGx&iQ5z;GJxi$3ok_ZcYTSBN18D^bW*;0;nl9&-81PZYv2r1SKd6>v+uRz=dOa z3N1h0vn?UWLA?=eM5w;spFA#gr|*e@2E{-mn9$KNq*_TS|MQ)&SdqwX^q-vtCq#?} z+uwAV2`$DGg`H84q4T4$!wviWpKWmH)}QhQw%_2E{}1AOmXGX#g2C1a%FQMkr~QkW zg`Lpv1R$^|LS`2jQ5e9qMH_H-3eOL>{+zlmwd4KM7vk|w3DMGhhoz%1q1435463zS zlkv5Ro8=(1TFwOtKe2mbhow))5j8_2@rMwge^Ob8b>HBSovRCD8q8g!_pkVKVffpP z*iy|wpc%z1Q;*KQ#qq`AAk#y)B*VjiRmC1(-YTqX!^u8j_^z$C9|UvZnfjaP%pri) z^Rt%E*ZDdKjNK7Y-XmXUKOF>a$kY&=5&S&Q-)x_IkC`k?lzL*4B-}zUOBkP^_#MoA z{fDQj|Bd%J0uh%vDvZRt^%uk;Q7a{=VNTe8=AWvL6J0rJ-2$x{sTiZW0D~5izDiDDQSNc z9o4*cvxq6MZmNeq%Ny<3jVotSfn76M!5pUh+5uY%eDa$DREu~*jsVOUera`^09pIf zBf;29(e%ZPvXe)~nA|W&3XG?s7k?Iy3#B80C-=3*hFF|2F;+Du;G!LM(az(sRs_fb zrrbQ9WaAMBY5T!kV@4A})ucHSu)QkKX%;#(+gsV_;2N*x_{a>fN-Fp@t_*|@4@@wp_~I=7MpuaXjib(FtHAyR#W^`1-$b%% zxg#2@WA1~NSQHz0dV&$U!P#U6pef&aE~n3)xTm!SD~~5RMEG5$v!yUHXxk$#5J@f` zWVj1y?Lr0iU{9dnxV89}Z#1wCx6Tg||cNa**NL zxs(#<#1ILtD|RXcGwP zRkj&#g7q1?`!iuhnhNS&JZ}upvpT*=#%LWn8Z;7fj<$GEnyMW;rswHtw6CNu2i%3<<6O2yBr>+wk35$Lc49nVW5v%5O$7FKp zzpLXogsawGSNEb3mH|7V3G>|+s}eM@X_HckPbV4;O$pBFNWe$b_!3(|NO^)t`&$Hn zHWj2^-}BM<0{+35(-S|5n6yJ3vq}9&d~<(^rC-aR54_*p%nnk2$)p*c*Ip-qK74lW zJK>>)OrLXqs^o$DmLdX5X%vDc@iB5a>632x<|)ZyPCpvE^-LcWchkXR=z93T_-D~o z@l#z>-gmfJwh-LvS!U-b`bYv|(@F)JAM)snh4jVjZ=@CpuBtD6-5VU`88WQEh(|J+ zYifZ)+qFzLOX|D;S7ux|HnqTokpgJO?Bri?2t;aJ7MO^{2IfAJlRCA$1%VV-&AFic zn$jevp^0InYKj*pxtlvW#4U`Jav%t^z{$?h;soMTQ^K3l+|#rB7Ma1cc<~@#Iz6F$ zmt9g31muv3E4eziwJ{~CTAUEYV0Pi#lcZ&Ty>_6^IVeNx!Uf|&VdllEx9 zhaNv}h9KII13Q?~_!^Uz<7$~7q$6(n;Z2d6r9PS^s4pv!Oq zkF{9@Z%1ONL~Gv<4<1JCSw2}TM`Vy)RD^{YQ-xImsU@ymIX^oG6^n4t!9tAbP0|4= z={o|1?5{$GJV(xV(`u{V*+YYUV;?pvcteGVYIp+A6ffm6C!k_8Jv4mz8Sce2Rd%X# z;e{_Z^;&RgWMW2ljN^#>sVw%qukt`U^0FfO?Gn&7*9(>EOY&OUmk`LItP?l-9eh$- zi8$JxcagF;@IYR(N_7=!Ml0+0ZQDX7kFg{%Gx>x86^^|~G{^`1piGEQO4@J0g@dS^BHt`?zyeP{VbQNxr`abdcO2a()e}Sa-qa9#{OCCwF}$v z(v2a`8c-`k*S}KDLMG!P!||D4MRi=Xfbm1sMcSX=AZ!I~kC#-(h@)<+2uZT-3KsM# z_Q#HIg{a26QLXn6rSvU%jB87<;&Xu^jAKp^CeydQcFg$4=Ai*?m5e{Po(l2l(H99e z$O+t<#^Zc?>(W4BB#9W4LhTabFsf7b1}qMZJ2{!y8z?-XX80i3E%ga$paD-@U~Wr< z$D9gtlG>!HEM3EMvM;>LD}I&G+|)AR`)!BNM@6LCSTG!R21AE`=d(@*r*<$ zsqr~+7XLZP3EU7H&LRuo)ar3Y)orEUZ-_V5A( z@3bBs-zf6H!RTSey7MIp8#y%~OnOMps??Oo$7)>H5N%h_`md%TF0^kYPS(O3F;K(y zZEq3M+Zn5;TtPHbPxKO$2pcP3U$#W*B-0NxPm26ciYR;3( z?nc2+h6pWE9jrJC%|~xCzQA$>0ts{4I!J$dkBP{y3l{cwAj;CH8gpHr2wptrjW8a6 z8RY*%kQG+14OS5Avf-0r{L)1LX zhyZnHWWtpEflCTf(1>t2DrM$=zKP)76t~r4`>U)8ZnP)p&}i(IIDs;-?yL~~H)-yM zKj3fj96uE$57Q$DS5!3jQI1CRysOME3Gnynuqph@6(FHuuN4nPTERmr1Ue7MsYi|mD43YxqQ zE!qMQyB5tYV?%^goM)uSIAqiEkNv&sbhN4yU6XfyIRTa8*vdl7lQnBs3JH8d&$spV zKMVU(0n$rirr>63-XlWI9Vz{cq2D=zr;@aU9J_073=UV_s{%$nV2LnDoyYs)%w>nQ z(=RKCkk?d}M28JG#2X!?`kAb{isWsF8qW*3`Okbreg!U|h&b_n{m3?ji`%&M+tLmMqfl&EUMb>5JsjcB*)&!U~83+~~`Ud`Q1sErd{NC?L!b1M{~ zRsTYO*=YjHc}%~nEQug3qIwb*RBm|2cox3G>SP0%1Kh$iYq^t=kdc0+BiDG`f4@3w z>5+)H=|@_hhFW1S*kI4uwJ4LQHBp!6>@>9~8!gL}WWs}m@7^ZeY?bU2py-{0@21y* z@d9?6R7{Vm8tOH!4o@nK_D44=R0hV}vkm4*hKU<`?g@h;zd28wC#o>t$UvJK&yz0Eg{Duzteb*b5? zu1frp3}!UPK)rB+p6E_ybmur3Dg>@okF!WN>ZXQn8%E}sB+md%71O6p;@y?)L83Jn zyO6$Uk0#Hnr`HCERH}+XM3)hjYGu~G)>qP*TTK_0F*Y}EE1_-aiao!C@?kLTxB0@2 zzf|t|c9!{8Eb%AVlSnV*^42F{mB(U8&}tM6t~SZ$M1}N=Xsg~n;}WnA&)-@UwhYWV zl+leK$3#pi^q9LiJo);uS@^_62v9DhL`G4`;WI_B8=MpRaWDz!W9Ca^Ybv(NI+C;e zVcVfcU;7|$^flmC=preF^{Elk-rfKpr`8)ijYxWEb$$DbW=U!7r4UV7ant)_6_kMO zJ08qm5w4JoqRXlAkfHt=93oR~kt}IIskH{0&|Q5?3Ko){qXYLXY>$TA=bmsxK}X*N zY~$z#!+?wsb%l|2EW?VgpTUfCWGt}0>k<60H=iabW7vfeH8XT)c&h8D)l2)jdIe&9$KXT!27Ts1BO^`flI@ zcy5I&aGmt?pbU-x<)#iL554*mc&k0)o&^{`8kBP=7)z9v*{l;WrjFi@9tv4KIIdJQ zG?Ex(Vp`mbL6nAR`2 znE#UI2M`q6RC3p$I#%%6t@XWf%W=FiqSBC_^NYNeKxG7tpp<}HqaD+JvPHX<*I!y6 zVL#s&FOD2D*G=!F=eTG>cW_~`YQ_0L4Oi3a+6ZDEB(IZFmwh$6O{?4O=_ zu~!U9c9HEg34qO*+bP1Kc*-;pE2{hurz6-SExLfF7+ruH#Hkp01r@LT;dazd))E^3 zV)DPq*_|ebnBp%I>@Nmy>O&UU;;2i->m2x#`JOvHBqeqNyz*a?1qq!27qY@ODF%&3 ze%XN_=z&8>43hW~bv+3+9%v;@}Mq>}$_B2oT7o5=sYNKTj62WOTp0nR|A zgEN@0F#mUv1k-z*XCJtS#Rg6?i5auWa_usQBipG~KQbs|i)u4B5PoP4mLWqIPPsw) z>g|oi8Ci&EJ}KP!whQJml7bh5hcg(8sKXhQgIC3iYj=+rOf~!_>SoJBKl{KAAJw`3 z#J3|;myz&AR;f^|i>#5=qxi3IK4W-=bLSoAurVDv>}MUi&*ru}{w`^FJNhvs4Q~|I zk+7w{i5EV@bkT|tIL^POEgv!yFdv1=p2ubuXzfW1Nzz~eha@QfZsNxP4KOiqb#aM5 z=1gQVq#IQ;y2&n@PvB2wTx2c;U^;Bu0VIE60piLsKKKC33~l!h%FH?~oZkG`zab)Y zGF~oD|66}K=mUIz`PG^GK4CP71Bv2oqHo-VY+lV~d1!;5QwmdDxwQ6l8%a-n3?afO zVwQ&o*`jCl-iz)nHhfUq+r^_1}>mD(1^G63b|Ms%a^9s!axC)pWLX&|Hn5&^k8fJ0W zT>}XR${4-dN*P3dp8}bH8P*BTCbkHg%v`Z;ZMl6Q&@5*>qdm)XMsm;*ezpf5ui*Ya zw72aQi@`-pFZSz>RlLuKUw|r@8d%mW)9TPLP9Z;e+?YJgnJ0w&iepEm$_YNVb^-k@ zqYI-B({K7G{-wU=fr^CLdn1HJ__SIY&|yy4w`H=8UcL#cKUV#L?#Ndg!`8)s=}+a= z1_Y!5rL~;q55gbV8WBwBGb;Yh#6;Q(f1)QL!)oYJi`xyCprWrQjWf->bettHS|ZA* z!9wis^z)t8LY$<(oeh;J3zZFy<&8FYY@S~?Q_-H8Hj{*vPq;5RNEqh%_i zvbMFu<^lWkp2gD_s#m3yn3skl0r8@>OHAEuxf&`F;inPIj}e#ZMk-SZpG5C5wsYlZ zmXq?v=Sq#ci=C5fmDR)^D>xJ=6|@XAU@kKQ-;vO1vAiyU)uF86?+}scEp)qNhH_oF zUPQUj1o+GoWNMnnX=5XOJ;6$wBEM_%{pbhr9UBmMjWBon<)Oi`U4p^L+|a~Bb^V8I zMiiKP0Y6th=R^jVu9Hl$x}gM`Q7K9Q%h1^eoPLgoCE0mz(~!O1A`Xav1n4fYnJG@U zg%Ns<`8TDz#i)Lun3QcijFEqRdi2J^FkiM_Vdj?As@$Yb9eV^o{`A)UFh}R7Jo9M3 z?9N4~^wR2mJWW57I)@N8Z?8T_d7om)ui~4^$)adZem59^d@sNeY!sI+glD&UmKX5; z!UkBf0^lu#QVa=W@a^G|Xc^oY+$?p25QSMFKJq?~wP}canc>W;+lzb<(EjOa@RJxk zs@D{VAzjB7oHQATLx(8ujs&5a4F%}1UvkOX?8#Yv8Z?i+h1SRE{^N+5;(UKHC<5e_ zGPw4*j5|o+JiQgFXz##wP?HWKyU6xI=$ph{^t%Dm`69r7jE*=$jE7XyB60w9$3{nP z$u=hMwKOOXRdT(Q@M=g8Nk(R<>>M5?>{bik)3=Us|{w8ORUa7f;2O zadvN8H+Ysoc2=Sgks8hG57neqQXM5_3k>(2BNAww>?j$++8<9IEah;%BMvO8IH~IL zcqaQ}@B%v%aGJ_6yh+FsX45;L27F4`0l?LL1u&8_*dK_Zo&1&85bex|f}`TNW{gLx zx`1T7Pv4XzKB!JH@Vj#pehaeU@}+?_UHD|bw%=4w%I_thRX%7&9BRZyeVb;#r46keu$@{F9 zRI|(7bU?)>N3TywFEGyOt<_2$IGeEwK(NI5V0%3=yfjOOI(^hC&h}aM@LPzNH3ux>)D@fS zrk{sA(E|qQQp&9Br8^|07E~A+$?LaWQ=Q0vlnN`0HVbu=A(T~!ymFN~(H;(F4msd> zr2&oUS{7`?x`X0VjYrwXEE*e#TBYpAjhH5*XZX=el0Hyc0mr(-zbMPbK)0!7y1&+n zn{CUtaK%d;=PBrP;y_Pn_z4A9mdM{dOfz_ZtXzo>u=YK{bn)Rb<+wSmhJ@|ma}wy! zVFgWdXL3b){!5NPo`&tR<+)JuaTd>Rz_OJ6q5Ib{B>pyK3!}(vw?`*s3wW8X`=inJ zK0#fO!8XF^dXR^`G~%+6xMS$ji4a>1t+86D8EDf>jqfi+1)IZP8$kjNOCe*8a`)5N zdH(%o$N0q5zd<1lS3PATLYE(6)%!ICNC8a$1$tr?0Lc0VAVK;Y(SMbg|2xtxYz)jy z=!}g1i}Zqkqk5OsCBSjWSX6%S|E$i!dZ?~?jVEgV;ek>zhO-qKqZAGkjH!H*phVbCZBM`5`n4U1_#1o(bfVAz=|}F~ z<<{l{8bQ|q)`?P(#Rk||`_6uGRvkyzvfyQC*El;H1mbd^)g9Wu*>Mh@JhNZ#IMJ0g z2>OpPnD+b#Rg6#Z1>-@sx_`d*b|JERAR{ak$5JuG^r+MAqI8i^{Ecp8I!R#oPj6+z z9{NuPOnatafI=@|AYv0hiibnDhJp|wZuE$7w~ZPmcezl*yZ<#lK0%@18TBpiqiF@= zM6{Kz7wk7|`VtWw1XuGHf_oDM(P*9`#qYT>Nb;xN?~`_erVlt# zFaU&j{YM}Si`uwEqk(_)Pj5UNMu16N(PaNB_gBAoC0qe&_4Kxam`wn*yiwS^w3}*M;Zq zhx4ugZt)^jnYrfZ47i$_Mi?Yopn@PgLl za5QbhF{o+%xzeaQCuM%A>Z_}3u!A8uAq4le;U(y&r8I0qJ@%HV6#3g8LapZE%(W5C zMrW%Cqy0KBPcgi++c^3!JA1xe-FbBP+^!^(YAWBxW^eM$>K3W5*lJ%t-TZX%^$L?_ zuGmFx?-n;~RC#-H_v|#FAMkHt%y?%?aFRMf{8W= zDo^&4V%K^3?EiS=`3s<}t4cWqG6eom7As^(P?&{WFWT z$K-9hbfl7iEuVp&xqAho0N-7UY~$I{-WiZfb?LIq$>HWvr!kUMO)w1YM+(OJkJUqh z6EN%}VK6+#I|b7A31!9};iJ>{+8zMw!A9u#Ta9|^Xk za(*idHvjdb8TgRd%lUEjBXH}A_=_HMpF4R`aqrYXXhpR!X!y@T*XBYssB|f&P?>xL zX<2OMLR4D$@)AB%LOtwX5F!xS*@ZbS#?a*Ax6U>ZjQfWiTOCaz@b3xm361xY#?#_| z3kdrIzR8E^kr2z8!15T*$~GWiYmn-VKeb$Y16NnzI-}i0LIZb)?Xfec@g5LtA5kZPqsrPSq3I;9oq#`tz8~=Bh`RBSK`|NG1y;scs(6>OC($s<#jU2tk zmBDuzx<_i(i!3>zsB&CpTwX(ocV6!jzkolDn z6c8WHFyK9BD}w?4dR$Y~Hem}PiSL_)-9)nyDC$+3?l0qd-fLFvo-w#-v8*psWUO1M z3>-geqAiHeRH1uILZMb`T}LYKC|{G>0L6Ss5Jm^7AanC#9C>;ayONr~DN)DoA(V&_ zfN9F+n<@M8N3g2+231YU_7;sl%ZUo#?%Q=hPG8`jI;G-2O+R%&%y zo{&fO>a{;9ctmsAe;ek*16kwh?Xwqz^@HOd4{v72A06g)fd&7PxG$e8p5$zg4is}9 z>{X-}1qV@JX3BbLxj#q%d@91ApheivNCGfBYp4`Z9s$Kw+^~L^cp0Px06OJaB~$<; zeA=0}OL!lSAKIpu995=KJ3^vld8D@>nsl1QxDM(H3J#hKtLsjeAC30%Ful8D;j~F# zc2(PHa&!pjeGtLpdy~!A+YK17hS-XIXO#`QZUfW<{IWc!H z^3cOTI#lLp8%iP9L{nVU_Pwyd=L5`Qtp+Ufm+xSENG?7F5Gf3^%bhK4BvdFsM+ z4WUfO$zyP1BZxa#ihZt6@X|MNNaBeI z^0DOeVSfSTN6)Vpw>RHU|5?aH%Ab4*M@k3Px5gSW^sX) z>cf{olI)Wn{TmZd3Z{r`2tg<_|Gt@U!&Fnj=xaJ~|AqC}t|}N0MVQIR=K#dRB8`4D zBt3>bqDc&v)73vPUv0Q|fg!BjkO;uz^`Jr2F6{CTDJ{?0H$;cJz2+x^vu?f&2BE6p z9WHsrM@4Pg<9Wvl=T%kocdS+)^zl>NX3E^sQf)KrKzdIOD=m>-R~AuKLcGZ9ly@Te z96vg({M{bz?EX!Rjo$IW{}A3zSuDW&a(mY=PmZcaK9u35<*L4B2w-_~)A`)4|DZm& z?>)NZM~!g}>0pQe7SW4`o1vdSSyT|BnyA-Ap-!vaEYZ3ID)J z(%K~$@9xNEbAm)uz~$T%AFj^wFXg2_o8ZX33~12%Mc zo*zW6@SlR5woC|kps-=S98nMC97(S=@G6{p&all|35fQ(n-q5b$e?3js_v|_-Pu}= z1!CJJW9x*KXy}MhqNP8=);QKb3*6-phgf+OANyVK0XDvBWzC4U>N<;M?3*O@3 zw}*`q|8AAyj7C|As6;Y&cw+KJ&7qvHTs7CS84y%rWLTKlId8Dd3`j{6Fhzv^Zj zY{ceMt!AOc6;)VeV|!X%byxA-HMtkYlNCu9&o^Pi9KNe_BmJg$!#|Sqx)rAksHS5SS@{8i`qTE6b?vkw6ZEN?06m~ntwJlr_Ftcs6u&EB4AEEbY1m& zXuPSo(bwoea4*l;;n>2K8^r}e2hTol-La0gL(6C7fxjpMkx#cyC!o~4n*xd|IK`>}IK^P534#1j- zX}nE43R#Ulq{V)ss3&xhf3l0-Q%IX+e8oX>cP@8}h4GcO=F+_V-Bs$bsi;A_us=7k zus26B2y#hukb%+K8tq?4hz*bixrB%6$>DO6dlKE>&+ntjLprYJYDZ7Xi%;IQV# zZ~!93S-h~;fmxcNhS_P>Wq7yX|9DqRUUVU}y z2?`R`X5CRz`dx_Guh_BBoP>{N;EDSI=?)u_Jm`R9US9*!^&n>XM-a;#=FaZ?VgTk7 z)kMgvi3yq`4XUQ>r4g+9kYJKwO74ZWBp34)hng*AM~KpT;;K_s7MeV!0XZ6k!!tTxMbYSh*B8(SE`4 zXBOJ-d}^AV&-Dq4o&EHDSQC6kz2MbRo0|q#IWh7ivqw1hA{Mgp?KW6S5L-X6ezVb@ zhTT9O?)8lbk^+ z1(?)uHj*p*JqiS&88F9HmuXby>Vh|P!P}IELc{ubU zqhhO&uP+H4-{)+S$|#CX^&WodYBM6EbVp}^%~EU(yA+%dq|~9THv}ie>LEy}l9pYt z$xS`NRJD%4Uyo;-at8>oov<<0%Fb8UWXBY2o`-zcqjv9;1iZgiGDrM?T_ zF1bg^r^l6`EO5BtUT|csQ8gc0vD$y$)G2yYU7STpLh>XF8gBW$cDs`t63WIpHx0cx zA_qk+pG5KRy7-2V*$=0%)6qAHyD#H0_Fl@x^KI#&GNgt#WP%EeDyn3ev5zRWsL;_|m!|<&dYoDk5>FH`OxYd!?p)_+%5g1`VOvi<>y6T`w&V!vHreQ^ z2!3JTJy$IiMuBh_HN;^l@KRc$+W53o+C&P{us?;BP6LpSSmLpb-R`;!a;92^-b^So zVKzpTmL8h;FLdAePMtX<2FNJo>WtK(GVpD0w|cui1n@=QYF}wc{v-EvbMvw&Pcg0| zTu6+L6g>7KK^G;On`m(Em?+>vKI#}nVQnQ-BZszDAhC>MLWwkIzL625Y~LUUnug2b z&l5n{&A~H(v$8$Pg0x_4Ej$13MPP*VG@G8Kt!s-zmZ8q<;zyJYU~}1;m%nB|jPHVb z&?^|Z?24j}H7u+GQNaJ@<~>Mr9R>VOxL42(@iZ2Vk(R zG{<*SI^%cF;uqm^YhX7Pi(*HS{zX1@35uv~Aws$tW%UuqEOPYjMpmiC{#6q5A_Wmk z#A{HlIpu1=oH@+d12O9Ot18n0EXz(pj8hxxRzs911=pn&U<&e*_g@jeqDLrEbQCcgIcK5rQJYp1-q_l6G(&7JSN z&tkFbO!$yo*2}7xa2_7AD{y|z!`4HO$?jY*vwEy1KPfO~HaA?Qy{D{en`rgZG5vfq zrGZu(=qybS;`Glat_VMWq)H5doxWXQ2>d+fFuhj-wR)v_|jnDaQT&C@wLhxY(T-8cvf2s31mgxoLwR9$xFnev?SmV9h zS@;b&zL$%Gh!+c}H6aVkd@UlIwACK`;(g(~2C?%mm?)GIstHmW%~cAh4Em7bCK6?x zxG_jmZ;Z*7>VZJ-9?uru`rdJkplYTCWE-YUCRhnjUtKDvK(o+jG(L4YbdMOh2OUbI zS?Fl3N|f%eQ~h`>Q1kCGzgWKEs|j})3(mvv=G8Ciseu5I`Ke!{{>5vWS?dAZadu6C z^@N@1&GIMQc|e*p%=6W1pHZ_ty{vKxbH^WkC1LVf4xBVHKt^?0uj!SUi40bBR;#!S zUQ}1bIj=-mwhC%|FL=vBc8ix#aB@%hH9}2+ZOc_loP~p|Me&M@!A!-)5~e6*2)8zE z1^L#~l89>kQ_VA2aXwiRFJCJ&*g}X_Ti_jy_s*LAjPWI`c7` z<~Gx7#@qo9OBD{o>-98Rb4cRfN~-)oG`ZvBPQB)c6z=%m4`uavgADU=7!X8GXJ`x$ro+mLJ(A>lBd3|33uve#_9S8L}qp4W9a=KK^l*-t5|HeP8faQPeDP*OkSdI z7<2p~-OqB2LV(_)5)^3WfBh^6^8a2AYbQ%fy8kfsMV`R!|1kAQ`N3ZdMnWvi{694L z(=2^J904lZaAS)G@KpW!pxroyu9ziSo2fq}B3Jxks6~MwDSHP&_T53|z+4r1g|iqB zXEQQ60(08rKw!ziTB-xQ(>>qskNdsn2%)amFVSr_8T!BO4EESwoJX?iXzJ4Lh3xDl zncLHf)RHN*WXTy6ToV!wF@m`$*a(04m`X>>0#_Nx#>+8}SsfwTM+*@es52>xbx)Yy z;nV&S_~e@x!8#zt32ut)z}l`}lyG9y&&oX+Mh1_(9S+O?LQ9ar%z`SA@H4buY~km; zJ@NZYJg2~QLdgva=+^BY66mADS>Q+)WCA{mSPdkR%;TDq&IM)y))%(#^#^s{YV-H} zeMXT-CVqC6*O1>KSQWU_d7v17<>rj3o;8DCNuvyNt>sGk@5*QOdAzHEb-oc#x(f{%77YCDg?|4XcNU<7{ z5hI7YY_|kY_iYUo!bBwGTVQ+xHEf^=zF3GHFjArcjcAct4Z%9&&GsL<1t%%Y*1gcr z3>0+ZNtGN!o;~Z~Ak@FB8GQ&8s^|NU&E^P9nLF-&)aw73DSHC+e;n-3@cnGz3iPKR zO)Ri@NG&7|&X*)~eBYqyURAYU3>y<}DTq>(v@o7bBUWqn|FC)R9z?I+5A>CJ_GE*8{E@!y|HeZb?}u@AKWuyJJ%M70P|=KV;7Y`rABSZjJ(5+I7!4_!}ns%X=s^WUTY@C&pDoFJ-#JN*Cm(f{v7Oq=yhlrp*i zJf?pG%%Jo`r#;C1gu=nxy#2b33!gV1Cs0OcLqd<Rg;wAb9U~V{AbxjyIjIp7&NW! z_K2||$Zb&lH!uTVosR$C5_|xG3R9eVPnjL1OPD`+mj&)a0yP4FQSaXuM?C;Kz)|Z% zNI@|~vd9e6lqux*AlWHqWm>Yj-rEI-J2nqAzhzuz+~%7(rd;t#tuG3xi~ch@TP)6F z-U#$ih8`8dLnMMDd&Q8+abA-j6$Ip4=!Ix4bt=71uRszIHVKbBkk&Joh$d_8QFOD( zhKA|s)brapX?ObwFluo4Zk1lCI{=+L*i)@&KmY2%1j4Dry;3Ll<$!Svf*xE3tAux5 zV|+jfX&@Wl5U=xg4BeZewP152RmB{M?mNdXpD6z`zq^-sQTwgBeOo-gQNePm<-XO} zkRA}R7e%iSAn5hVW{AzE;AMDJJV+t<`(r&vh<26c!531tVJ!W1{zgpi4oz(2%O$K& zSm=VNRP!vio2$KOZq@_PBU7E7=52DuGp_E@{2g}rJH6qkl-;(o;GO6N&y6JUFO@gG z^U;Ypn1z{V37Ie$DlgfcPsrE%{HGJjDQkhV%mwEK^+J z{S*q6fvpogGY8xMYz?__RgU933&7(>cMuHD!o$`C^O9R z?<|wO8V}o{cTHi=x3yzk^u7Hvx*Hd}pFR?M*h8QkZ7%_?-e*!8<`1l+J*q-On$&_T z1k^9SFvmyFcL+=zTiskJzgXWgwBEjH1ur{U7h?p*j*T2 zp8WXw-D{;?UR^zGUymnDf!>|F6CKf^zjM{8-w4Za81>9!$hAa-dxxdwKQ{Q3=NgUIBL3)Uv<*iS4XKX+SFl4~q- z8`upEOjX{jsr8EcQv6E`tlM#$DBju5c`n-%I&cs;)X(7l?g%fHMj%4t_J*Vi5s|vKq7W! z$nFd+`9?)3*?io@sws34xd*`@5~i?ppFb{3-ayY!TiQbrq1VLvanU#dz8k$Ey2}T1 zWN);W19+jH{YHqF2H;Egq=c2*(x<`Q3yDn{4(L#5PyumeFxsxkDh)Jx*Vb^_3kr38 z%@L(IU>M!&PXh1UY-OeS(vCq%rG3y{tI$Jsz(qvcUXOxNltf-ESMug1iHCN_gsZt% zjb&0g;mS*r8UX=564LACe-$xsxtSE~+oGXNHpSl+4;^75N*%vZNnb-C2J!*7iLZ9q zN7~;(J2CD0&Cz?HU=4i2wLP)c-KT2Z->&gg)mq;>ZQ3%{_`0fJx|xga@7ReXg4TrO z@!Mq1jON~jzSwp$YaQ=5C(73d6&X=9QhG+r92e&q6Gx2iCNOq*i*g;zRsK0latHP8o?l9wlb;pP=xKptrq$4y>3h z*%)&Zl;qd2CRqnLZF{^BSd$T+r_{{tkrv*lk^RMe;JSIBFO8)!Wj7H>m<1IBrHML_ z^okMrNriKkH0y|rZ0kvg@E5vkGgI3*S}o?}QLju_^ZTH{$-82q>W7H^oeiDfQ9-KS zUDBRGI~C${zy-{?f}XUqE;IvXbT9xJ2Z@D>l6o{)sWVHx^rYA)9yytU5mSwlMpDCn zt!J+1zk`(#k*$pm537h~nfrR7TF%x~!?7e*Hs)C=zY+_Tz8(miSg4h+cg|DL3|28T zRI^D=Y5oE?#o2R$mWHNl$@WQJmaiKOt~;y=ltGeAAoF^iLv?&^R@jf;o5Bd%TGhro z#Q;6UWif_`F2~AYmPU8>aToudfg(iGEIhNy6tQqYDyu^Jtp&;u?td??e%G); zdW%}t4X)1^s6$78UrjtfY~V69Wmp&1VcgDe!A6_BV=`3ghG(h}m&u9z+eO0B;Zj{z zx2lk<-eo|uVk!0GW(GqnfWbzH*>tN2JGAcaC5dJyT@LFH^^vJY_9*IB7PBGxYBm0^)SQ1`Y~m zZ4+njQUlIUe}{#jXncS~4m4DL+^_$*t=uo#_OGsYKR*qIcmL$ruSUAgjPL8lL}?Q= z4tX?EJ}$T~a356SC9c^uQVVd>oh09-k8f<|bMLA;v2yKma2-n*XEJ%Q z(mQLXReC-TT4p}0Wk$m;54@#n#h9;MuE2qnmy?vjB>DRKHD%Uejo@+9W3F0b(`$P7 z=#jlsNt%8EXBAz0+l}Ajl%AxFa%p(BsGiOicU(f_$A~W!8wCyNPlpf!44MQ?pv@}# z=YRJH|MiciGI^d?`3u0kc!6YwN=z>-T@V3pLy6;v!W!5}MRKO1RXkG<83h%!PXJMu zS0-Dm!CI!wnVDBn#bEigkZ*`h=X97zt1cabVwp(n2->5~#Z7H^ygA2HLXuFZm6mKT zPBc4(7m8kV;}>!0a69tX-8Y^5rzGXgsf_0OR@``F&7kw_Do^HMr1RYdTi@0Lm(2e< z->YaK(3Ei?0%1My!k;N4{-2gc$H2zQ%Ep@RznKf~PyEl!r{2sV1i+Y?S@>Cvb?)0z z`X)0{Zz*TriqZjbU26@-muZGuX>Bk)7NW=&lP#XZ6Ei^zSA-;*NK>pP zJkfZD6G-5Jdx0qubD|LZZ4+$~#W5j)f%hDp`SE)h&J z*0L&$Z7-2C2DG%k6S|}AQD_S)A%v#L|GM*^zk||PKghwdxbdVp#IzO|S~Yb2|1f^j z(=+)YGTRj|4%bx$Sv=cT(pV$V9-rQVrW>JADxr;y=J8r+!sWSJXo1s4$CZ1GhZ6Awmb5ZqZz-L)bO%gX~{L%CSdlJ?^~1VZG{H+=L9 zQ_2YGl$%DR%D|<>dbkU%9p0S`G8_v{WKJp9Uwh^-;Jv-^rgeW9)q;+4#U!$dP?#j} zpE_V24~G;_<5tnkIZ)66CH1iaGDG1`d`%aZ3+x*J{YG4+_RpA`oB|HrXzE-cS3XG4 zN?Edg2gU)*bk;cl^o@h8$m6+v5V{;mx?AU2ulTuV_$`Wy-6{?f`>#;D1D+Ue7z+x^ zoz~xu>f&&d2M>hg2d^+TX+~@6G{N(A+EKx<0cM3-4o2~0Kcq-tQgJ5HyS>rCF8R1r zJ6O|ZOZnc4okKLY)8bK2*1#i2$BXivds3i|^4<8uTK7=gCI*OV>hQua4QvY!|H4Va z%FxU>*wond?*yS2bPRci{2S$L0W<&P=H z>?1qF`Uy!ONoaLW80;xStnUR+5M7|)I|q`rG?Dp>sty;l!KVFTy_{-vSnmozimR4a zxuTGYoh#Fm6%&~iH0(E%|3|goCH$Ng|9L6OSSdm;dhrAB(3{<@ck_<}gqImatr`6~ z6M&7c29Az0oq+PsVmM$E+>MmC17-)bxH2i9!t~rf{9p%f>Ef=);HjBPZP`6uvhPhw zghQY+zr1qn`fMJ{K!sJmc%(J>;wfzy(hSMb=VkazXv968BCT5!8CN5DBUsZvj-5f#t**doISH&-DQ=r=_lSh zTP=2i`&3w$>j7r@0Ujlm1e0gna5nvoQGOywb(!~y$mOL}yv$NY+_j0c7m7QwWee>y`=)A-a1L}73JvjG(S8*v0W(EiFg+hbA^`0h1bC!B?FR z#OP!M9nV}qci|vOUPh&`_kHtPW02BL*$~VZ4uh09mB)unF|qZjqf_u?3U-U)`b~?H z5+`zRtd2Mjr4P=;e-nmNH{l)}4J-GaiNHqZG;HyqA$rg#@0%;Qky zGo*4tQ}v0%%`I3$E++1A{!AJqa;^qLtr?8+ZmqLMd*KM6W39`nqD4s0X|WJMl4+kREHcFeQsy`IV? z6`(S|nUDOOt_s{l2RYv6Oi~Xl{&2)iU<=T&-Ofw=(-j`0C$r^VK=#H*1e|xa*ekl3 z{DlN*)86Jn`3Mp8Ghp1pm2tszDI2rZ+aCiS(fz~e`gWe=;Dk1_t2qNE<8`B_7*Ipz zaA!qsU-y&UD$jdA%cnX`LofYM_<_!;tJ~As1(F;;p2>r2p;FH8Rg1PE`^Tw8hwe4* z?2D|E-pDae_bY#LhCK5hV3i$Z{`lS%z(OgJkIy;&Y7n1c2cV*~2IrwSoKB2Zmtwi< zaHlK3;_w>_8*!m-`{1Ewal3P$_S(F2Tfvi*s`K;=j=?lc)maR;BXn3VttLrpxOVwV z?Z2e4{O&vdiSy6#U;N_mS+wJPl}cIuQW@29oqpp`gMwNUNvAV_|FFR~9`C&ZZgm>M*6=Sw4s}|p1qO5|6mVU z!|NXZVGonDif96%{~h&~MR&GwJg}S_hUWxSdl1oSTuX+oZv>sezHu;| zfeCUXUc@$!$!d){*EePkyPU4FysN(Nze$aL4<)eDO(eK_OfJ}R&ZYBOIf3vX4Y-gi zG5xrS!d%$BcNu(+OuZ(C4?P3JjgZvdI;)+IAH({q#eMa7Ib#wy|0JTq93x(vK-}${ zq+~4h-F#p@kx4yRTmY=E9JyDazJf^8N0Oyubiw_DwT3_1bfl4pkf@*(Tr~z5DI;KV zEUj6epllI&(<5Ghi((o*wY!Aa5!+vBXJY74_-bah`fm33@cXpv41B2VKf9;s>DH&6f+crb#wJ-rs4*DJD|ux|AM#wNX&Zf{ z{G@!BRBEt%K)RJ=41c>uWxL= zYDl-mRx4_^*ABi- z^Lj#Gd~cAx0}9RxVVi`7%>(Lq9(Wb(s=N;h6e*X5njWw(yIEkdB5UU_e2qfS?h`@y zXrHQ{?&ixj-?A`_w@qkL&^Z-wG9Y6~1~_ECrkE#nxUwRU&Kjz$^l4*WC-jGprW=i- zu-m4J3SpF4@D^`7a>bFX%x$6gbJP9Xe}qBPL#byrk=eHxN$WIHVy;z_)%za%n1$|aeZCmodYm@y;q8(@l6tJ>p6&uH?YMPdXSD65fV z3ftD5b%xW!dm}Cg#X-&RaAewI4|htehyqh<9z#%7tTo*+o>Uoyg%immj3EEyq)W{4 zl}!bcOKsV3z+>|Ax)t$Jq|yhA97oCQBEmopqqi|tdNkaYs%=hv=J~>w@8SBlFdH$Q zskMJTwm$;a7Ol%~F}J9cE9-1zBKu2_4>?+nb0n;#b{$WvHI ze$|O)CwApD9{A^td_poR*T_GApCQpps$j=%(%O8hw|@OzPpoF*4pA)#PD7w=!-)^L zdPH9n9*qfx$N^b|3#N%P7%M?zP#8peOmVt{0}Vhl)H-#IR_VA*0thkpl1oYFZLl@i zzMA7USg>%H&i!IsV!@=}?U;XKUY+vcECQ1Vdz;Xo2-0|5tXuy_$dMRFG)MmL>a0vE z%nL44mgpTo|9Gxe(6r5vyTRBlI^}^)dtchp7Z?<-KgYLA&dECW>u@U@4Q@@t^WitV zo&)LM`(m^a$zMQJ8}qk#RO=0~V6F%qoEd*BOOlQ~dBEXX^9`(ui)SMo3llQ5^ z{;cn9w&)&ayf`3(3(3o>$0}zLbHbd{dS!*_;?=`f4&cGI7MT`=flc>oO+`(_e5PhQ zPJRxLFKuqDRVu8hWHFJS^yWPXbRpuK)mhbNe~9I+t=(XR$}2=xNX>`yc7+XuRYs66 zjh%h#;fXdU&&%fvX|bUOirZ88wb{J9w-Nfc2#7P-9lFB#(Zu#7Zv`xZAoLQm!tZpo zl8zw+U}S5^0xHbHy@iFes&uVBEwU50F^E;SF{x2HW^q5gXez8Oq2)5Sa2%Gvxk8c-J2cvJ9^kl*(e^ zBGI|8F2Sh$Bv4Im=r!jn&}Q+|l=-Z@+PxjFqfw42=gRGpZ5y{{zR{#QXXjfnTPBt` zJjoQP_ERQy$rS)30+uF$a(=$<&exD}0MA4XS3}kUL~KI&Q+pG>rU>m|)xU~Q2XYTq zxs^R}Uxt4IBybYZUEwkeDqDc?qv}j~?Hk>ZEUus_5W|oFkxA&+0x4U+b`eQoOsT%w zDKp7`Ty1?rfh`3DD|2g=9whyjmeYZ9VI%vIlGiW;uJ-Y3j!vQ5^4|%uyYE|-N1=Z` z&WiRy1Mqg(ZvQy%gUk~5BmEZi8sgI{n?{|BGD&qj=!7(~`mIF@?Nj?Sy6S}ct#soG9( zT&E5^?S^#02bYMXibwnK1yxih$@{r@DtMoi1pl8p>2G9QHRi zv~VTpAT3UmCpA9tNd(2HC4tqL$Wn>!*rc2_c4Vl-h!Mw8u;d}Zk0Irwa#uL7M};?b zqPq;|Hwla7R&!(P1{&rn;9<4auJmzZGBMl{w28Zg@z>$gj2SUlX(U_~LyrafhRgVm zvauJ568_=X0>`b}L#LDF(#mEBTYK4B7Hv3#Wv+$URnB+85{IkW^BL(Z59J8@&?=LF z>_&|AqE5|5O=l_Pcf^~rlpXoX;_mca$ZRo89qm zrO<`ryjVr0iiEwPi~ZxhC+3@%_r!mXdqHuCwM1y6d8)x^;(Kze?-AZ%7&crj%QO@U zDxIlrjdx?_f`lDOe#Q#K?si{Nbuw&(I_mB9V)i3^JvJjLs~sq?On68+idLSRj&mjl zPDjqkbB4(1yb?Ii8)IWd{lomQ#*~#|2VJAL4QkXOqSn@o0t8ec^NavV@L!+*CjGCk z0ky-gCT@C^Jhd6hMhOl2IjV{ zVJ*`ySXCrouYNW0)=T$wVZAe)wgr<^>to@lU}(8U7jty!B;aiHkK?aI1l-+>M&krx z)r!W)4|@0Z46w+AY{objD`3Z2E*~9HCVpq{i!z>l@n!TPi!)OsjP8)sA4((iWh)Zh ztma20V)^IN#)p_^AlkK?`Um2Iy7dRyaoMcvE(5X6 zpoa;$|B>uhH1^9qr7YWGWh2AG1`U3S(iuPXTF+m-tsPK*W+3jF=J`W2XLH*JvdWy3_0NBG=0RJ2%_`<0Nyj1e^T zAs|e2Dq~-I&5nOCbYqgTHga*S?}o55od?=A&Jc~KR*?0#jxoBNm%aeTZkM4WVIvdc zV66$n$m{ojTkODM_EFe8M|K-E@Vv*VIG|El=zwOE5!G8HBEA0~LD`K_p@XsKKz|^9 z^%++pA=Xq)JZ4LlymCs4qp_R4S(e!pl~t8yh6QqGt`#x}rN?x{%;I=ZS4F1Yq913i zYSc{8P{}Jh3s+sdE1{Y0pF(->dhdsDSP+)NrB?H;KiQ`uS!|$~iAXK&|Bz4}vufuZ`EpLQQ4!uoE3sM@I@qs2QbP9&8}ZH+fQ%>2Z)(dSt=<_Zv9HE; z)7-)vaXj%XTjw6x65)tS6W-#zp0MOt5~v*f_NZs71SUH_dk@Y3HE@s2{PAHY#K)jf zPzOx)*8Wp&{tfz7o8n!762AIoU{Hiqr)Qfl6;r4Ya`9vD!cRxP@111LWo032U|(nL zAT0{@WAK@q@?eGD-&&3@O&<59R?6lavKzKsRII?HaU1jFW-&JQU2jS)g5Atly|NY& zAu!gxr+t26y-DT1rJ{3A#opj+bTv$#4olvb4KFBM>GP+6ltPc6vnPjgUSK%#=vco{ zdV`KP;w>Sr9#s(rO51&<5x#%KrKo|x_?3bvSLO9UW@exwzb1Lert?_dQiCBnXUw?1 z^WHGQ_HIQZA-FAZyl;8+FU5P#&6YcM30!zwBnEbe@2ZxlpK<%<*58RFJ`1KT0}+r& zJ-=rG`Keg$OD951YW$69i3+edglA5RHRR+FdxH)^m>HvQlHw;*l&^8_b0i`vmsWSR3FK$^ ze;q@3Zu3U29__ppMeE7nF7GHEAU~{OFT;1HuMpAznhYoyw{w<4=7oB{7 z=m7Hol+NdHUPP-}qb`CWV`+&f83?kH=F=Hhsd2_5LOE0Dg5KDDj`6k;lwyQDj_QCR z2*qg$X@s%g8Q^32*8mxd?3;28DMt(+M^^ACg3`3EMc;BnDjKeM1+e(`+*z=+qxJ~p zV43?E!%Ln5Y>k7M)d408fPA^OevkvF*B{}KK($)U%9$jm(!98&BNhuz7{JnkxPquk z6Lh4>-bKXpc>-Jflw&t)u8-*wh6~1{)I*@=#)^%SDMA0$eE|HW2;Q#M!#FMaC`sX{OWB2sO{ zo7Mq+gJLS?V1#k@^pN|0BEgr1%WN|E0k1}W@LStm^+2mUlef zJ50Mn3&t{-6j7ZX9!cuGDbf4apRi%ej{UQ)Mt}L3QU8>h`wu zDXYv$xio!uWpygnS}N@5C0^CC-L@aO3(yjG+d9qJIaI2(rr==UKGi<%DnO%9F>^2p z_1)hbn*3X3Sv_LBQ!40fV^H4EWJFiAvC6%;>7VNY*Lki2U;DCZ8O0Q_W_zwM)lBL0 zx`>H+R$wB;CD%g+TC0dZz6D0X5xdgPgb!JAiv$j8II z{TTj;3zB{BO}nK_!G$E|IvY6Q_`;x&Uj*lH9BP?O(X9NS2ng4i8X8C8PePx+j-YPqi4d@ZY`@`rWTy-*np z)9`)qhy+%ihJj$8?0YigBNg;9ITK}_V{YM@D=7a}BnVg~vir7ZKTGN0za(+@*s7)$1CL`sdA1c5&pQXtl%X zX{(J#Z0#0(f*@dF_b-0RovQ9@YGa>t9mzDS8(Ax7IbdU#bRE+5+Qy5x1FL~?D`FDD z)T@V8rR8dY+p~(iWxm7?h=n5mlp3eNa98d=K^JKOPwrBB;rn8MvyPO(XtNF1P*BS0 zlD4-V%y9$||31s6S1U=D+IAuAeww^sf)j<@G|c~MKeV7|b_Dv_kBEL02WY)B$<8!K z$llXfkWy>%1Y&u9cS%h7c1cVa|JOH|e|m*fa$OWw`?5B*&yLw^w(`5zb!e0Ubt7K? zCcDozZTac3JPNzYUdK(jO;+GKvE!(Ciyk;ni+|g64(nOQG3%&kPx_486SQ4p|7-{O zO!cvWDbb&9#KH;eWu`BL)_)|A^j6 zyl{{oD=j9W2RWl}^`slmcGB{{6zU+#=c04OMqv4M*tE0Cp?`*;W|1sUQDbwdTDEDD z9GE2P|HjkaViBc<;N#ZiKi4{!5r^Cy^nagMy%^y>Jk8V#xM)*k}A!P1NL<-&u0-&Wpo3QR)vOh1?rCk8(Qstzpc_0 z-R7=M3(Dbaj8u(@q^Oduz%FIG=*R4gJ_y3#WH1b5Dh}lh!k$S-r=`PO7l7I~tlOwK zF1_XG?gMvOo_5WExq2ov<&B!ORw`<=-biY+f_G3*qr_}_3qe!}MT1z}WM3|bnEG$1 zTgAgsr}bqV%u)Dx)_eU5`3w4`W@+ZMSynw=`;BJPT~66p*a#lh_98Zz+WeaW^it;- zkSd~Z7Vl|lg-MiO0&-+jk503A3EWiG^22EoMuX>Zu((Nl3L}p=9}r}UtKi>piR$z} zh31ZlcyMSIs$Xq)T$D^*8IX^*OtNS-Me~-O#?x=kMW7Eo7$+c?M_M~aGv>?=U{nf~ zgxw;y&nhn@VMXT zh=2WKke3!&e_T}$!pRsw=TV!#q7RNN1%lw*ub5I!@j3jPxyuKxh@kVrR>_YB3O?$w za2BZ>OoSRGId*6GnWr@IqZ0Rs9(LgS7@7%b;t}U4un5PpHu%X=+ni2Jra|1F=7@WR zmJ%Pq2(2WN94770xqwd{llU7yyH;Pia9FLgOTfy@h(`TW!?iU)paCa{1o(0lw?9=3 z_kXMSzv}&u>@Ss_>!rB;(Hl@!VhDf>3lX#Gph5VoJyrA!TuNvifrhhzSQ;Dvl91Jd zkxc`a1E6N0l>!Mc$Urm&1iSBKzu3MyJ9lWdw0~s*te!+AWZ3v5aG>>CF0#2hES#rM zY+i9XdtiI`TX<@&yC=6gx6-2onz;S~gQQ=2>fC?Bd&;<$t5xlrIsq8t_L`f%q!<*Rc9v!PB@Xp{B=ZtkZ zBtN|;TX0Ss3Wi#ZA59Cxct5XsUtX!pmpI(*9PT+}gx{xMFBWOzmxP@+Hd8Cv6E8}y z#Ia5ta_e)a);iqW62r4xX;N5>QAOcSgd|;AN36sx&Rv_E4(9)jezqqsXQ8d8K0Ub6 zQNU}s3JXK~^Ok84BkzZ?v;VklJo^w2d8sISG90QIda!@;$K{6TJuIS7L0`m8yu|bt zwGy>|XQuA{#FG;s(h`6`ZxT^gur>==5D^WIF0l}5Tc4jx9g=ah(iOfvstBXWA2FJ# z!+7RPw7V$;j}!a6E{L1+`R4N>9c1ZS>j;QBj+*zvH$*-@8uBuo(raNtJm{N4!u)=Vnll`eiXL|_H&1WRQ)HGIoXZv;Nhv27Se%P(g_?yOvi*%1-4aQNqaQ6h z=#RU=I>Ex2KjDnqH^f0M(C;c=pOh?9(K=LTR7&0|&p@Z{ep7|Z5U)K-)V8u%-f-g^ zC7a%=;HF;zw7%0EbGwAeC$>~WTEEgdct11gcO+ZDyv2WVsy3pEo^s68sY>b1XC=9G^n3=5#N#9>mC;d))BHaViGF*aArh{_}K3(uH1#Xf24RY zVLx+ETao=;5X+!yjZ)zg7CH&ilF1GXc2ZOj>U>TYhG4n-yb=&gwQ? zYLe#p{!6K5aZIxHc6Mgc8 zBxEb2Z6sXjA;Li(!Lr4B%`s_GwppY80sMCxZ9{_*lN;X=8N~=n&v*WLYV-(Sjz-4i z5feuR>1}FE=IprE`@ub)oS{zU!VPO5py4~tJN%%2#s7C5WT%Qg1v@E*=w*tGyrcFe zit!&hdfTaTVxW6%Q=(z(mzZioZwLCm$CgCxn0^OcM?rv4Uepm?9;X(=R$q@tkFcX> zq=ODW2-()YjI7!7%DmlNe^cTah{Rvc9q>*~dxyeipXK1FWa=4WR zQ8sVS3lx*PJBGL_Yvpq(-ocZh3A8Y0E(<6Cm9hl}G4S?r>)t|PorLs-i=;X(A===AFt9@bX_1z&B?i_ySwlqidn6}6h zl18VeH^=1klll8iN=IsNsxsC{#N0vO6J9jxCQcgd#9(X+n`*b7ZJ_+)@nGecS$)oE z(uA4`9ZemcX9F{|bYxdDc^G||+eq^7w%=7TZKA>Y^MpHm6A6O}+bJ0b9Ya`DIMH(1 z!ByQ6E-a33S|f4U4O;M?4fuJ-_Pe{rg_5wC`fdZ|mOs>)b87{*d$w$w_hvwB9lW#3tIJ%u@gEc;qOHYZ@0kY>3 z%t~4DasfJ<>wUvhLu#yg_G#Id*|~hYMAY5OA8SJycmQ^+OKuzZ1BUL7|HE%6yzu(I zcm_LTctxXh;Q7Enz0(aTIjZcCH(K5^TzuDHJ{BZAaUJ7=QX+W@T$ARUSlFYj{m;@`^jNsYiC?uhcd;*D1MlAwJ(A+K}1$TB+3Ji+yrB@ zfZk|JOAA|^s?WvG4av`#NuBF*o8XcBjbgDZnW;R6M z)(^UMXflvG$v01+2@5lnPZAfaP~_0=R!pO;ZCs1dHCPsX&sZ{xQhE z@m{1{^;HIBPXGh*&$Xc0)Id-NEVyI|@BwKr++J$5kA8qPQyNRMJogTXLC&yNe6)8H7bz%=?KbKC_ zUoyzg4_mrfr$LomJoV#Li&k1FBKll4=d+IdrmC;tqSEHr){9PSu$ifxiQV(*G?FD_ z`tnr0-WKI?RACe;nFNRCh7M}0Oq}uphW7cIqyG(aXYKja{t>Y%(1M|rlgeAdc7heZ zTciI<%gUcaRpb*L6E63YlR?mx5H27rlUJ=rlBbXdG9l!rh@Z`WJz8=?ch62D|7}+t zLB>c}014_BWA7wSnn&*quRHV$8XOhzCw%YVO16|Pf-E~$4HUWx7QQ$bd?5gtGkjJ+ z*C|)C_uN$1iZ}P{1wteN`wJS0UD+prxl$5>n!T#%n;* z?1QIHCn_nW`x48BWRt%T%0G2ZC-{-^MfITBm&=Ef5P zqmSGG*=dv1(Jz#3G+%W&f36C=5q{WfVc7Nzd0IG{kF&8&MCCP+r!(D{N$2)uF2)Pq zj0LB#8<|Xm^@B+Wd?TDhs}_F6nOipe!aoyq*Cod7NT_rFHo%gU>mRpz3vi}Id@7_ zuyLJ*v7ZsVAxuYuxe1%O}_B2LzN#yB1O*9tn1?alAe1wqme; zcSwyzA?}>QMD3pSb*UXqR*dT@WIbMc!+!4w`GA3!mrKUOOwP4m9PFN?a+8pVp~URs zzy1*Xwg5s`Qpb&aFNr*n2n+*42j}`t*GtT?_j=o)DxR96X@%*S%Bdq}Ranx0pz1gBM1ph;4pKh+zOTv3`Ud^j0QLEt&n~JX7V{rSz zCI5O4etO8p=Xn4Grd!J-Ui)(q9~Sb{P9hL5zRMd~d*rm_+GojP4Vu~G;uGabcaJ^I zOLlp}WBU=w-!=`M{-=0jd?ZwuSpqv|^t$vxB ztAnGfW4S}{KqdrijQ?lY9Pr;Cq*_^u8XeTYoJoM<>9Vi0tXHR6Lqmlz3ZHj#2_LE- zGtIxN_)$w56@Okqklu`+1&MvJF{XV=)5Ft%?H0qbu~|;S+ay3Vsz-i59QS@Z^fci5 zgatf;7BIT+j9KCVdjxq;x;uH1u2h0YCR`!CGd^GVkTxuWME*Zqy#sJ4LDMcA+qP}n zwr$(C%@fRwOcjYyVJ8ZH9gz=%=FWK-=KceLFDHeEX*wW zS9I-B^ang4{CcA+p70CdU3D#z{;PS{T|>CO4R{zA7ye`jUL;-}ZfSjqCL?);K%f2i z`)t-vH0!5R+&@FPF)eRfVp;>?>aOp(R5w?m>#83=&8CevacVO3eIH^vbZ_!WmDW2cq zEl$Q0jIT=`$AE=*A%G_JD6rI`MzFA&U4zdttT!YpN08L2(0_KyKlObN+|9~u`k+$2HgH_1qnR_ zGa~|P;}*OvI<=V_Q8BD)m)fFh(u4%`N-M<}a*ztv5|q$UQJI*Kfc|w0L_0jRUN@sX za5aT%psrU9{9us|_1B9EK)0T^Km;Lz5J89_9bcYsLd=vS@ubce{lhRA82bAONbaa; zt^}jZ=*SwA8m=8s16WLBWlIqd^2s)Fr4lc&35x}3SKZiZpatlkEU994Bi+#-17@9) zNpFv>psz{tW6LsqDPRKZR#~h6@J)OG{!6s6wW$#qIYSPcNLxq)m3(`CfSyh0$PH7E zqm~L2$1(nUj!f6%zzq?npaqA#u|vLO&g{dB`9-83oh90mb13VEs|Y?KNX~-6HeNmg zw3S{O{$?iEQKks>qDVjL8NvfYBC-lw?-*3mp|RP>0{p&H@-Jp4o>F$>nPS062V?-U zO=IP3&3CC$ck&js9TQUVyzoJ1luX>7Oniq>I$~Gtt}O;ut$QA&e!`|9hOnJzF-=nO z@||K_;9&!_quIx}PLi8)h}j5)JI^>;Ls0m)$+|ykt3N^7=>P2pU?xrBt+tR&Rj?qa+9z2QAqghF5ws)S`Q=dQ#hdAmw&9svkdvR@bY|tIGHxSiS4j zyaL0Yf3qiaPzWX!7a+&gWScG+yrV^SEPZJyrttop(Tn!FDvAl?^?jS4_Jr5Hx%)H! z0DE5iD}wf`Hd!qFgHME8+TiVTP%2O|+PN_*2X z|Aqx2f)I0cmJfIZ4ii<%4E!~B;pC)|qD41FoI%)DjuJ;%h!zjcc;vd}#kw(Xkn05Q zT(i7y_y0e(9-b;`oReoQ1VyR>6)18xj#Ys~Lkp?ANK#g;fA3zBxTDBbc84%r}Slnt%X!mzR*7(_c}7mbGF2a6FM-a1fCyO)l` zkRV_NJ{OWEag%9CmJ{h=k}WEj1}T_%^BrO?w+I1bL;_zB8KWG|3 zDczoen1v0%!VzM(TR7@;NtN82r9bjTqZtK78w^+#7iP}5?{-rIQzXW-j&uFAnY_{F zWYFLU#uX>t1g$0Mp&~uCqUkA;02nb6AP*ye_ei}20vHC2fG{Cxs7#7Os7%1t1DMe5 zpuMi-qS2&(1S#}+AdNyRyg)xG&vww)XDQD?#sapKQ5Ct6J=n^Hid@Y$-Z{%rk(;&P zea~1CxjaF+gV$(855yz9fC>GLa`YM^^g!Il9vYl9=5xd9MiJJlv7*JCL!LutD$h~m zD|8jv|9^wTw-~CsQDZc)oIP@5WDYGOY543<_nm9TlhCS7Wo}_cV&sAVaa@W3n3c4r z==4EKVZgvUl{88A3BJ4UbO|~YMpo53on9zGU)oTnj2kEa)ZPpk_RMqxnOP!T8~WUW z))8-^C4--XZG;ycw@Xc?^i8S9^EJNBS?UQ)>S%p6DGwvGvjZQFcQJne3!}Q7-U6a+ zy9fX%6fJ!z2Uw=`T&X9>jh8d-U)ouk{Iq6P3*JG5)r(eghYGAEijK5qItylEV91e~ zQk#(lGZ8XN+TQekNR~8y8He!xOX=5-IC$CS(-$k^p`Gt_6R?Vom2{+{qvhSoid4}t z9=Qdg%6R5H^4;3%k!z7J(U;(r_R#S07=#yMV~ErO|9W6?JJsGx9)(>VBZ*+Vg)#f5 zNiUCM2I3h^CnGI#!i)(`gj~QtCNnIukDZ6Ib)Qz;L`Zyt-@hgQ+Y*`D#vS>7RHTZI z@$eHAslWs0zVH5K_phaO>+5ycL(!U|8dpLQlUE%kWg*RXf`e^|=N;y-{l&qIuarsZ zaHu0m8XXoVc}kwsG|3r;Z*oP<9R7}^VpOO}TdJm2=ideuu^+lDNGmLke8-BI-*R}h zSA`;$X;)`dbQHf=!5(SG7O+QON3Ul^td%#p>Oo#W@`7*Dvu*d0ue3KS)S=E4A)aj% z`HG;3t!iWxeE2IG{vVx&Oc5C2Ls1%zUg0ZUyMN^>OXM; z6J{| zR%WeWJ?5!Z>*c=tdS$3j34qt4_@hK!FrA^j^L;L{A+ip1Jra#ZE;Lj`-eN%|M6!q*Od?Y!%F+|-iJ>A=C;XI^sBY=a;wMfMRiK-MWttB zdvDk7J*7tv-R5PduhoM*X}r%WAjV0hXR$bLYMuM~`(EWuF|TFL9JDu-lZrC<1yD*_h7ESX`YbA)F8q<+ud z$|@5y!X@q?5oJ}EsEP>iKo=*lG6KB2?f_z^oi4(X-zWyD;+Txo zfESa;*zRYWb}pZ5?lje?+mUe zAKKl1@?GzVFB0EHS;h~y?x?G&t!ze+7K>}?toGIm!{`|AH4ouC(rEU}7~{Jp_a_XO z5?71^QAX9PKKQl3K>ig61KmnL^eask;HL83PX48;#+j*7(93^zo>UNX zAG;kZYdgd;4alu=MCIplTRvcF9=yXLi^LQz$=7`zrqH}$l73mwR~11o@*Xk5L%n4; z-UHHNLGbtjPu!ynCrq$9H%#_+u()DIbS~egQLxjuAXrM6EMh6a;$+C)w@)8qU-r!w zqONlCaNcdSl%pzmVt{9wEUkWWfMBP}IT87{R40fcsU~80SVw|!a{_=UHGdf(#wY#8 zGZM1EOx%nmg>QNz3I+P%_@lx;;vo|amtGVsVl0dqx;w%Y2Xu%=W|zgkjFHnbE?BIL z>R_h|#UA3jRT!7{Tuhlk3MpRiyxV%|HcjQf@wyZQ5I}AREC?@f1lV)ynW}|)gW7@G9{g=(>0K=*ZsUbCp zHRjg)?cgtcTUDAVs^GcCBgM14+bTc{g0;D`_BCO+TVH$%&h+upvp>e7*|XA6M7~=1 zW#`8GJ-Tdd8zH$}ee+!eW9i;vdB1~jn0S9_`})9p29ND%vp0IW-;s&1L#)L5V~=ew^6VWs)ZNz1 z7;mfk+waW`9#YS=wRMR3^WOXkduy1n?i#ouvHD9(7V4&nNwV;u-_{Qt`^F&c8=pP( z5;SLT+TXD4w7`80W9|D$V{sX0`4i-V^5*`4k$H^O5(eBmMzKhgoSb^FHDf;1dmF6V zX7<4g=A|}@ZT-?BnP21>Rp6!h{I{RFBu}#6G0GU=pA~!0wt3}xjFIwg|2X-T*NITd zg?FXH^0QY5$5>EvB*m!*7NB^#f%~xFDU0-+o8TKW8ast2F8VA)gys_IBal+82!Bgf z87zN?<~1=6Asw`@40ylzZQ!(b0zPL_!YU12nCbk$Ff{NF-$f2l4wc$doqSvy!?Zj- zJATuxk>_pA(qzeW*esE)s;!ev~@OF zVPniGZzJl7#7Vo$#jM_2j=S`@mp*;CqvR4vdHufl7-3nGmskBOhfFq;e!(ANR}T(U z?FS6M#YRIzx9fkc^XR$4B6GQNA_n=RR9H;PCc_c&AD38brR1d$BOd)(uJTF~fg`j; z4@X216Q}Af$-e-xVpI~C?l=oQBqCr^qZ4V7LfPDLK}YZi{gG~-k`i%Dl26dUSzkZd z_Qa6!&cp~;X$X&2-oUB{OJGTy(3Q?Sr;K3~XHG9+P@9f0Pq0WO7J1(~4dbGScC5;e zIq*T9SbAXUdxeC6M=UbQrNXZBT5t%oscFouWMCWvmqf6Mq{mIBGiHiUbBMV`U8j@B zu@SlIRR0=boRDtGx27^gq!W_kd@^I%6&V=BeVPJ7a8XyKdRJt1YphV*Ac^04UXI$~ zJ!XPj7$IH$hOlK?=`vxjD88W_kSZI&0Xw*DrWpYjQbvdH460$pAv5YT!AJqY!8R=H z{Gq_2&T~cD!rsPTs_X%R1?AE#dfijYx`VqHUCV|hsO{CZt(rGDfo);%Kg|U{GL}tC zemZQeY)v2CSclLIRIq8={i4Ik-PUHM^+OiVnsJ!HwR57EJTLTwZDE?U#^wB%aK_G+ z%@)XR8y$`5`PGHp*S5Osd`26%^xv=A_$NpF4{rQTOM)^UXSHG|lG7|RGt<1(rRAFC z6H!4qgjKrC*s_l(m+$;UNdrh4)Ve-#N%Jj2dkW3f=x9*CXkLM3COTATse_CaWV1^T zO0k5YT5m?z63K)E+`ogCvqP)Dl1+_F!M4CqL)h7bl~-f+f-k$o%#qU&R5msoXd>)} z>OwXURfVCuMRDr$%czq$hKiS%9im`v6%tu3gd56IXt=; z=CX>t{o2e#Rb_%1cvmT?;W_RKIQMR*-;P3rbqYz#O3UZM1i_sl|H{5mF`tL z@2sACkTx1SQncfNN80(oU6c^Fk9c&R9G)`I`NYLRh7@&M4mo1WZe&CB_=Vp(+@A_s|W7Mt%#{yuS_=8?{u625e{#oTYV3OoC$M;hkMqas!r z-fQ`UgKIeH+PsBY|J>7p?Uplq2PmXKs~lAKwHyIu!!~EHz#J;M8#9zdlRl<*U~C$Q z`%9w;;X>PLa-Ji|u-82bXo6U7gunBxqCWhY(_T0&TnJ!IvYLv$PuY^_w|INOIR0?w z6?TuFbM6C5d`@LYe1if$wv_{ITL$x60dVNt;%U;cs~(21NFF&r*cOO@H_crbAc@@{ zd1qp$pHTc*{51bu22@EN?}OqzLY0)UyP&V)r$wooi~wU)NuDrHz%fPRNLbltQDijO zuZ}2fpho)dfsBN@m4nU|_Rb_;|9rJQ%G8e!1l7pT49Sud$rJ2FeO2=c?Qrv55@ZY& zR7C^$`kPMx$p|ATKP>&`^@sn*{=L1Ur!5%ZA?%C0Gh&w&_GbKJ^qWwMTbL89&lG#0 zO6bsG^^0D&%NrVl6<;9{OaRaSuK`l5kMt~UqybV}n}xa)9h|H$4u29C9y=6$0%$Vh zvrp>+7B%m1dMOF5G3tAlQRB?2;}Oh*56ogq`}MTRq77_@kN zfC|YHai9^6WJsn$of{bnQ8?W(f+`t9B^uE{hGeRun47y&XzpPl>*6!-x$7(C{R!puuD)fLZ0ABh7`bi zr>F!pq7#i!QR`Xx> z=TeS?#Nz#^;%uR)|Jz*83u9+37h_b?BsG%f|30hD^>_5#<4mAPAZ0=z;-LB$Yn3_? zNoW9}&Bj7)E}{ixnsE$`E!7-hzEVtU)Cw^(&k0!wfN;jd(`6}EcXY`dmnB3bg@B2R z_8sj~N6VmhixD^PolK|mw|2@%tG81WKUd6v=LaQW%be3}ga=7IqLP^}(2^;WTF#KF zNRErO1(PkF#F#Cfev>br-k2|TKHVN`tDo^S#1t5O!HqK7ELpI=)D~x%jYMJ^zm>#` zuUkGT_GJH46$^Es0l=W;hA#{I7;NT+@1PS-vLF68r04H8ZK0`&0*xnDCSJ*y61UmH=9}R&$JLlySwC66^ zz?uHNCl9a%mBP||%^aAGD0WE6q-b3c?NS_dc_kpsyxBofY3BX!WeMZ5nvsuTm|&BL zFYw4tu#$oCJ%fJpUj+viwBt0z%XBEqISUX)8#&AnZU|0xZY`-`?V-_N6H+w3Bcczg zn!r$^oh0>5waawG=(Qz-M)tpZqW&#iFLC>*z4F;3K&1&`d*t^;Z|%b-#Dx|uan6XT zfK4%sO*%;(ikD6ATO9Jfx!$ci9Q{_@sSxZ$*uS3awo?i;G|)ZB1K`bF@w{ssL9PQ= zg+;D53Px(Qp&D4?Oze6Z%6d+uUQmkErQ024{6Ra&$+gM70?kx>lW)UNfqVUE&> zLHgiUnp*Yj!enm@_SMGJ$WX5Rbr@d^Y+uh zRVDP@yzP;N{y|t_Dp_v%T~QEA9BHdl2?Ost>V6swI}BxW=rLrk5{t$6#Fu;lCh#$4 z#pEGYNY@57=^!x|==I?8Is_ZOuqg<-VfD8G;f|4;-HSdb1u9ILJtmWJ;aN;hdUj;# z*!dY%jn@thrYuQ+Bvd*I=~R-DPyC$0Rjnj89cNYI%aADf7G+~X?lYv(L5ALIp}68X z;(+KP+?NLktK>$*4DBE>{SKIA2yyQH{0$XU!kA+|3c~Pv8#$mXD40DjovETQmd~tn zna}69=lA8E5P+`4pP6ho!kOz?L2fdLT(iA?q59*)kJlYyJ)HKX5PS-bg|PWh9JFQN zn3#}TExAF&qlCL^u7jtgR1hNN7=0o~utRiG;WE+b9+m>c*@WS6(t|I<47~isJTjJu z)o~jc86e9^#&%EKFM_#Tv`X_xe6b!=g)x#6d9n;qq61>QT*@cEXpP5Z?_#_QDS_|C zD5E}rlGS%JCfo6LpcsHVwBqcQCgOv3GG*T%Jicw^KR{B9HWuBvb#CKNu*Qa&m_K$q z2kUx8Z?v4NloPcPAN-ULWiq+2@kO4)`0vF7IjM;$d@u!Qg@=4SBVaGx`j z3+jfN#H$+{aIC?JmJ|t^w>h4F8ZTcpJyr9E;eyeFb>I`e>Yq=r7HPyGghLU!3Y~Ps zCua0x{RhhP{UI=BWZwMg9Me^?rcB>r!OxC;&lx5S;=5am zyTIQTKebZzXIL7$h(IsM7vAvW(s%8V0LACzP!z2n{MaqTJv`J&P(EAZ;})(ok9s4{ zWk@XfoXa=b*FP^;Ih-=bA*5tIo$d|lkgZSE3lfHeP^S*5z&Rs#y-s%r_lxJGLDN@r z#IcDQTR(n;JLjn}VF$)%nX`wz6KYwpuC)Eid30}?h$2F~hQC_cFX)ZhSo!_Yan%7= z#nRXPGcOooc-wAaBo)Aez}#Q%2Bxw-&+Fo<%ESsMj^5|1vS9^$ z_8LMRBjuiW$8bGzRBt#PV3+SmtW6M%GD)0-zty-#-1v!yL4W>kW4Uk&fpcz+E6mLl zVvN3i!?S+&W_yRqwbZlW`8HRmO=?&m*mj&CcE)@)&(XA&O|Gs@GkC7u>4&&U-D5pZ z4`qImzMKHcbkZO803>WFlYXP7#fxhp1sU1=vy!x>7ek%wi(S9uuTA6BXvnSZVl#`273TX-{Zqm z9BOk8RDf0RfG~EUiKhx^ogP?VWFr7=-B zec+ki8Lq;>CMzzbmi*qID$UMK=SGNMv&F*BM0T{E80SI2p<&5*d(FA3=6CgIVw(S| z*+p@1m`^GEzz*l)uj=F?9vi9`;5Hy$Kw3V<7}9n%%<91EAlsm}p`ejgo)X}lWv%$+ zziGB-&Q2Ktmk=)@y+1|89C>2+{g|CGbWb2&L3;T`MBo4%-sgV^!zYQEI?Hxh?7f6-%#=S+Lv&{F_Q>A6(l+B=pj-}bh z4lAn0uhvssYkoH%Hb-6}teT@QL962~K7{q6n;06>b^t1IpZYN3M(>2gVgQ@_Y`zl zfx0ib2d|6=J!|#eq#saK--$-RyU%de;pwyX#wT)q3r-C4(9D>}uJtw58|bdyJaf+Y z!PY8|3CnetA(H8N{U6CrDQB#KbX7 zl%8UpoY4Edhr>Pg^+%zS-SnLJoUuCxS%{wi5>WF2z11)YsrjIUu@BEeh&}elxhExiF;UPodQppqy>mQCV%>~~ zez%oQPFy0y=}Ti%cuqI#3%KF-aDN~JUM#_@9COzF&;KhXgt~L^7%>o)a{&i6q~%@exL7citRq8 z_A&ni7mR871i`TS6%MjfMjge_kHDU#9qQZf>w@_BX|%5hnH0gR9+QD!8m+ZRPUW= zjsp4#Twbaa9G#ibIcUC^j_>5J?_BO*?omp5`>lQc0=-;-q~P7d@OCL_#lHcqO@^z?nas5M+KSg7r&$Ou*5nNgU3En{%ZF(F(%{xh9_ye*Q! z4e@i-l@@We5Cq~j$^;>;UIT?KwxUl|UJQ+FW!b}}W7NEciT!Vq34Zdma7Deq)pgc)WXzzA1*TSYO+1uLscqF4Rb@;wuTQ!7rG5oR`_ zr}IlIBJ>0!ip5(ZC5-&@8vI3dgSi_PC#w-Oy+a#w!Eu*4oxE9m{Y8%|(*w(C3a_wZ zkas|r5(W!*Km|7s*-Q9#hx(S!YmNY1cY^OBQ-IOw=4|)yS^}8{#8lQK+%le+TBo(H zA4m2_)u>g-Di|=KLeud825HEw^a$*muz_j0^0Q>l&%r;UkKhmo{Pi7f8F=insuCyX zf;xe+;8j&;E^ip?wg$myjgM=*sUCbjk-_53!ehl7} zS_|V(1aFQckI**ozTzPnTWd*)L)Jd-#QUrbYsP4`UEO3fwjP;D)$6AABfiO2NRKa$ z=cv-t57FfyXjyg1WpJWa8TEEUWLBpqS=R*bF84f4PXO4>jjGv?Z7iC7?b)M5Yu)si zVj)tT;*ZSr30zzkPd9$e?A{gqyb!^fKah3Ck9O_rHL?VH zG9@lKkWy{7imC=+JKf^Iv68l{Fjv7vUh3yPaM|m_r%~ZlnHAeGdIQ=oC7wGxWot@q zG~Us+sZ#O1cj@M7lj%sO|A4J*McfG>h$(YIW%Rgg8(W4NclABNQoKBc3KKaLJA zC79}0PiU)5a|RQGf4dv1Li&RnlJhuxiq4hCFR?cm7M^ElT!bXbkl;asz|5V*jg@yx zq)hT;W{ye^dQxf&&i<)DH617qg(YEin=tNMJ~LleaPZ*g?qGPbI6QHB*ie2C4);~e zz4vS494RhUj9*b72^G763(iq+Hf5G-H33E$FQrz0@nyW3M5VyRa$2a(kO)07u4jVi zkbcce3jB0j9#nv}lp%Z6K_G)(TU>C_sLDay2MHFu9m|sI0~*xIv{VvUKKxDAC`NN0 z@Z^2wP^mG3sP}8$2zXY;cO>RyCjf$_5{bsilC_Q_8uNjSVbHvq^8{Zy?uFttiNPW< z3VHtlZC93DO!^+P~>D9L0t@&&R)#0$^J(U~v2lv&NSkk_G5 z*ejh;TfAZ;QUsGtBHmz|XW+ zFBdU=bM^H4qrYldJsEgQ1#VIcBKAv)fS$MP4*Q!=ruN)ATDvv4v2tkgJkz)4D41rG z3rLMM1)dcF=0&(*M6JH1wz7H}ufW>S;3>>R`OeD%&~SjsWXfu_1ywU6ZP}j77A%;U zU%xc{P|bL$s7%j2gQi({_7V3>#=SI9%JU+W^`s>~4wVhIT$ZH!Tb?n=80p+WjMod= zg1M-1o1nw?R5#!i4H%ZPkY?o1v_@r!4cJKl%gI$Ws!NyTqo9p)DfTm*!xZXzyQQ$c zUUDVC67+s)vY5$K_VCo6Y(}ikV&>)agdgJ4d=0k}4ogMFrfTWqSrz}t*?u!O3=ME& zuEs4Po-1ud>0my_{#Ke^jS;l>xb?9&io(i%NW8<4e;YrpYEot0K^A)$9%5ciD^CV3C@Pk28c| z9rqI8?$y}MlL0gcR6^GC#Fa-Wjuaq8f_5Rg~ta4b_a+my}C8BK^)u;(?CZ}d7-4&$^Xt(p!jdpWJ9$9FRe z7;v%GYMcEca)a)#vzxfAg&gRalEyA*Rhvp`BLqj*yHv8$p0}_*J!PC$W(z(W%J^Dn zRc}PLk#B!qwDsC~BU^A!v7^AU6D3RxgJ*aTxT@q;`6O9)6tWE>ukumJ1Cig%rAfo`Sv z3_gs7)06*vq@LGA)6WgnqxHHiintZv^1Zxq8ZlKH@s)b8;?}pSp;frz0(LKgpM>X% z*V3tP`!DREjPE!bU$XX9NHoIRI7cqZOJ2F`oAFtPshr~|4-3++_tid7diJm9Q$J8( zx<(A-KtS-#O$pAY=T@oNqJx@T$B+(rjZ>`2ak&CXmDETb4!M@1i-L+0oC;z{ju(F+ zEF=eD6ZXW}=CfKt+Y*(1Ip~d20dS6SmyYpzjl-0*442I5JU8%AMrA06(~#IQoqag~ zPE??MIY@FOM{>~19aCnX2rw-}oI}rTlc6G;s9@kin7tM=f^O}f^L*(@0`?K`OoTFHDy^3cI774X^vv#fyeG3Th8c&p8P4N#{3 zOau0-xP+?$Tc*QDV7BISG(Q1bWdhZkFayw~-NBYR@Z-rbN7hjIIz{hBSlnsm0%Z%# zwE)gXc+5r#m21eXB%mSB3^Tw&MDDSnqSuJoIfd5|m}Lc= zACDNwTNM^)hZ8zv2AGfV9LH8=@cGZ3k+MVB+I%>M@iCy5+j|NO zjFBJrdCGrRg@07QYY7=(1$^uoSc0vqf#V29=!l~`xozq>}yU!`rwBZU6eA)aZ%dh z2sY${_zi$cZ)ni(Fx1a5re?A-ScdV9Jv=+N_xEK+sgsY}!b)bfa6e9cYe*&N{)bCtoa}e8PVydn@8B1n3T?q zo#oHtbcd!~kyRkaR(|-~@YG>0fLah=#(tHZvfaXlU_ zV*Q_NpTf?Ern87m*j7U1Qv6dqhb^N`UaC)l_2vEx zr5hm)7;*Q=hRe6C-d)qFmDmc!53|i!Tw_}yD(jtUN_T3+v0lXwtxfMzcZ$N{XNvvFkXwwt%73x{E=BW8o{ zx0WJV9S65#1sYr9r}iZV`}jI%iBJ65?7a%@CDR_5?+PHJjWaKneY+&30gG3_}xPFNO*CyoF3QoVN=y~h3sPLvxnY=UiUJO zg)Ee@O3ZZIOjSFGN%zeS<@`?rMw-<^@^REj#IqhBabBWYuqdKts-M6k7@lR{{ZxSr3|VeOful3(5-r*_y{deQ>bm9q9cs#P-u@2osn%I~g%CFG&e6oqoiR-bw1zY?LWfjFrgi-MxMQzKYMZI~1i% zlN*NHtz1|Tt0;Y~nlFFl0^CqdD5Gh!yuKTYm_f0K7te=hIxoF{QH*2MK5hvdhhmsD zkpsQCv~{_=)%JmYj7kiX(3Ab2(Op#b%Q@t~Tfv1HD0S6F{$wmpotJ-mUM&IXG0AqkvRm3nFtMXs9B#kLz}LBgRz>NEXE*M*$54Hp&UP2 z9!}X#&gMms;c$tS7XC2Pk!EMCT1GNy82DBI(gCFrw~ZRLSmNqs%_jb*O`$@u&$=SE z`(0S*PT+Ak6m^{&fpM({$82}oA%d>2LphVP>O*Kyu5E+gnB}kvhNTlhuVH9SuWFx8 zhEzaDJ{0LCe!NzdW~EWqXLSb&!!r(*bJ=oYRKU=xz;zg~3TKwPE&(jTSsAX$0`);S z)eYj>{9^^q%y(VtUxBkKSY66rWF3N58LG9m()(SCEPX-Wdm*`!Sswf?OBs3reZrEB z#)!;wtlU@P`t)w@9B%8A6;AgXb2BQYT%gEF$u16fU5JrTZ#@#w+mfFLyk^9iA2N^0khESEWeKs>hu+_Y5}@Sag!K~?+$=vD6q=T zf?ksyrj?nO0kRu8!Am#v6=bf#Pv1*BRc=#2k6yc0GV9!P&?l0t$oW`*gUUtX%uAPH zg86#o0Y{k=FEEKto+a)Am4tW!XMWe7VgorRN`nzFL^@)`#gu`<{Kk+gQA08VC7s*< zJWH=Je(iT*qbYcq8HiTDtAr#crBa2P_W5_}3zd^e%bkck$k2IEp;IKJb;avf|GLi_ zjKyC4cLHL6csbp~qa+D76NzNMhrGB`DTX=}Kdpc6*14)LLV;O?xQbr#3L}%8dFATa zF*Y;BKsn>MjL9dd)82-{lrHJlW%1#K$_SiNG~&eG@_Y_CGQJ9zCvJ7;7ZG~ppfLRg zCztPXP`uqBADMghNnOCo^KaX@iYD^v*d#NPNE+zJ+b9Q(mU0+XgjKGAvuQs=a=k)K z5h|$!k8Ic)AZ(JJ1K!$)eOxVP`Y z3-CpFYXGeqLF%P!WjwJ+K)IH_oYD~7TYI+2TS`C0&n9Od5}?_Aog|+IuX}P0AVWO2 z=|R^p>&Z9K3hNZsl&vap`8FOuD{Zcp)*5A09B46vr;KKs7-qkAH zF*xx)|9~uqx2pQoy7CpQaduuQ;bvG}p~`mPHRBW4u<%%Z<@O3&VgT3d6V|%MPbg|i zhF>yqFkU~FxEEPyjJsbJbh@?4c9u^%iw3L<&M7ViE?|jj6vZbEoGtme!&0NAG;M z4j`!U6i+#dyTJkcjdn-n9h&#VVivxI+RQUpebbEY>2pz9JTv8%)hZw{wUI7$7M32V zr&)0ITIb?sZp{8G={m!EW<*xU^dogncOQzT1OC9nRHql|e+lJKGh|Xs-W4+P4D2-< zOSKuxz`+58;iK!c9ZuX?-<7g=Xoj~eF0!%-cbYDh;F$CF6Q%U4>bri_s2l7~3|dSS z4X-@ag~71e`%n!GoK4vTvfKh5MQil%D5NaJGW={K97g>}|+;(QsC1R}THPpKq*JzWpNg>^m6lVkq< zgTFckwGI=8mG5Z9M>6u_>*8MRYMR4gT`Q%Cf8t$N{00EiUx9Au_!qvRiN06dhj*|W z%N?x{`1M#Yfb^MfnUPqO_qy_=InJ0Om=yOX-iOZ(`0z5m6XvgU?6l6C!Jt3IB~r4u z*B>%&BxnRA3`12h7PUIbUi2dTjMqdzE{H6Q*psWfz%&Eb^#kj*$2UdB_^-Ga2acZx zEn`?m&YFIr3aTZ?VcRgImZ<1^fmb$Q!4(`KYmWU|DbAxe5k6B=PF2--8{+tl%fq-& zg{U$bRJGE&Q-Sy=#zyL2@-8yryc>Gf6q6MzVdZ^eg?d~*%SXbLY?$9Z1a^vpkH4=0a&+biJ{VJ-?t=Q0vIBxQ~mNN)A1ui&qIu+a~z|Zv4 zrmSXfb|QOT`i;lb3N}GUa3%G=DI(-y?9@n5=QPh%?ftbCSZY5n;=D_Cx_`>q-j&^gFR;(U6FN1f0^P%uG7bpR<9c56w7+I}u8ve;XvQ!kFP8;O!Rr~>7pS)kE=e;az z!e0?IO8gYN+#gD@g0<&sQ3w7Ucl7q;|5PS!`_fxmgM))C zpCnU$E%9XZnHyEnZ?pZ;em)kjPA~KjXQM7)zrt~4Dgu6npEZVf0drIKr-_t76Z^Jn zPEY1#n)j4nQlt4o?GQ~37_rD4Z??hrGuH#tw3?_~rImr~N-k35j!pC)jyB!@X_q!r z)9M_HQmPX^#~o?^Mj_4Yl99d<=oX{i<09o_byE#x+F<+x{fRSXJyiEe_=kCfPRSE5 zrYm=u_6<-*84tKZH^^yn5EG$&&PL>I%CO5>&@cCp?A-fLRCWLF*5Taj!`%~gPAAt) zPF|kUeblTDftc)qD&Xy^_F0FkUE#vuGJEjX$e&dCoEs|o?4y2LFqrkmHl28iufZWQ zrYsA7&F-^fc=&X9$EV$B)0oE!sd6u@#CY1>LB$1mSY_lMXhc-dcU~YbKSyf4R~Od0 z=sqv2Qz%UVh%hZmB)KDs<`ndDdG&6RLHw8VnXJMcq+v9JZ9m%T9k~XYy`>?HEO^AI zWho~;bn_rRgTc6Z9;RY>(lrLM_+Hi|zk3kVn*qjqh6Q>b-e8r>VPvE(fe$ zKAki^f}RDj1=kVMm$qR4s#}@;G9fmOGx~<3=^VAOu1EbVD-%j&o^y!2A2+YNw>VZy>IEb!^pmK{8EW|5slw_=Jwk6Z}E7)j@W~JH0TZQhd5qli@yb6Xcmin8L}hF5zSr$V9Z=7 zE@LW+lrqIrS~syi<6Olc*oP#6g&fXr+gfP&h97jjKT0-?Zojc;e| zZ^>$$qWldRivmIT>}F@QW0-;A zVVEQJmgfbjkZgJ~LTUeH{rS(RLG`{5MHuUE_Njml ztk3_j=~ZU|fW%z@5Ev>(fc^hF?>}sMUgpI3{C&S%kj&+<3~s{AEUfqDzwvf}UN~3z zwzg~7|A(!24ALZ8x`mrh+qP}@v~AnAZQHiZX`9pbv~7FZ=IwLd8(-Y`;{8)Qs(w`L z%8JNbxia_4#Bp=7I=iSRo2{Q|#u0~I7IWQ#VhgcOj5kiX-nPuTA@TK=%_gpuor zPFt^PTCU)o+ueHGb4Q*QT0Yp{iX1R@eg?BHFL%V^4g6NP0#g~fMC?eb;=}36`lRh! zdT_cXhAo;!?hA8_xBlnG;aNdb@kWU=x)|Zm90$`zbDe*GzxSZNzug{^7Ca4wpg0db zwuaD!p@tZ!_<#T+;}j6;m@}wwXjxEs`MJ?W1%yxFzMfhshWnxo%?{WEFMUD)Rk1F! zRQ5vJ_5N(}LYwlX1KAATu*{eLdK3(UlXW zx}jBOIR2XVsl+h)qW7&2uLfqUBC_EVP5*7z%euCu5H=!#)vXmaG?c_;N~l(M?%GBu zvxsfbnNDQbeTwkFrz{cp-4I&gk#*)SWCo;y`(6ej5Ikboepa$THD^dziPrv9B5+F# zhk3n#&_K|MzB+vZf$!KW&Nz)u9lJYDWAG4=vn1Kv7@({-E)_&Gy<$aSI^q}}U&R31 zq(Om7)-}WsW^R<=!2DDM!cxbpHz8_JQ2im}ZgVzCmx(|eQct2S?l7Uh4r(|fi64Zx znK`7?vU*~hu=WzqNRdGlATm)(NdI}hoU=1LoWBa)NRU7SQao5u z3Iw5$fjRTw&Il7^Is3C=lTc0#whu&6>bi8x?DKF+f2NccT~RydTBSPqsvD>IO8(N_nI6b$2%FXY&^!aJL)wQ zl5f8m=N8-rhFi;w9I*mm!gO0+9tz-=Wceb8-Bh$eY`u9j8JU9j5F#zb2!}ScmWgq8q?|yjpasUr?WU%J4wCIZ;By97b!1NbVlT ztJLu$#sC{xXEG!cW3v8%G+rGhIgd#QMJ`^zn9_GCx@Sf!Hwb#Q&)(0p4gDjLw_kZ1 z-sD4|uM$Y=7|HNgK_+YHeL4)5{%b)IXS6_BS2jv)O5}`g(Fh`|Q#wSYJ_!K!XW3xJ zN)?i_VO!3iG^^DJHFfG8xvrahY1c)jD^p5F!T;&CM9ogq2|{`Uvxxo|ZkB+k0Rwt? zkuMgWY{E=8DjPkC)Wcuag4wk-a4e~6e&Px`j1cN9;_+x@qYj~|_9k9ki6VyxlXfp~ zavegE@S*zv*ASgRVQ0iVJ+dOo!4W_jA__3>D8!*r2qy`$Ku7Xu$VFejID@46W}sxM z_3qMX98~G-jh!J;D1GU(pHwzJm28l*MLn1u+bT1?QW+*aEV3Cb7E{`bioH+@hz1tL z6syoiO$@v!04e^kI+EX!rNqc)w{LDZ##sr(KL`LBWt|KwOob` zohZU}L@8?F5vlFMyyt&GcEe;yJ_d!M2@1d87>Ox``hrqPh~>t$bvJytF&vLM0SyU6 zu1W?^R|QaHVYNq@2u!4*QXTf)N#|CEgTPECPnEQ$enYtVQ52z`fqf+gzBhCR3Fq&~ ztUeSxf!-#&uh)RkwWm=#m7>ANkWl$kie-8!&tTIQo3&Y&tZ*rr*|+@xCFsi8qNf3t zg*nYRfDC-BtdhZ}!G?;)j0TAmL$UZU|C`;(luw9DD}%C^j>2gyH^|FLf0h?jjYO{R zKsLOs0=2Y!ds30b&Gs5Ke;(f zopo2RP6m*n1h;$M?s7(-4<)vY_=~N^JSr3*=Bd1o`YQ-mgE0D$B@g=rT+J1=Jft$< z1BG(?fJ;1o8XHFM9oWb06Am_$cpgQ37>!!mQk4SVo*6`}22~7>#8^{Sq}Zy)rn8!% zzY4yP@DEr|jX!58oEC@{O3*7KL{h0FLNWmITd>88uyg1gy1t4=w`X$Jex|^v9BxK; zzUl5cXl|XiyJ!6b`c|jwRh6B(EGNZhzRWl-F||#%6U1*_J@WW^8}|=s02K^$G%BUa zMcI%uy_oLelqA2Zg5?v zx3CJZqgO#=Ns*ixPr=Bsb9IV*N))U!QIt>JWPsH#g56rWbApH(mX?AJ^?fGEzp&@cd@>Ew47ug!Y^J}Q*5O1ov)MYb zJYI>CtK?q0ME(h#;WONM`K5$>t(D*9s(go*zvbd=2!~PAEt>uHpj}W1St9^P>O><` zZA~I`)wO=j0zs4M9*6dY97RRO@bK+R6~9jM1@PImCa>V}CHNvFM_1^NMof4MwfxGW z^j4))d3d;zvZ0w~E(#LzOU^?6)SG#}lUnlNk(rjYx?WCvS~z6bD6U5%|J0|O(R;mG zY3Lt4+xbK}jIF)EBhrWr+P9J9>B0n` zMC6)zq~4fmp=XQ2F$E)?a0kV*8|IhN$_=+NXlQKyU~y!cy)2l=g(vaHwiPI)DbnkA z7E(!$XjqB+>imWOXv`qmu6V-+cS#aS=S{pW<8}80p@g%wPYrx2pVARts)A02a2u`% z^ngKq!Zh2epUc@)AUFSVCN|mQmS>>F!=45|@$kZQh+LuTRik0x%d8zRQJrv4zNn*ImJLF`Vd6o=a|zR*BAY!TW373vuow8|gj1 zaO_B5Y*dkh%HWS)*k9*Pl$A1z?Q6{(yMYFkyp;X>(%L8OX*RHZmT0cjQu5GleUeI6 z&??8uo#Z%=54aENNml6Rf=pjdDRV0>pE^+<@=2Iu_8QA!)OD*Vlg5FfPW%MwquEcG zYmzb2P6ob{ey-p5f3Qzj`kQfG@jhxn+e91m;92P(Xz^o0+Z(i(rZ_mIQ$Y5ukdTvm?@HCm!V;;ZY6i(Qy5(;%I7(HSqF72Y{`Sghvj2o^W{O9Aj0 zBXyNJ8kHN-DcS9OmRI?Ff+;Fz&V2ICyAw)0U)`fGa3&Pb(Wf%l?|5^6w_Cf^D<5Q( z5fj({vt^q*J|)+@tQwtqWQ0AK-=%8ab5RiqK5eCD={LQ<@<pEwvfk61)=_q*JbO=+WS+ zS-0|`dU$Dq@ARkR*3`oj+(~Z2mxkT9sNXm4_8&(Htob2Vldoajcr3^0sw|1p_uyD| z=z7b8Ddm$$4}IJR$nVPY=Z#{*;pn|BEeFO?W?qK+oqt#KEpSkjKz)K@4K{~5g6nhXRMGy)*hc^bR>$?g6-c=i7##{Zwz|9H?L_kWV(8Tv*j#{Y~) z7rj$3dw+oc!iT$_5#F3?J-o%c0g>2j)%|H5Oee*fn*+OToqn98mv(Lp+`9fkBBR*P zw$diI*f7a9*;;3{JMHQS1|R<^QkKj!H9^T8eiYt{lt}R$O0sJ5$dQqy-6yEnzV3vA zz8RhMo{R#p^f&670JM3v@wXq}Ng;3EEEA@~3)7%k-=dpE1me|87rD$&a*OD1K#qGO z!v59!mH3O=5JkswwY`UREa{%_LH80Kc=Gz=@%VDNTwft6ex5fE&!I*}_#9I~I`g$U zUGZQuR{YbC><2aCi@`Szm^z|G%B}k-?G92y7fdvl@5I=g93G+snWX+5lgn z-q6?OAQ%Z8y7Q`=?Oj}~7~3Zt-l6ij-~PD1S}4;dC&T_i{`m9_Gx5z$Cf|kWb%hwO zt3F%l_TPPz8~(+4@Ln1NF-4E+=j97DG+*V4_|g~O%+GD#i*;8a`XBL^75;gD%Dv2& zyfI9EViMeJyw zXr&!GEE>3MYNcX7`MX`88MMt~G-` zis2Xsp2x{Hp2Z=cSsKJ+DWFg9GjhlqC9Eb4f-hr7H+QD;U zg+*xLIs65Pwtg$6vo|psj&6Q`kA4OyA4l2M`aQ2+qkt9jNFEGd?3UwK=h*^<;< zR}`rg{k;hUH*N4=nxEJggO47hX%9&A**yryCW;Ss0vw5k(S*J(dHiMPB(kpC#38~( z>CqEkt-PzJuD>SVF>>jxO}GOnea%g~a992N2Xie!(kZliV#@(f>D=vn+x3kN;+3`q zVd_-9bITQZwIWQX(Ch1@@AAv>V$a}&GrEGa-(2d7gD@L9C5H(x#0oHC*+4bx&N+g3 zknipeRDa+6UPkyvH^c4@WG~TGJGKt1G$_P!P(cnA$w35|)+QW17EdHW)UKt&x@h9^ zf0w`;XwXGQ{K8pYIXX&`17ij2ddU0Te0`TWQfg8Wlb*Tb&R<(11ml|;ten_CF93vt zY6s@_J?eTHLk78%8Vg3u8nG(8LMh4t$^%bSzTC2)9wQ9$!+ZN~_+=4VH7;xMFkj#y zl4S4S#BL(|PIu`<@<+eFI;V`RJTUtT&D}#dLx^8gh3Tea>Ck~2p{31YsL!7YW zO#!U2WN0JXt}#v!t&VqoN|grk^k|wiqTu=lP4v{;k&bdAOP|EIPatX@0#MyfQv7$k z%cm=|KceHzbGPA^GF=A z+-EJXA>JV-H^nF94)rPcNd{jm2$Q=j?b})x`6)H8+7So^H|9r4F+Aj&K|WWPZY1~m z(&@!ty++&m_fGn09T**el^+B!VM!8b@<`M{s8@532Fk~e`k{Dgi^erdDHl|fh}not zGJ2%%3KlXc%7vB&Jnn*p5XNQo_4rY+ZgB9qaaqzbq|d62rT#dp z)I2YOiY03r2KimT={01&q1yg6Ia49t`3i%#I|CWLw%$*qyZWCaL1lcYkl*BOLs7Ve_;Kk zAqg!1`yqB=uO1wGUpO1niTuOVP|kNslILIlT2-fDq*4%6di8KFoN z5s|-)DiPjIb~OzNJ;O?P@TNT^2r{sR8+NajgDnksE6)(zB>b$p1!~t^l0J4BrL#0C zesj03Y2FHcm)~o`R#2*zKqkdWXh{My*AO~MGfLRtg-kRDQbZDAM_#@ORML*)FJED% zA)}%O{_AuYnoT5`2S}P(pwIA-Qa%JWYKBc(bR&~`2~b_vT@a;$119Y@C6hMNmj??M zE36eugp9com?#fZF3CA`8(SrOlX&kL`>j4ugO*B@K8~T5i)oJIV_X%UV5Zjp?+;kD z56RSTjA%ikYl6nJ{b+pL(BEmKpbI_I%#lc^>>R-?88{n(G<`m{_ z?|ESd%v_$dLwgp1^v~>VL+FZ-%{W~G2`1pf+Z{%RoTaZjX6v^<(yBwp9OEphTYbS!J;OPce zy((#e^;-U{n2PDMU+3t3bUyQ@J2746i&KDt6dQ0lZxSr~^JO^jUL^G?*r!dqcq|se(`%;qc3K&k>n03uRHtw* z581}{W9FR%Ah72hP(ln$Z1*2SWBf;&@c#kS`i4%HE*A9vF?T5X<^Py_KpT<~Ak4xd z&t|Ik27co#3KCA<-*RKOWo(fG*mRp<9jDB}E|?P#yp;xblfZG|0&m*pfc8+9ZOo<< zN+K&cbc1sD;_$)@VqM_Dbo6m%xujz4*5-#)2OZJkl%gUDXMv&%fbA znsj4FS$5JI+92|vvf~(3U)@l~?>D(ed74%AXnz4DY+nPt?^nR-JBL`6`uchPcJO((BPJH0tK2>Gg5yX4}!U^ybVl`;^=c zN#kL_hllAlkJq%T6aJo5OGnd;tT?sF55`^Y#PM2fxT%@t#~~S98!amo#eV$G-Hs9T z`4-pswh#mFV={^k3b!<)Gj(Vx)K|a_sbZ(Pc-%aZR)6cH47PgfF$(Kw=s=mv zxRf)eO%tje?T&SXJ=`ExgAyLRNhOca7Vl!0dtBzC_6nKfjL4(v1eCY+cY`~p+c$nj>~3K z+&ka+tcB@URjAUJRj%-GqrzdaSM9wkht=X2j)i`gnwcIZOX4s&V`n_qh`NWlTC&T= z&MrYHA3oc>GX3fxYUJikvr*`JG`IpU0Q4E;$bqAJQ3?kZ0zfX5lzx{L*sBLSsS;`v zBfmbHu+iw+wQEr45 zC=|=5um@AiG>_8$QT$H#y4_`N+Z{|RBKdz_;8N|KTKvuN|(T~vO#sPl}a8g z&cc)B2`y$>$WQJCA`YJD>}BYU^#>D_MGJNW_i%FUk1TitzD!D3Ml)nuAnhz^76?0a z@r^9USwR2Tk^af_w^H3YW(g5Gxqndb zHQB1tTd36b-kG>xarQ1s)4$#;Ix~|Jii<6)?|<8;?*&}42e z{#D!we~amw9o%ZeZ9%gf5L-YQ_uT7YjDQW_B}i#OsU0YVN;4lK!y6t760zdz5yp5} zxU5ybp^Rw`CUptV(6F|CM&_q#VtygSTkUQw&Tqbfj&JRf2Jn(ZS?NJUY@sM>Gqt}S zE5&Ott!>Q=di}ZC@kx_&Eqkwvm}poWLYIOST)B#{Q{c1UID!mA zh~dDAx)GrhQStI3B^3S5W27--9>Ue=5kqOKDj+sAq$UI6J-uc49{#V!>~InzRMtoi z^~11>EUF1jnn@TZTNx5%7$kn7KJ(8e#@gZ5@!(Nqd~f_6df15=Nk}zSg1M#IyP0~d zX`sE(~?KhFfPn(d|0evSL9>kd+*S-%;;Wz@U)8D zzOOxB|KP$+%rXnB*0b%S9l=~S$t!iMHl`C#+$($9^f!@IEIfpqT>#kbivzxLvI^@9 zPaqmY^UgdqG|}lh;3tkb5OtTH1p=gGrNu5JJN+xaieeA1B&>Qyoe1-&UM`aIh>%W$ ze;5e!=UlX9ba~9QaLqwTp3vUKmm=)k&nz$^xa`$mGpghcM!}N5)o|gxSl9k^@VwKr zIGax=g>}UJm6lmmp|;B5owb%G5iZkBUUCF{6UfEd&cTV@O0|Z27y1z2a(%VU${9jU zeF&)gK=8eRb5pFHR?ux^vnv>cdw?;LSSt2pL!YH+mL(AtQ*uH5QjY!7bmOGt0v}QB zFPmka>{5VC=JE|DiR7X76L2NzRW-6w2%e;H;^iO?kJ~GZ)<~G4mO>rCvqJR8WQ}=M zIpWRPhEt|`4Kz{l$*%EFnKqClk-|BsuEc)ja>CN z3wgB+DlAoti_@T4D;9@P%p6%eDW&RG7V%txvIuIaCS#(*%6{7I)ddeI}o{KX`sXS&VkZ$t5 zNZCp(t*4ayM45+EHA*ojxTOw8UGjF-!8-v_3T}P@T2d^)Y}QV8j~M>S=2rU;JxZse z>&dtER>MX4=-^9uKI+<8iUxyWET<8k#)r&OP$c;%E`=yqIt{46@48YzL;i!R^dXd- zUiF4(Q1dU#4=_240RlVi04B^Bqe1xrCjXu6`TqhFGY8lI!jg))UEQv!pH`S>Q@{@_ zAz_v0aI^O(+kvoDsUkbGOGug|uJ%RwO;@zPDv)lf`$8m}q}$+Vl9KeVy2X84OvVNZ zQy~{h8pQR;d!cvGYE_K=o@Z+OV5C1Eb7l_#Yy$_Kbti*`1zU&@Jeh8)oj!UHfZME~ zPnkI!pI(=ovp=gsv4hUtUZY-VZ+zvCLv!+9JpeOuG@;W~cMB)5-#U7Wp^Cb6aiQ1JMOCLcTBPyB z7^u13*63~r*55B!89lFE3M%?`wc#3q2A`m1&o*n^f_X;~guT&>&ii60nR2)5+ckS7(7x(%~l%olCONdk=Gg zS70D1xeOW>=pL=)VNF*1>4}h9a58me5D)bvUyvN-CDWQEi_Ug2+^y!{CnSl}y1hU9 zs@exRgH5HdqTNAWuWpx2nPT_9JL4BDaP`tOz>l+nKieVm`jqV3bK0k2d&&(vHfP6! z-zdIh1f|k*7`E}!qMaQ?>oE>n8C1;4^rH%WL+KruN?4fSTG|Yk4WA?I>I^z*|JJM! z?&a{k8v=VhQSB$TXWH;fCT+^Ti&cnlea`RTH8$m#5i^RFF%w^H*W||9K$~PN&op>w8fQ%F zjJ4LJf5g%i-Gw(||NUsn_I_{5mfIBJVaK9RRZ%+42E~B7%4{%o#zgdZ)jfZ1mG$y& z`(n*+Sg(HrCU9-4qD>I&qMA1jHEvuiUGP&UNKF+N3r2b8(Q`|j?~*)YVLNFivm>4# zeXWrqJx(ADNltW4kEGP)w4h6(VWqs+lQ9 zMgkDS$|R@AmSNFQ2q&2_1QnOMY;*o+?Jiz3!ImYeqkzS?88<=jJ1CM1F6 z^jzc-uxgffyXF!o1rf^L79a0L^9tedg2*+ful%**%gB9hL(KDct{2Br>Rfvp4e5sn z+JF=2Ivy=3N{<+ThjcUE4)QWY`f#4*vSREyCXa~Mf*H3{3;X4T$VPvaS9jjRvW)A! z`GnrAk?qt|k`;Feo60MtUSmP`N$q-v>tlL1I8#`^0}F-Xmii&|)wR;djvC>bnefSQ zX#i0}dz|XXUv1{*Zat#p*T1!Syb^r=oJm%9i+7h{I3>Bm)U|}20uHTmuMeRE!12Zi z{~Nta0tED{FFwDHpx$R>bCLNMSt?}7rX;0JZns8wxx`PmrRyjiIgPXI5Fbec-0xEP zobmyUEL@0b_E1(ja6EiyN`~=nlF?zQ=F|Dy5nEZ2 zXs6jy;ShQ&A65^c;$gLDwc;tTG7n;e0xvY-IBY{l)k;B#NB+eY8^eh1BX|QN%;wm3)}H`%5CH^sHU~ub5P8h`6QI!l|CzIu ztF6O-Ba}q`|0K@iWBOo>02XG}2LrSBJKYzLH0cDlt%-2cG3_*+3hN$T*CMzxO_L%< zWkX|tfZb-=zwej>+~x-@)K(q9zpk#EL=$Zj$5GtdH`45T*_Thn_KnyeD}5f*+jjIs z{XyLxrN^kUs|Ks*dCP0;qu#AAXo?OlF4)un3q+Hm(CvV5;yi~mbG4h_JeA^5siQX+BH?(%rXJ(J>^wEl;m zj1yW2|J5Lz`gS7X&>$c3F{Nbl{vm<^S%(x))+GJU0^=HEds>sm{B)Xt8O%F@m#Vls zu!t!I-65k0t33&B?yG`szxAPhTt3S4S({GMB_W5~|5w7%bO+Hvr@yA5myL1zUl6ry zYf)HV07FyE;}~|YVFWef`@P+;v3yCF3WvNv19<-Z5t#(>?JYs0_=v#jva3Oh-2>9A zpqnP&4ier@UuW3bB(FoCbP~-fgX8p&HoDhH?7jjF=@UBCyk7*OOK_bck*>y9lsYWL zp&vJ{e?=b=f(Ce|bdT>$Yt1Z!=*fQt?&M z@1YlHBps%MR_|9}^ig{qxRH^3g#~9a;3e9dG6dsW$m&jrD6pG7Mue7nnDDMsg$8$04n1K094lyNB5 z{x&E}vN5*c=GV6|etvJE`K40_Pmvou|3dp+xvF!a`d)+DMWsj{UCzV7YuLgDdsZl( z_jds@2bw!yc3oeFg8w&+VLYh*`>#V@$o+<8F;8EVie4tTxfl+>9g9RvDvLIJdtdlA zN`nM_tYG7>Lx~t3@$k$NZI-UX&sUk9UW`{2u6eX67GGP8?=-_K#pT~o5k-ytJAdJ7 zEo_&C%b%242EJ1W3ZVWvtUnIyn>vls$bCFqxWI3kJi`hSE|f%I1;CnOWk7)siD-k^ zkYXSq6@iQVXDI`h`Ojhkm5`t#A{l~$Smv^Hglv*U5hxEOIuzOm1K$<=A69SW2RuIv zfDj^2Un>1?te%a%xux-cos-?a|8Y(;eaZkvaAjszc{YH3FIj%LSCuOGoE>;q8H}Tj zMC;^k%eoa+=Ww->MQLciO)s>hVx-y5$7BD9k{T%PO(U{)8Qs=QGa4l4$1egOk4>9D z>DSrU9`AdkM&}N3pf=axSeS8RCkw`EU?YS2+9Eym(uG8#~Eo80lgIi4)?J9?*KbRT7u$zg0e^Kg%1a$$0xF z+rD%uDp8Vn7Rz6!-}B;Z5+zTqo1dr?U4V>gx@3{a^w)iAV)s+<1QGTPdj9J^aQZ>vVa zh+2zw5pFRLXkFc>zjN2TF2BhR-~s1yu%vB1AO?~mEd8cnh%4=;)!8|qLAS(vw%Hab z70K^gYyU_NKU%x>TPL`{QE4f_eWuek=+5abZR+p0DK3fNcjsEuEpPJg>aH7D%O7m1 z&1wDoQtwBa^r8kfe>QxNm&_rx%NDIw2$Xh?bB!saLLJnw-k3ldXB_KoKJw&`j&{kdf48wwf8hqO=wGFk2PpR~}fPIMQLOokmtH2toyBK*R%ZNa7!Zf$R<)N>%FhpZs%AhqrWAKBy8L^)E zC7LV#bx+zuxqWB^aCt_4S0S5JW#CZr{f39~--_n*d`OV-%)QZbGbxz_lyA~S@yVSUL zg*PqA2ggz53-q$fWT*8K{{!Ll)ZV+g=-%V7=pU%PsMw`{OWAwx+~w4V^A*Z;@%Mz& z3Z$R|GPppj>&O`ny}5ET+CB>X!mEDHF?}7@`jgSKAwS}xi^fiC>zyK3)Jw9|s)I`t z{4TvO=WYD?@kzllpjVI0cfQ0L500$aOBE3@VSFoh;+Ce?bqcxj`nxlg)}uX-@+!Q2 zC`qjvMG!d?LXWaA3&Gc_G8qc1sEn40G9)eYcQx3r8ocVFf9lVGFAo$^B1x?^6FinF zjavrVF9Nxo)+<^t%zbcA;(O<>joIoMOo2P_O-{gC3uTSG$GD|@x{NqIdc&eWWyMUs ztwvHyg*&!RCFOh*-Oc-CR7~P@i)VLSMwJa#NPzh{G1orOJW!Y&?XR4;A;90hoFO<; zge=r}Ft8i}e%KzWf=pn7AQAdURY!;;1|>L7{d1R+mW#wMjcFbc~Vzo95k)}faS~|u>5Zxh>(Zl zeD;3>%eI!z{}YcMDE|Go$}}B{_5+rMf55Vu>h)q<|JE5Q9Q{J5E_%c%Cy~uoI0z|Z zTV>IJQdAZQNKK_K@6m*@1DR8t&`<2}qJM!cDzW3pynkml2R?}B2fd%kmOes_6}#>B z*k;WSJel(rLl<2O|2dumQJ~pq+F&*>HpLv$6jN*qHyn{VZ^qHmO=G@Z*} zQ#^3l?+NC#uZnAI?kJuOA|S%2?Z91@^(W`@;X@@!!%rj|D$SNULbd4MoVFZbSdw-Q zck49zir8wct;FTxwpd#mC{+k+c7^i2My3ZJP9biJ=p288Lfha^=hgrx#Q0bRre<-U zLyL~8^7v56=xhXvG2rU2;ANV3!33bzt~C}%M@4#*ArVG5Q4&eeB_lKmg-tW3mw53T~(AjR63qUI)Nv+QzB}RV?ZCrcSNB9ZdSG;S82aird(+ zsg=4i{VGyfXF)Ll%f*k_Xe;_GaRu$w(g7MDYVc0_mC(9 zx4$B9cjMXZL2RbGo-s&6X;l)(-po5L!`HGs`{_6q@J21h({%FTMWXZ3pq(UsJ7vk8 z0*>_)EUxPAIZ}9_@g<@GOTm5(N5JvDU3n}Wv*Rb&N#VVc$_InyBQIG+pMoOnft*c?2<~gzIQT+7&ZUt%gc?Y3zx=lb047D)Ti(T9C z4;psu1nlg+ewAkNiI#-?`g;GwQ^P-qx-b$G={A~EMgRN3!mQ~f$WP%r@#z=W$w=L0x2(y9YOZZu`gVV_8FS62 zzHQ%1)_C{as!HOh#n2>?qORtj9@kz7Gz||&3)HJBY2HM=s=njhY}DP<+iJ&Nw%%{i zR%;y@e7C|mGgBoR9Z{)e>|fi=%RRfs*@x!qY-j(&4+lg6fwe6I5o%+i7yobku&u4f ze*tch(f>G<35yRfMhIaRQhE0O;fH-X=#+BRZ7I`1&SRxOb3oQ?$(k>E1IcSQsETH( zTKiq4UEZfTm^yZG6UUSXh11>pu@Twt@jY;6W|&zHJU@8s8Lrnda;wVYs(Dd%wFrkH z_?X?C9|c=XW>NU;y4?NSVxKtVrKSFE%9+`9dp7dx8tc^c$Dbv*(i}l$hQD)Tp2cWB>#^d7uO(kAcwvcN#wT;JQ|lJ%I)X3|>P?Tk(9^c@{nYiYAt*KXOA z3G*x{HHp0VK(%P(?b}AFZ+3=verAd2^C{7X;JLrAOtp=m}87g6^59fU4^#2(!$FXo<`;eNdZ9~R$p`a1c zUwzTk(bh7%lXLV49bqx0JK&lxz^R2j4r=Qn&^Js5$bY?dGD}3rE|whsTBPlZXo<7` zkoBDgHS8G<97%J=B3kBk(RAeN1)+uCpo4+Uwu33eX+imYU_6wJxE_u~2v&lZ`BoIi z>^HO~*)4h|WG^q-+dptED4q~I5vce}o_P`~bh$GjF?9ccE3o4mk!~?idte&fLC6dU zt^d;ad)R(TVkM~u9m33xfDHm9{`3(_*n^5!x&)IVjT?H@x(8Xda{Cf)d)FB_R}MnQ z?mbp&!d;XX0P(4S`ec&B9(?6Oa}!XTf*O<23EDh{vVe2dB8|D|Rps8D$ncFCri+l5 z?)}@t66mXgV1gm~JoLTW*45|?^UvhkA_EdH$aotaVoGU#5g3)4zLWJNo;pk?%RyXH zCH-2nguP3=GL)Kn)Uhn07s!Csq_)QXA0twJBwXWIeXm2_v=;Cf4x^vLLb>Xx@41v2 z!eg{uk~OrBGF=jW=D+XsbL1}8_VqAs7YR`YwO8YPMR85UCRes~#jj@bf*O;8nC+(C zckjV<_}+|t#Tw3N*?-`(igd1gDWhL6`$ge#~cf9JN zYv0<;v~oU{_QPW*74Nj3!Y3m!T%m!;;fpw8rE7s(IErn!f)&b zxbSET>7(PTt?MZN<@k4dV~}n(mnP;Rgeg=M0^Of*2uYO5?Ze`h3q7@jC{)xe2<;Ue z0^2}K$wSY}Vx=7M0B<Nfh$HCY3P0j4_N)=yy zBmPP0jgWhg0T-<*L4y;JAKzDKZuSqFUq!;|YomGbx6-@9>G!XBf#kK=i9Zf89?g8o zw%G*ZyzkJU-uO>|M)4t?QaT1@D#%R$s+`VmU&mh0o#Dq8x!y+jRVy2gXol8c`X&C_ zu!GjT(%!?I^;Gm(Wo1J%2HSH%Ooe;qu%ggUrPumaP6Fv(hp%Gis)*6xsckrU@c;W% zN{Zwq6Y>O{&0ixT730{yVqn9P@te>`i#8bJi8}iNskN`5{|nBgl&VCE)h+rSn+_ubAqjDaAux8^s`dfgsziWeS_r zBa6??Y%B=B5j@u92W-)``mGyQ;pyR;g<2%-pQuLz$gsrlQCu#qITU zsCcXY{L%Oyh&1zDx>)6&u2;pOPpEEp4}|mTx(GB(_{%m^-MJm;SP*vCl?1Qf&{;He z(Y7+p`{=lNAmD?6{!!o~dH#@2`NOb)@$8Y1s9UZZ=rGD~k~aGBS4=0&u%6eXjHfeEH}}Mu zs5zs4p4X>-am*y1t@F~my+hf6-vqnCQJ)V(+y=Fep~j{ zC6KI)k`2!mH zm?JM$rFQauoW#bwPmtcaD&Pe|_8@=KJqj#jOV#~&p+EHkkpW!>RJ9N^-jI+J7^cwZ zDgDF+GStH$uaIPlt+y@xhavbTfnmB3<P^RmrRryN z*lBGz>Ty?~F9FnT_5FjA{i2@fJPMYS^n`4ufM(*>vIEMHcbjAL+2jMZJd_~-86Uxj z^*qi&L)>u>RLdCqIN}jD9GC)@9P>BV@$mB>XtaOn$1Pf6T0N$nVygpmn!OC4e?JDO z%C`6P1U*m=H-U2fU4|89EwI61_QU>CYNw!lJsn`?U-j97T`i49Sp&6~l-HeGc&(h2 z&*NOd^zo6zjvD0|zlUc-+vgHp@W2o93twY00KH^3koj$V-z(kkI-?yDj(xP;IEtpx zsNtHTS>C^lcl|Owu^UEh?((ZblNr28VUJL!FmcoO=0k$wBlKs4iw_R&Ml1poM|Kfl zZE5K1hEuIhZ{{y3fxTXor)TB9GKoO37>v2E48>>M zz$`_N)=WZ?XYo4fn!kJrp|1Wxd7>God)N#l*>4Aue+x?qG&_Gwxs;k@GA7_XOxpF! z=Wru_jB__g*Hj@CCq!j77!c!^PQV;|iG#V}+8?AwrS;_d5l`yHh>YEr3H*%+rvbg6 z<_?I6_W`6|T}!T}#Lp3{YB9$2;WT>Xc6MIvRTi;(E?notAaEPnZrXyoKQtW-yA?K8 z0JjM%dXX<$L>JCYtCEcV1N8EfVCG--6q<89Yj)`yb%)DAJs`H@JcpA?cWLqBP6qKD z$R}oo-o)%gzP%Y~0;h7V{4=#Vji@RADMeurV9ks~jawep|38h|#quAX@4uyJ_xpcq z0*PRt{|sIKGyzBVpL?C%JGvD0EQTSl7T6ZsWRNsWRcNJa!5kSH706#v${4U_YYv@b zUSoh@ctyCD;{3 zIdx8e%=osg7}bt!S@qC*GerM6f0C&kJ!J%`E?w_Ue&Q`B4ZWE& z23y&s-riw6$YzIK38eW_evNj6sF^rxM_ik1nwduOWLrNB@Z+ccNC4d$hH~yv`XneB zxWRS5+w@PQkjMgXjrFQ=&7wy}gIhGyui_Po-CQnXs`|Kf6RuRL{&&&vO5c>>E{W>* z*$R(XANp=3)Rutv7y-rrq^xR^rp~#ajDsCl%~hwC@VnnRQ9s8)DY6$K`6Ck3?gg-< z)>TvI@_~{cThQXL8V=>c0+-D>BkUK^-C~fIvu~$OQZrLLMC3TgptxKu@sk)32EhA(!A-*h|@2dNS z_@61yeCR*W%^?sGoSQ-U|2KkMjZAF*8$mGg*Z-rcX-$Lv8$px)pAoc7-um@0Q%C(T zhv4;$%hvKG`3(k{VvOaGCHK`bxK#2E|NT)7BIDpZ6SqG5m4hB&^hPK_sf~O1iMN)6 z7fC!nFjVQlD9Hp6vRvpFr|ne79n27d7mq~T0=r5LLD_pmkLy48FH=d&v{#14l_CSz`-I>pftW+9vrK_@G3|ZXsI@)p9p$kp zOZh8x#;41|&zz`L0pvKTcb;%p1BB)sj`#{@R&8>%(UxKCRex6dkPRa5nIuE1Tsan^ zw}b5&pkV$O)C&X=-S??s?lYSe3y1xQ`@n%3Kv#o+A8%8di_~c4Rljt;`+iU-asHFo z4gb=8CMSMKNN&jGiup<CaTJJ=rnf~Kj{e$_Q+2aqRumt;yOSEBSHK-g2heX8^B2xC z*3qqmy+Q5H%WswvazES7+M=e~R!l-loN6Lrs-e+DD8x!<&=(VmQ=rRe`@Lh3mLorf zA13%}$fYfZ&wfCU*>YuH;+6ag<%LSxg>1-8*~B4~5ty>fHcn8AJIb|>YuGB$azvR= z@fFa!?Zs_^Oq&&|;Ia~ar8bencve)_ZY;)SR^UP-84QTmX9|p4-Gt{3?6DM0{0yn6BybSV-P$`^lLid)bJ6hi0O} zI39n2Uq^7vfWEvI<6@D}bDY@~vVoz)Nx!Oi4ME%nS2OYIFe_-(C4*>+%m-7LO|PBS z7U4`JU#=srlu!QiNaF>gc8`%y5RQJ*{398c>FispB(EjhJAbNC{5&pRS4)aQ7>roJA;t>1PtP4tl(dWN%h^UPr~eFWfGn&3NIgrk z$|!s4cT(f(i=6d0z|NXFFlz~iE*UeGpqkkx4==g`sb2fD6l_tSGAGg_ks`QE4l>uR z_OF9@IVulMPwUd#9Yc)0d;q(ykLTrqZXnBWqHn-(M1j5e@B-R=GiT0QyN2rDY}tf( zg;}mHuC-xgoAhZcibh7~vW+B$!p~TVAKKu1f~E}*YU`CD@&|9_CFpEwR4D{hMPfX5HDbN9g+5gJ*jM{iM{cP>_uj-vKktuW z_&&lCVsQwge1HburHGSB2S~3n0^UL&^`GyZ^@;q8q$E!bhc)qkuyeN=>_gZ>iM}lU z^}BnZIHaLq`)6mfEJ7SQ{wEm3;|f4xxmmz%T-;sOdvP{C?0E_cnLzNNmA;vXGf6a2SO3@W-l;vimrLCM#npK^#Plf5UmN9Uwi zcX3+(Tuuz&FH%vb8N5}d+i1id+<^oi1iy?Z0UJq9xBDH()|aS#Lo7q?iwlOYmNoT*kjck~mdvN_1tSYuniCH%13%{g0*FEOI5dmsekxIu%`Is``iJ zwunJQFOc^agm1;Mx_;m&Q-~nJ38Ye**glYyUt&=&S%}jGBLh%WdBz7=Wy2J5gW^o5 za@fKfo1gf2c&Qn<7RZcs$WEa|uP@($@{t|5+KaoCAtBl~5rtra)pYzCUnU0GiXQ|1 z>)M!E(k6AbLJ|l>J4se;2n=exu4t~ta!g1gai-*;MPKpZWV>gmH~1*H} zS?;@ps|~sq>JuSKha?|#-f5)n&=8d8hi8ZP%rbw>JcDwq!Rc&)>-vIdLon<59mkzd zs^n2ec{FHy3P z-2Rp0p681~u>g7(>bdP_EI0JF>k^TM$XqySm%X7rn)gKdD~!SmMO+B{w}S;(Y7qlF zm8Eb|C||RP4Z+S`MV47JDvM?`vre83q79_Y5R(4^C;=nN?xat;iM^?BO1^WSdQ?YW zCg!EHJG%Ubf#yJ`!Foz3McPzKou1!}VK4Af&^+A6zA9kQL0xF{z%&4%nwXptvO&w_ z5sz#}CqZMjEvyh(>h@O3*?P#E~Ry=j5VO@(-HV$nI^Gz=#zBN*c=q>5+bePmWbErA zU9A-W&@F8KM9d%(?48-+e%VSEb69cJ&;e*Vv9t~rlD;K*vYZRT8D3XFwI^{AKIahrY zf0Po7N7e372Q}udoM0iFJPejpmr_MSA-p_3?JK$*AV{f58X3GVOifJ=Is}d6%=Rl%V$q9OHS6)&`LH?K%=XIPgZLC1)Y$0HwSe8$hS4m z=t8$YM6t`yy0=tz7*{Q; zZO|WtUs3n-vVoYE z#F51cVd7ALJ|b#SlU(sLb<$lUe9iP)+I0z(Ij;>{$(C}cd%&<}kA&e2Shm!MFimx? zC%#`J+Fkey%>J-u)1e04BP;wxAc6@a^tEX0X5bjjp=8-o#$|*1NH&{9e>?>bDSUZ- zljr@84MHbv)p&be#6_80al| z(c7)lh;c;rDIV`p8WUd`qmDE1h40H@ysmXm38J2H+Mk$U%H00B>@-ks+?BB#{Lh55dc*y4S z8Pu<{atm#uzluJ+j);>i?qUy9-^paGsHN!OyxL4ylaYWAre?W;?wN}~XBSA{&Sy?F z%1n~XQuuj-z*#a`D1moikRE;9%koWx7ru~d;*ftx5#VMl4k(@Kl9J@-mJ(1SShyJLcX;BP@)Ivm~nK&qPGu)S|M9(NtX4LK>JJOm7NA=~DwUCKe3A;P?)Xb8S20 zCmqXPFq~iThMF+wO?8}#8v8?rnWC@m+-~lBDr6C#_R$JN| z66MfXRGbP4CkxhCmt9W$UP52MavG_0!omN7mXwTwjS0*~io;YUC0VFjHQiw<51@0q z?Nm~O4BqijqR6(+Ie@FB>`b6zE7@1QGmOiv(0bWnlqksZ!mk_)(qHGq2+NKH{i*M@$ z2JPz*t=HbcvXz(L=vkPTB^1oRpu~m{?J=|E>CV0vmCyDjIi4U2;kF|RnN&|kGWNJ8 z8}Yw$-!!&qpd3S`wAU5r2M=ltjy8`tNehmO4 zDhHCK0mOkL{kMt0|=iVX*>`69`=afy)<=&Qi8 z1Js4$dkgt3>2j%v> z1L$M7nB3tpBL#3O|BY9%7=m~lZk_g&%_U^u%!kkuprbIg zW@*SdqP$=I;_XW@ZTb0sH4&d*Al z-VIE7u4<72w1ej}FN`46s@3jG9Hexl1}&=9N&x~>DK5PY?v_h|LB$@fBF{KV9v}79 z8@ZNQs}^iH4a(FK9Oq1_wn*g%3oZeEN6)`!-KVAoN{?jj_!C=y!isT__y7b!zvd%I z(F9!ZY*3oSp{wtHS>O&woJwHuhN_4BG9+ZG^(Ekk8}mE|ms!;MB^sl@7ZDDpA4Jep3)y~#e6 zyE)?SEMG5HFZ9_yx`*XFt#+^71>_sy!2{u8{M{HBgyj2|f#(5eKWo3=YMUVL7hEExvxc1G{=qI5hvLo6TGvsN z##LTe>g%4O+ckpQ5#E}ke~dz1SnO{;E}c)U2rbMN3sRPJyervmfs_EF)AYXIbQ%8M^1qn+J#RM_=u8=2U? zf}=~l{l}klbU!pdNp_hnqV?|S10+dytlK8?44NV})wqwt28Wr4&8)T#+qFdPc!1STTd2 zyy>-7lD`EQ6c{QteMZ@$stj>hnRow@n+D^BH7`)L!pbv9ECT|S0VsKNvxaQ(jv3fQ zV_CHKe7l}w81fkj5ECmy=TAjI`I*gV)7WNKq+wCVcIpjeE-~oiVP@&V+hX?B09p_^ z`rrV54MOwjsr~gc@#~hqd~j5+5L4qu;?ss!>T49tWO(P&;;hML+DJjHv7|ir7UGOu`FBAmu z8Q&~5m9Ze!;=C(?+2*LfatONgeR}&epjoXAeEj3>9Ut`rEDM+#l0ghR>c=C6F zLoie>rgLre;zpA4tNC$xOQMk<%-SS|_eO_%McXYnAQ2NMiGiVc?$@?q5uxdEhl^_z zVeKj5rUOR=@~^%XWUg+Ys_e?$FBaY=ZqjRWlct=(%=i)Z30sKUU)ww~|KLhJ9p=Xu z`7khQHN%kOiBtZ6vjKn0zli_h<1Unh&wcK@zhUviX5yNZ?l~@Jho}r}V+t<;CU>fdFA)Ppaz3=u|@Szzqp+x+Ob6IO(zekukT)?`zJl!W; z?$HLI>F`x3_CsOPDv3nP*eLbKetJiF2g}ut3=1}(eTqU5FT12%4z@hXq+TdYdJ`ID z7?~F8XsfSFY@|jjge&$R-ys9K*cp~;lw7QzzV+|=cg{S9 zQy3idJmE%ao_y5$eSUl=cP&!wIx4O1r?SGcYsQYisFkeWV7_u2Izlh$A(wqR2;>-p zO*XiEtn8)tin+TKvoQ|W-=x;=>0cC>ZgRQ2Nc`FS(>6mLuAyJ~VMe`VbG5qPykFg( z0Cu0X&F9M{82HPkS#Z8v6w<@EH>@FIF%+Uhy>N>lm+HvZfhDKZjR=`SJp7a0FUsBA zM9a}_>87CfU!=OQ@H}p|kTWtV5|vbn>VzE(Axk7X=krWama0UwrHmXiQG|#}Q*hE@wTd zKDl@m`q271)n%CAL#^>7RXv0Rw`{8P0UGo1e>c`bOn+LUy0y%%?bH)F3lA~}{;}0q zTI@a~{SHpFuWbmt+}){X@JWJfG^S*WQ+J;!PW}w-X!c@VP-U5=7+QEUmiF&iiRTLf z)dT#fzGmy*SP4rHWO?d5AFybyG|_@jNo*0u?3qnU3*Me-cLSUNU^$oiWST!x75I^3 z?Q*g@l)p)fDuo3e-yV8#a;2m&bI7n!so}Xqlc1V|UGLoW<`riiaqGkf^`NYWd9>nJ z+mBs;3N-ojgN8dmGIGwk(Wj!RObNp9orr6(dV_r_ZvPS@llpOJHMA@0?k$|c@Y6t) zf_ckI;)pLp+X0W$9fO&qkofYe77Ub%`27RPKh(?bCX(xJNE1_mdx~T(fCUYmIjNA0 z7gz{wOM%vN7!VIHX`8OM`ZCS3JT7E4BFZedV41D^r^GPCTJm3--5tz_h`#D5+l?n9 zS|G7lI6h;1omIB)eb7V-4k)W2{w`WwWK@exk4&lRthVwr4+XQV2Z@7M1F7X)M|)C5 zkjDKT9!yBQ${@aqlDo!!BY+i-ciZ|EemQX+e6N4+Tq^O9@A*MThy6Vs*=&1^e97iuEz~ z;|EDpMmWbUl0Zieqx?q#U944di3s(ktrxBlCTelJiqPx9 z(-HK?EDOo&gO2A4Lv7pjASyqx9Dne4P;Ie>lvZKdJn%H^J>m*Z<5+_9qcrPNxKAN^ z`0Vc}XYQ8r$!tND>Ef~6Vh&ExI&uoYsn*|g8{r*{fQKZN3I4#w*bsCV0ak$lepn|)@H~&llVl289a^Ij$3A2d zJ`o9*WL!BB1-Lx-L*dy=rR+w;Fnm?p=tpVdkyinnHz)}d!1Y1JW+{wl$AA8iA7p%; z-k&C>22(i*c=QCnJY#d z^|wXhzv>JH|L(wFD&l;=65pBqt~cd||J`CL$Q82mcY+PKU?qQ@t3X8Z!%b|1E+A(< ze>%-&k^hL|9Z8+irL&kn{6hM8%SyYKvmP&`m-ED|z!bkJSA~7hG|FLPZ=zk*MuqqZ*Feol#|XJFxSD99`r?tw*{L~699!7LDVuauFG zts}gHEy>I;AHcwH4jP>bYVUG_vJ4V+bb{j62a=;(EfuX0h=-NvI+UWu&yB>JlBp~a znMbQVqFn5Rfa!t7d{*4Z=NjZXh@{#-C+9Oi<)~$}N%&3@*2tBfR;b)JU_Q*6Qk|ER zqJt2l!zxUyNe~pn!Uipufd}&(7ZbLrf<_lEgOiAz1PS~r>VZRLSa;v6c2+?9!4?H` z1x{bN!VdD(t;I1WM3MJ4nI@3d#^Cm?A!(7sF@FXkV6lJD32@jtL*T&8lka?drTyb} zwN>{VT1e2jS|`aIbfsv;D{5V2G<8bo^khk%nVFLeKPGbgwi9bUheH(UQ-#`*fgp95 zwfB-=iiM`)YLTq>JaX|`oY^g5lz*i}z~-3mT0@KBsw(P>C(LpFr&7=tS`cr>P&coV zt$%Jpc75KseY(i51G(}lV0zhx60IN<@PouUsQ2FeEB-_x25u4EVvoXdSju@u>eqR%|kHg87Rczp%d!eF~ z2c2QGis#Tt-80|by16;UH>xPJfrxGTxqgulb7njUO?mox@Q+25k>zAww#Ni@US7aY z>LSB)ZgmtKB3o9v9+GCv`E$OTZow?`c5oztpY)IY zgDj|h`IrDj@!Yt|;Ms?EYn}q^htRbeVJXb$r0R2f%!DP%ymh?wCX|KcIKO6S&J(IW zt;8{}la*#@=xyBGE8c1}HrDF^b>1J!GroIVL&A|8%_n)_q4y7>m;Dbb>)VK57l$X} zd-tO}&JRlqfS;P*#`Y*4aQOFCj~!14K7?Y@vCZ9_i~x@AtE!F;*)Tlz7^5}DyfCoI z^sh3ES~(WUZsp70-XWj!Nd(ft?MGvyS>_T___@fiVT#20Gm7w za%`&sqi3b6?^4ah>1jXH%fe&-U7>$5t%PE1Q-8A464JU@zmq^Q=qGD1oqaAQ(a_DW zYl1@DyiXEFU!_@a0?5d{pkmE|{;Lq3dZ|}=3x1ejvz*M!sRfTaoDj(f&OS7zUTSk| z%*3*y(`aipoAtEQWxk>4yjF>haY_6^G_XL9AsYgN3F69o%?E}+xXJjY+;`aONJ;>vos6c;6 zc5WlDRSXT{$tI~a{y30dfqbtg7@QOx5YNPuB{Wqb80V**V7s6_;)hraA3%v-A6C|s(bc|)Ch36G-vVmJ**H+CiQX@lHMo| zzUkRD&dVO!{kW&0OL)q4M~lGifBkt4VNH-aptjr_6%!6S(;{InmCyjUA1uqYD#mP&&B;u?98TTRtAyXu3Txu?N27p(t$unnvou340Da^m?oP_d(Q+$w7FGlfhqv z-c>eZaC~ueKI10psbTn%a9C6rdw=M_QCLVL#0&f2xOcCz5Y#iA47No~PB(~nj6so^ zgCr6Nn_fm;C`ZrK*2-IkDP`3!XAh2{9(m`2J&M|Wipx9xXBLXv2E3-=pqS`xT8;Mv{g7=h;Q*i(;#gVYE@*wPh7sb!AKRciG9+!F^@8pcrFm6V(88-@i+~ z@_0i{c87TtUi%ZBN>#g&FPGjSEE z>P)OZsh~NIoTvoPR^9cAKc|Rq-{TgNW@~VWgM2Kdhvf;`3#!7P$rfN^FXwTLzWX#e z;UoY)Abe}PL48Vhier!|V~&fNLh2sPvHdL?3At!opzCeX)MYdHO)PxkV*nwIz?k@T zt1dF|!|>$K{On3_IWDfW;^E-3z?|VM&4wsuq|&QkeH=+lFAetxQSCA8uwE_*HBHMU zSImB5Tz6}yna6)a=bFR441otk{e!}u`#mTfcpWPDaxw-D8{boU@wZWVU`-eiw~Ss2PlS$Lb$Qx#9nywgJPia}s4O#CdE-dsW_M8z?)QL9-tm8WJgE|x z<^$IZEFbmc19_hwXPoQxQfz=8k9+fYmHuJOzx`!aU-6t@-WS%&zbO5oxKyMki|Te0 zT5?M4%c_*9LBTi`sL))XDFD#UMjFv z+Ee1H6;M$RbfX7_$*~l1nP9B<+f5;|j;jKkqhHpjs+PK85#&UrlaB%>9azzzwb&p* z9Y3;dzEb%?dt)L!_H#w93hAyEg^_DS^0*{jK2q}w@?^}NZ||JIxgaWVENMfS^kn>X z`sN3FxXFpnP)siO@Roh)a|OM6dX6Eh`REKay>%~X6Pmck z$V}hW?YW9F>8$jc5OzZum@WsnQMU)}&tWhgoi}OS7WuAU}8`_~b z>N!D2EKSYb@QKYww2h0M{zj3izsY#=tASW101gF>Q^Z$+ZdU|WV|IFQakau9b=l#C z#Qm)DWlC$e_DQ_CjnT(aJR~gM2K|zx8JU$MVZ!}=nZy?p#4UIUhS{5R7tH|jI+pu^ zCd)UJDjCkzMQAIWD6`SW_$dsrlxQ!f!p z`Gf!+WUPu8h!#S3hakR4*EOzH{klKt`pu_%_#Vm@+xPFe!+iJOCfNYb&{uw{1WS`2 z$%85500z-vx>rvLSY*)>=;YXW~h|2k6h0I*; z90IrVX{vV7N|_dOmX7WL#s;=^lK7<2^O7F^gE%sLj|$oL;?eIB|lsCLz9Z zG#Ukt;*)sdYFzr4lA~NCNpCFtE?h`BL}t9IF1O(s#HbA!*p3gkZ<{ntIRf;ZK?lk~ z3H|2kf@6?5oa^LNNF+rYt%XpVId1 z&kaM{I^(pch z6Q-nbVk{%#NNNHg4hTZ{nI?6Dj!e<5we1?`HO?M^4DE_dEa&D_WpqtFnc93MBPlkS z`Zq_apL{6eou~OC0d>F<4V196Ih;X2gD~B@fvOD0RR@C=+Rw`>3y;CSqpu}21d=gy z9!;^19&Jud2$x1|n6hVnFDTDTzax96HB%QftyZHGxRX7Ik@pxgk_qeO>pw76IE>xr zYY$H6?LbwX*J+;V$w+)V@p^uvR!`u_d+|ljat6)XRpU{G3@9vkx&{JVk=w=$94wrx zTD}y7UPXbDgsGAt%wEAU>Z3rsEN(7Eaz?_VmVWC*`T=rNs2rk8zIg1QiaY;Gn~rwd z8}OTtYu!A}SI@L}5xM~+AI?1$N8crePBEvRiUKAasdf-{DzZ}WcR+Eyc~R~9$nmr$ zGzwckLA2Y!mLb8W0)FufWqaryRvh2=W5=?Tc|)eN(kSYJrK9^Mjea;ytA{T=&^6Lv z#4TSq$3Gz96}N4LZ>o`I@Yn8BxX*3f{#tF^k`Krv)wpb@+Sgt+1AmNU-&%jg=$$cE};uuvMs#IM7onPTKmS4$scP98e2Y(5M$kt(D;l(f| zc6j(4Kxg#Hv{pVCB^o_)Cqh@62;5h-X{)=oCSF5WozB1zU+?<#7gh#vR8CCe+{1t; zx=7UlmR1@BnDw!`QOKI-!tf};O~>FCPR|s;L~P7rP!|0gO2kL@voauZdQZUSJ*Jza zx;mfuqz|F!?Od>w6nA+y?(Dq`3=dO|Lx$a5)-}Y%O{Un5HK8DTm^qC~Z)Il4tbM$Y-)foc$lRnZ1l;9By;~866t@QY z`}lREX4vKJz*kY~=s6new{CIP($ClDC38{N9~8g1K0 z3OTT?mAlkAyrhIv8wRwZw_?YGbd8Cj&S;LWuC1JJos9?!!Uuhp15pG8`)P591xp_d z>sc830{e)*qhtmA!$IYzW(aG~txUwbEfpWIsuP0lW^QXlE(Q~aO)X1m2c&of|3sS9 z!Q;h?a1z=mu@9o!Z7iZeml2yBbe_yoVGyE7*BLj|@oAh&yxRvkf^&dyiDV{cXDCRw zFdS@(0ASIGGX05Kcd0Na5ibb!7x;i%L^$VP9ja->@IZ=$oaK?Agh4%rFpk0_V@?Wf zoO`yc8*<(2ta!Mew`y_O{x#eoiy{#pyt(!lMXK6qq3y^^z?Wb$6P`c5xxDjRLbwzG z(Lz|-Fzi4&DOdcseRxikD~6M9RO?G7}Y zx~rp+BG3E!8SX$qi3igBE4cL(gV(=mUUb{sRO`HvGm<`i4%9Gm^&GwREk5IzU8YX& zSD7&Ss7pu+NyJ{BBN5Tm7o@Oah3Fqa;e{?~Q|a`^7bS+~81@hi=rMAv=O0j>D7dX6 zOnJVMINf{cI}9<|@FPv8VI_&6-H;w#&6#3_w)YPYk+Sf@U$P(KA4skTS0vuhk$vo6 zFujpK-F1j-zPnd9U!?k^aY_7`!}v-XdviQB8AWQhp*UIO4QV|R?7fYdP= z5EIZ*>^1uPq_Ln3G_gn^e(h^)_8ThZ7Yra_%yE9niTXm~ilY0(WiP_lj}=zTU*Plbxv3~`qBk5$)dsJr;|#N1 zHZz#mbSa`rvs^i=CQ<`Ylzds)CZD&?k5Okvge4L0ut%8Na(twUdqE4F+PnNv(t%Yx+62x}lo%^px%i`VSzPI}l5mXFCa ztCXl59(r_MPK;Y_T;2Z85G{BTdxg1G-Q~l8Vg6MXwL|+vFhRdKP=zh`bs*_SWUg?W zc^19+HmMvSrupncZ&X;y$#tjzJQ+F)oMUtJ zUGy}iWJyx?XXgF5IiTc=osbZFxmi?_f0ZadDCJ2!;abPH$npq_j4#ImSBo3@~@8q)LoywLfH=%6x z5mt}*c!i~}1WOVi!h!m4?q_62_RlmyLGEehO3q}{MW*mm&)4=7GU>j*GIF=hdZyDT z-+gQ^Q0>RRBZfCCxEK|vKcR7Cvz9WG`bmfEZ+i?IxO7g4_2vF3?=JeRX=i9ka{saO z-H!l)O`bpz<#0v2{j(taKg8yL7KH!$4{B6N{r>Ae(7Gm7`bXqoWp_aPhve{@{>0nf z;d)K7mx+)rDoW8ADqg*!=Z9|3wQY!uu0j!{0gx(4I;8Nvc>Q4lo`)s^K?u%oJ&M`k z-O+BAm?M?2!Tt?`kbXz^jRYk084e1K9S8vgDZksZ}{Y7a@sfD0zs$S(#pft z=7n+ZpL^TjPq)0Ys6FNUqt3Z}TNN0)5#}t1xqM>p5VfYKG79kW`jPY~%KWA2pZBaw zPzfXh z;<{aMNN;K>mA9?Ix_?pO>gAaOH)C3~i|#m$%WZWG|0uM3PzxIPD4eFpV`ZFwXdcvs zB1ZfpjTF=0d)#6NYWS!G!TZ<`-Aj^8=K_F&YEoLtHrCgenafoh6XD$4G150R$|?a|xo4MwCrF-dSGHik`k)G{Wi{^|gnFONf=#u0dkrCQqfj}DH0 zLTT1#y?2{uO(oBY#h!<5ambjdWh;eOkKm{?1lpnPp6WDWDqi)j_fxB^&92gv*f25wd9bme>f-3LF;JLc<+n2 z3dG>UHdW2S8;Ro<;-LJ23N$tHwF8c#H_X%cRR~Kic)C}j8YC8q+S8B?H@QN787zQK{(6Ej*2^o1ZIAw z5mPf)$1wbtU$gdO&?HREt3u1^!3QL+W_2dN)?KVm5enLB@q56F!)f>p)iFkIj=GzS z!~L=)DJjPY;mN3ITDn#UG2XwM%H%K0M|z!&`m_?`;tq7-A$D;~Fyfo8W0N63sa1oQ zaoU&{sWk*ti|1{N;!eXy4%A^M*2HqB0m#{P$#OYy%{lUx&gJTL?H2>2a$a~a@~e|U zdt+iOC#_1__1_fj$oCvl2*Xip05uP9Qq}WNl9=5GK>n4 zZInDxGNic8G4aROSmrpwhVgfk?e@cCxMSntlz$I^o*Nh4)1_p0NcuP!smKP~4htt> zVX5_HD4&NinlFneDI%KSf`f$zf-$}3$y~#C4j(()Z_9(VBCPBCUNwROU26!$q6bEu zgG|GHQ}EiQ1UYWWs%5ai?5jFJIMbklj1Y{V;%=h5FaAmCH%e91Pu`AVSZJ5c%7%fB zrqTY}O7rJ0!X*a~(PFck;EI@&lK1#nm{?yEq^gWAXKN1N-62eGV3f_Lb4&Y0Za z(2`Y|>0w(^VYz{A;F~5&(TbKWtyTvwYO+1?b zkljF7&~J0~e3bKxNn}?`7a|2@?6*}|g&KIFXDoCdC%J&eFySKj*)O$M{2xpq@{ZJ8 zE52`dyo=bT_TT!U{{F&yyE_pgc2zkHjm~izXrU2Z>R26BUDj=BQ<(pYu5$_!CD^)j z+qP}n=4tb^ZQHhO+qP}nwr%&Ed*^?cn2C9;m#oUFjLIE5zqQsKoP01!RU-(b$t+MS zb)bFnq%eD=%F2jI@{Pi^n>c0nhX>}*&CbhXlqBBg;z19CsegAa!w6{8O5u4XD+?u` zeaLf`SSyN%Gk9w}hP!*|ggBRl-c&tN5K~^DAD8{=_MmNpN5-7nt$j|4w1f&h$f?ebfUT`R^_gd1x7 zSZ$sjImbXWX$bZ6fC&so8?V~<>z51NC8O$1hGD#|4%S0g&E+Pp$4^iGZ8w;LBoc2UJtIBWjY`j%6buf!raZ-9r0GU) zsA5x+ZY(|wf>!vb=FM;j??+4+e1kO*XTD%NnOz4?c* zWQ1LAE=2BXY!Zk`P;Se$JOM~xUlXV-$&7i=_a5C2u$X=C^|VwW7H``cRoV72C>3Vr zY5h}DzRAd}7*wDEQnB5U+~^X+rHNdM3}n|vE;TNM;UgjCwjiOU@5pkmvRb#ZNpzjr zhgq1_S`FpGd__{jOfve77Yr@I8F;*+Y&A`2hy5dLfw8VmnKzzo9CUZtjde#!J3wO8 z&SUr8w{H@hgZso(guP$^X~cqz-_$lXuQAe@U0DUL@ccp|-kPV9eei==>4syVt zbBZGOD4@XYJFNfwN)u;GIoVNx^jR*3Ft{@u15dFmdIN=^kIeLj9Bo1GeCPx)-X zi#r7I|G1U_&#(FI5VT2NkLvN#h9Mrns>`%<>!01~VZWG&A1)yyw2!66>$brNF7x0L zbkUwy)AXOHtM6aGM0h#;GGlwuXryV{F{=VH17_&47eY@Ka_97G1}!jlYD_;k#3TNy zQ=y0Rr(pJIEUBP954@O^pS8}P*vyT!B#r3&l|4p?meSq$*mAf2g5BcoT{} zT2L8&rm7fUo$@WU7=-#&#B?!M#m-$aHa}NV!ONPemOP2?Xvh{jQHnJ~FT3#i9O4n0`@3`a)Ufx=z9HS2WETNCG4NInv4vMx7<5GRQ_LOGdLpH3dYe)utKnDjG zz1vW#CFtRgeWGvFI-p6{YAy_Dvi(DBIC9$2w{7Ef{EM-Er`kIEBmXY%9>G)z5RWZ6-!N@0d-$Po|`X&UFl-Fg>;?O1}qIq04i`5jWVR_6U-&LVh^{HFWihD)0 z7QbtVlZ(GbBko#V{edyGtz%Bf)>$4NKI%l;a=;eX^$1ZdM}i{jl#~ha74Nc3O>9#Y z#r+#*{U&a_HNs(vvJ=e3_J5bcIf<>VqL-Pn4Ma$z(|j|X%L(`GH=fhONj~GIPHeMN z*zTr?2cF1-$E)wD^82qGgP&Zq4Y@Hwl%8 z0A2hYuYxMXHn3d1C-9P|q@WX;;7iQFgV`{L&%hGd7!-l0aFlw9+kRzfM@4e2U6CM6 zl3*&wOBrhk;Jxc6*{3sfrBl#v5JSh56GBxBgj(PNFATe@m|hFa2C2u`w1ha4nnW#Y ztS4>o`E~D%@5W)=^Np?SH`$qAkdH6Avm|Ft67Mv^ny`v)P)16D_*gW8lhxq@%&iK` zu6XCd1D?k=G$LvM@k)Eg{u5QL1Hk9#VU_nzCt&QrRwSQsU_Kw-DY@A>J&#gkE(LR& z7E~~W({>2G&h{ zbSTpsuHrx(%gu+ZO~!~1E}Gq*x7&U?BgNMw`Waxkp}ac}SsrdHXT2;2%?gKWuoc0# zN0PY-GHw;#o&#}NH=5HGcU3TWS%qxRZ;sN zHsIG?r1RGeL{M-qr*4f+Bi%j-X$ZEe1}nSoE+_~5l@2;*FEI{IK5wdxQ-c?DJXaf` zE5!xjUFhMjRkXL_@GnZKZ_iC%t_Ol663umFC?TKy+Vv*fbe}5=JOda5kWCxAG^M{# z?H|~ZBbKAXNZOm_+Bfa(bwUPH*$xgSG=>oIwH7U9v%@po@z!GD{7fv}V!jYdv8@v` z2Ng5y5(SC;9D*iur(KBPGm2kY=y~pWI2F6KVsWO~r*1)!%?Pl@pqr-K)ELu0jGS|( zlOi!1UV3cp*$eS47m|%Hme$6{*;SZW{U^(T3RU=qwiY)d)6w3xuO#Xr;m~S84*?#@ zZHPcBKFHxVs~8<=<(fid<;VP9l2zDzawqB4|jpr@`uQg@7>Yd=}EOCTbXt=GQ1vC19#;; z44b!W8~Ef9UV8VOnH@K2i41L-e3mvlsMVR;&2=7O;$06hloYE* zR|L0`dE!Y(EytR|ec!c>7Q-9E7c4rK)8Qi&ATZc2N1&+>4&8gE87{Y7r?o!*_DE4|Q~?6l;(MdMhk^q8mRN7DXZu=mBuYD?-9{a&Tf zSJyo00Ak%@iv~2HL>lc_{63^!^I;rte zWqr`@BW2z@&WQ=@?V#Jv|D5U*ssY(v%3;ss;9BkMC;eFSrWib@*E|dL!>6OaFx+_C zI(WiBg&mM^yCYb$3gd3LG80oQ3BN7lDXOzOIa(tZN)Ji;nz{gCBKuEFo z!MVuJcft+6nrotGj|E~%%B=nXL{xzMP#u_7C_~s-2XPfqRachse$?&4!t=&=32%%8Y(LZF~uY zaQ0I-BMf&?nkh5FxaNf5-HC=HbJzx1Gd`wZXoCvtCfD^J2j0AW4(Z$TJXGfm@lQb{ zv^DXC&;}Lqc=STgGIS_K=Z2YH1e|F!1dFHC2_<(v|8oWV?CSj4KE3;wD5M6OCL|61 z;SDZq?@KpLe)`cEuq!N6drPg?l_`%F_M69;niDmuY38`8+2V@#N+mpsJjMin#~_?7 zRXX|rJP?8)D zN`6^B$i@lVGD4{2pJq@{K(4@}nUorG!pc`8sU}XAE8!7)H3>UGf>Q=hO`#u{Un%_I zRGyAd+1iALb!mrundWUbIH!=fw$Wfx(CyverQ5T!lUuUtVE_>e;5xSbSFB<%Z+u-A z;mb?^Wtx#=Fk3Nwa~lPt>-67l)eGoddrMNA>a5%SYb)x>YYo)}@Q zG^+>si<$+DEM0)zGBETT8Xl)H&L2)T7QJ5f>~H*#8T7t(ex-c5GYJm;!c@81`c|-H z>1qpb?nlS0ctFF_pQ$T>>8OXuh`mi}61^T_5~b`~3?=47XBB3~EWU6iS;M92jo!Ru z@KVkuCUBOi(6F;7Rq0o@tn$KUq=*z7$(*~%I6k}pwIWt$0d#PvVqQ+SG+32I5w5hD znKz}$56TpKN?t+w#~)t~9r>c6vCELCJGw6H|$SObQ7EK6p}|=`8H#x22@lb)HF0N zA;gjDk00NJ8P@(j#%T=R)OSY19C9y! zF>Xme2ID&rrY-PgCM#2^dQ$nz^!YTLDURApkCy7v0{QtprjwK|4tq;0^{weu39P=% z!)KEz<2VgBztuINjN3U_{LoR!!@tm3^V3n>=pkOaj^b9# z+}N0ruo;4-1(U7IW#U`SA@dOYgZs@`dGZ}6)tDNWk85{v$F!D`B7v%Y@Sz0Tm9N@6 ztIeGfbVg_6^h39LXYer856>6UbN4Y8t{^w5iF;+mCeDb=r$@_+i-mc& zz3C<+DYS2MVdhP)iqIyoLwB}TR@$2;NyQ>Qf+y2)&O0T( z48=EdS_A$Z*0zq`!3DZu#tZ>D**GUuMFG$CM%lXN{0FX^Igqxwwz}io!uWQtv@g}1 zwuGdi}F%O?j|FHf9X0?7>*%%LW{q=4XlPmQA&YZ1dGT1ZW5{fR4s?FGH zw{25)3sAa~VbmK&hnFnEb+N07kK$=PaRJOrAXElauyU)4BoFw)CM>MJ{U<3@=&wJ9 zB$GQz$8%>anMX-W7qrj%-Fl>`DxTdM)ZhwHy&b!>uk->0Z&>G}#=GCAzn?F5yI>!E zBax!crosAxD)X?*12Ya_jU5ZDT_db5a35|UxX%~wN1cUT{2}+YL&QjP^>B29Z8Xd* z@UaXrsDXA-$Wx3_WJ;^5H3cNDeBrAHA-oUg#SZh4s5jhmq{OFsI9X$yL)R2#aK~6r zuz|^asTegun)nHc4_|L)+dTltov zGqS6VpJ*ek9OAk24p!UW!{2$tlghXL#14^yf~coPso&j2p%EEIr8&m2o#6jQxk3d$ z%H&-Ve%m@3e5c4-AUM*G(dJKob^nq}9jAnYZM0XCM8eORi&3DE3zkH)rZ4wx%R*$A zT?QznA&)n3Qgwr)@RV)tgf~YO4WPscIT=C%Vu}Y*>=T3L>mBzG>@Y_}v&Tj1k#TEev_DK0t*VslI9JMCTmEl0a>2SPrCQa%tPZx&R8D3M^b0tZP) z;wkUhz#FN>GbQ-CTouzY_2|RvG(gL^cPKv;YB-&SB=hjMk{-V$4nNhn{h(`Fx_RHe zuIwj-&$g_v{vree{7a~nCtKUm&p=R$Wn&|s9p}iQkSmKm?+*n|NNx0L@ANJh?v7yk z;frcbI1YCL7&=8>i^MtOE^EEJ9w)OuK9{G6-B$|q>6z%YWM5ygD|NSZN5WI&G3rNF z<%$2H94F+s85D(`*UF`ut2CIt$mm!xwYt;QPX!iwiyX0D5w#HYTkf>4?nLhd*0v&~ zCzsfvVGiG!Il38*(b0cJSd<+QXJ)F0KAh=5*lF#1$LY~RxcHHDyt(t<3-MNeY{Ne= z;|<^=@+@^T?NGTr6K&9)s68>ABoQrn-FB9TW8t zf?2gW>^>>2d--u8!*0}OeF%p^Eo4TJL##Pn|lLXgu&<2^EdFPVi)T* z*`lxVOL&3jd#vmFUP|1J|Dtkc`&grXDOF|3G8fI^5j}ZPcVyOU!|=2_6EA8y!*cT5 z>M1!1&!HugyGs(ss92sdc;;ak=l}~5Yu3ZQ$gU9!_Dm-;t%AbERok6$nwyF5$QtV} z{OC>)DPlK)!mHspJ&j8hrQmH-L{4jbTz_p^vCIdb?7Ne49-C&EqdUG^v?yaV=CG%U?q z&+uI1tGcpeE=~*={2Cv5tK7=mqI$+e_|W9a7)%99Jj*#B`E4O!`vS8FS-e;C&D_Zs zgzKHK2=!63wMZS{x>U!*s0Z20y_pAT*Uj_Wb}Vgb120}i4ISC zv)2US10jhZi&ZA6WuMXEvVdDvFz-5hgB_*PPn?S^*^A-2vzbn2-{=#q&9zT35fkIF z8#;=#d0z#Qb#Wjh*+W)Gv)_G@nB5qROpdJ_pDe^vkq^~w^U!Yn^teVTAh*_Pm7ONn z)zu$&*+jvTiD9U~NzJgJkcdF=xMn;J`p{g4Ud83LgfJ`s;vcMb^M2Vl&LHxU9^awB ze04Lzq(Xh{+H75a>oF93WZ&PH7e2CEcNVb9_ ziN&uiW7V#zmJ6FTqN$+o`x!} zYmtaglm{cM@jRkC9Kx$@~(sCZK|3-2r`v#3`@^dkG`p4futR}&C!`a=ya)o|N5W- zhbk8ZFTwzm9fL3lK(9ia&nttO22b0?DjJ_}(!WA=x6aV({q{AKrS{F<(I&sDPH%(* zeWmYypznWQF9nclm=Tj0HL^=fOu{!-H4kQtwowsoNlt#K;krFVh0zOYetK+Zxha{yS~U2g0&H|yRR43>M0v7>^R zhRSe&l<>vbd^Vy)LFzrH$Trm<2<8Pug;kbwLUWRmneuzLI8oQv$9kmD)2J~oLufCi z8ui3O%@cO$fSn#^3gxDiv4v22F#F8{0a1I-XhQ?oj{No|Ds(cyw(rwU^%HZgZ={d+ zkNWvo@RPtisz^OPiaHLpEV?B1a}JjT#EDgn8Uczv*2443C%=$SHnLN(jtYq zpPr&Mfo{k>nyp}%gNMzRuN;^Z>seo0fG`AYa%W`QBG>V!-Zr+4eZ_f;tktWR=U^}D z+1P;82D1UF0cAR8RLCl{+!%$0?a<7nd(AX3@yPW8u;aI`iBcsx$P*r-68(p#JH{d) z0--V@QJ|U9(y)hXUlvEbc?n@~{*CSDp>)&19 zw8<<1b#7BE0fih$W+2-+gq^wV$C2o)L&^cU4l4T>D^zp`$SR};5P}1AR~r{E1$o|9 z9K`0`y|!bKLZAc?ljwR1u?GZEXDrag$tJRvUD5mt?Q%oq>23qPNjp2kDn#7~}zVi;j;Gws#o%vTw-zNOmoK zQ0Va&(Q(Vq@D~6QFNsxMh&Ub}IpIGn9S=%938xhpo*#yEiVL81Y|vf*k)|@kfEsB~ zZX|TP%Np(Gn>-9g%8^}NI~t^kcqDY(`WJ9VZ*=_oivmL0XKF?*|3V@KU3n^%sZH0* zKOvwGvm|u){=pVFlg?D1N@KlK&kinmn`q67e?1=&e|*6UHTA7s$Dzlq>WuDRYve7I zR1f#J4!pn^W!odg5;N;zOOg88#g9{uq6yK*=@7 zjsy?MQEXDuO$GpCKl8H=jq8DZdmO0Q`+&(^X$bs)52Z~1NTCi8kbFu4jQ!Eif1J?& z6P)X2XlD9fQ0S{#_`jggbRioM0Vp#w+mpQU@7@kv4~3UR&l~GD*cxG-lqFr?z`_L5 zUf*PqtA%Cta3eMtdzaCPqB?29xT}Os=VKS_#-BoS%Her*9&fVuv4w-P=#r7OgfEgA zk~Q|dq->eXH$^m>f@2+xGm`_fk(}beTj%-4dLnhaj^|h4o*(qqR{1-_;cWtW#Ucc7 zw9wcHIHG+=M1kFRDb<9>Y@0-1db89ry7wKUVddb$QZRCE{F)VI^gN&kSodO!Dnamm z*I`hCB;3p4__KI--tGZu@GXDpsA7k4yF=hLlLlI>4r~p)sx9r%Q^NuZKzr?zV(2-4 zaf81aEi{kev;?jPe&>2*)oV>=Mt@tZRau+Z!TqNu#Wc95mK56`0SZ&*fu4@De{7E& zqPllu;k05XRJ&`ny~c^YX$q*cbh!=63R(-b7L%7ks=_ZIJr;QeWU671($W$*^Dv}I5zIqS(Uuhy{|&JOrCc<;4M!_>E3I4V zohw~a#Oj2qGz`o@kisiYLVkTa*K<4`T;Ty}?1JEU%3@3c0^Mu3g5 zGaS~(_wQqmU>pD(kOX%7a{R{~H#G?Wr1%SvfIAfr_y2asbuza$w=vaa`A4T2LIDH$ zFdF`M(TznSL;cG=VP+P2_!rlFhW+Na*(bkQTV+m;EjvjMY3S$za2T8E@VrwHf-O<0 zRzJ$x$~A+#x%=9tNa`{Eryw(al5C6x7T70bo@g*9FnxbWLTw5D;r)`sadCgh8{!0? z(Qry6iP(TY@xxcE8^-aOIZmgVD}6F|{^9xi*M8L-t7yk;a{eCV8{^$zj>QKrR_x%p z{`8Xcbq{hnk=fj^wCppdfi?=m@##F#Q%9Jdlb;_a8@8NkFleT#JrZW0P`%OA+o|k` zWu6`)dhq>jv)LyQMO45qtz5xCu=$U@-?)SuBD#a~?t~p-JCS(|wvB>!} z%sD7Q^l{)Gr4-G}?X}3PmFqer=vEiZ z+LV^xVk>8#&BaH&v7?{yNf3JE4U$iL7AwaVI1te$&!pv|>922YgZq zjWd+T3Axf5BOH9cozFX&c{_t?LA1<*je7I1EnS-~CZS9{WU-;kje3QXoEYvUhw!v7 zFakf}$FyJ*`M)!B*IS;&F2ILh$zSGq>k8!>u=1@`IFw~cZSsV%D0N>IG0k(K@eIn| zr8uoMY^^4eAjh+uxAXF*f_Y#M->K@_Zs(t)(7dzKX#SHf_(QRGGW$# z35C{Ckcx$#R?6`L`oB8jQi-R8#^GCozR&THw}dpfh2a_nb#2b|S;4()w3Jal>4wUa zTwv{8SYX@#J%EXG7Y8uA?9Z65Inb=URz_Y^=-h;F)9ukkfWI3&J&*e9@c6XV!kfE0Fm(M5NA060anjZ;hR-a1 z6C4w!;#L@~;Eil1^|*KLQO>Eg<9mQC8D;X!499*yp??1EmR*6MtH2;3TQF8da{GucY=|WFLb67UDi?VA8r^|95WD|Jjhy%24M6YI`_(zu9 z#o^4*JS8Ue&5=CpdjjH(-Kw3P7VsUWUCOYa$tol{6{D9caD;;&Q?l;9^mdgBaHag= zMLCE9PrOrOtIKnZAW^;C?k{>BmbzYz=3&S4BuRVU@fQ!;HICm3P>m$O^Mcntb#_Nb z3n~XX$Hy|fV5b&>;wkr(!9!T;e^cgd*N-&K-^xDw+8;E@NhQh-assu0Zp5k~9m3V=TlxVXHI#MPn5(dmJvfNp2 zWO29?HtsD?5d{rA=#+U1pMjL+uYP?1U3=;cGdPkeK@GNK%u%7iYc*gpNuunUBlvb9 z_II3b=s&)*{Qja(uWDZa$(QNa)6xPhdZ_rUEj0VI$HtS3 z@?Fx4neI}ywp|V0Azu{wPT%H@S>6IR@c$GbJOLi^in8<|;hqjjMe%Ymv8GlXMpCUK z{T`-;>9QL{6$y`xPxm-@(@?jO!_%`)!F^LNqU^NKE(S$WkpT_HmB~Bzo-gM`SI|x_ z_mKO>pfOQgNqbjTiVOOrvV})|@c7!nPcukaul9FxvA^Fw1FMuIRrWbHX)Ptqc{9!6nUb5$_~UJuVbPdurqy5i=vT4PI_I zA?{}UjSnQ5l^+)0;q=XvTq5?vfX=?A1R^n}rC6wwE^H@sJfh>(+g9A0hw|?dDLWDc zUc#8$onltdlWJt-j}rQf$~O+v#6D9JIxb%b?_6>SQ9SEe7xR4PaW_e)*6Hg zpe4XVA6%a^)|hKua|ShZlR%XqGy-iHo&n&&_0j*-9z*_$a10H{a=_4SdpSqu0 zAFSUh6GA#@I(U@dI$kG%&=|B4cshVPu-2TAaCafWeH>0FW}Cx|rdmh)GYo^>vv)Uk zsM9EXU{Ldghrxw1o#rA#uO$2GCFmbR5B-`b$AmuPt4UeH4?LMfPLLE`!X`i>{|$LG zc_Ip6rOy79t2Blo#fJg^Nyb`rDBh(q?KKl$_Lh?Fi)ng3}6(=?Y+)_$WLj}|WXE=KE0Wt7dGUyRZ)b*h+c%gqhv zvzLxYH|dws-5H)<%Ks)-P7s!F%UUB|n3yB#hKLPWG@ma>7_3$v`JwWNLI0xm;n zQQbAXC@bQ^yjnsE<>C6^;7=maTB2;xw)LaY=MVr62$BMY-ycep%vNI;TiN$+pj9k2 z2Gc4Jh$o_nw-R3n2B3a`)7$kxMi7Zpob#;1tG%7-c(2OGr!#a}c#p4x5xlB_{zx>N zyeH_%AKxQ#(gV~Rc)bn=!xaGyR|k3!?^8-TB00hxNE3#R>7zc}Ld zE}z>000t$!AZ9Ldow|S1TLOP^`|?6D(+3U%`vhO5dUqBwIJ;N|UPEaB`mu>d5V}V$ z&jD}taY%ThPnXWsg?G_v&qRj*4D{&bOtvX(pHp;#KzG5=<=`Wa)>?`quFvEsnL`7x zd_0AQV?fXZmxafuIMKSpGSfhoF@wDVETUlLO{P(4_g$3c=k!*gTSX}^`24vmnFa?1 zQ9fX*2MqO6^XsJn+gtPjWH5a5&7)BM7dlqIsUS4Q1tRNd|I?3*^Q~?d1RsQAa6KG{ zq^(>HqzsyfdrwFe@R~?wQ&&s}UE4N{bLsC#4tvI}xXS7?v;E2D=g(N-b)mSYsF4Rs0T%4WtM-AJ2QInOhWF$>Guy;nAHtksa|Y%9!VG z$yrqkjTdcRdhH#Pr^vG*?2N(lzPgn;J!f%6n7zYue_$y>%J$}oEDK_L++Vm`&MO=$ zVFkAhISE6*7`cT8^PW@wAtIx`D%HAC_QSd&Bq2oNCw~RFT=Y%e1GM{M8s-^6 zxm-b!{>MNJkp&!Z!>I2&tm_L;#nC$_V=o~rDyv81S?ehbTGTRQJ_t*9AJJncfG^4?b3c|_U2_k4B0OT3T}e+GDOd$$lJK-CqJHC(x8ex$rZ8;w69NvYIP&X#4IEw0X%L^fAzexzYQYFX&L1lYprgaT5?ZL~WS)rNxs zdzmnzi2*cOocKC|FW1?79P9{3{t*rKorhQ3#72--0!TxEG;#o^27pbh2`C^fr#82H z8)fG+~c<{DH1-=!{h5KPyYpR&&;%myoJBuk?w3jNxc-qy~ z%&Q#{@vk385V_2s=S!j2jm)PNHLu8_inHegn|>!&BCg zy!vlMOixnE3e?iTbf*+hnnOo?2Z1I6CLZ8rWqPAPI1AK(SqWG}-H~c$=mIZst{neH z$Yvmg`C%thMjt50$l>|3{8aayQpf4lJuaUGV9;(pIgGeR{OUYE5T${~Q12`G_{0#>o z9E?*)XW@sRA7s+`%2>?5!)f^38p3WI#*CL2j-2AKUhPT^$eGTCYehi;N8(zP%OvoW zSJ_fgupInw$y0t8#fmq_+6djMc7kICnd!bnxfxuB3OleDr|HkeZyY|*)a{Aw-u1l! zDZb&xvs5ueTWR9Q#3Ky{(T$ec-Fm}M4a_G;&q9&om+2ZP)l&#(;dc}9!}_CoCAc z{{Sbnnu#-N<=jBEQL)-0Zpt^(hW5_2@o2hD4R|o8&;s^sYR)F5`t77KB_Xp6S(lh+q4RfOAh5{sRxi+_}T<5@7cMmw3 zMz^%}T`^ViJ)jkIgyHOQIdn}8Ow)Va|cQwZh{ZnVW$~>{7ig&OMHAz@#uh9Nb#K3u97A*xoEXZh0m+sP_WdH1wk=e2GL#si-HAkB zF4aZ2AHTTeC3*fvPxzgA?b2)D;Y3#$^MnbVqsK6uIr4-bnb$BKP5KDy-0}sGWC&*b zaPZ!1YJiS&YTcA+(syzek!Zv{59Sno8kWr7Yrep=%28rGXNJF;<#hSxcm8YX7P!59 z)8!S&=bQzP1fTvj_1D8unM3^7CuRRZGOgbOoLL)GhFm&m)7Lzuo}W=1uK|jcd;@}} zR-xRyGK&h4u{a#Vr396F!*3xYAdSbv>y?LfB6$m}<@=XEn*JSvYCB0zy1D!{^xN(7 z5qD=6lM+5GvjF7c`IyO!-MFa*;i@w!>;W0R5bW{5=8*!3}07UVE$ zwHO+C0`X4?js&xG0;~IO`-Adw6;OCUGv?0;*RVArcH#AuTbWt>ltO$G7f;a5B5@~v zI_fx=`1{WO+V9wsIfM6*`rCUF%hlf382@i+(+z(K%ME->TwLHkJ9#LkQEf^xODxyy zdsE-`rd$2Lw)YaHUYWA@3KfaFJz-82Ifb|@rJrq=RptlQH120*on*nvRQPy8uJ);F zi=%%9f9%^*ve5cV)3=t161E2PKEoOcM+4_?Mn>gMMW=bXMcCJYJBli&INgRU4R*4! zCeH@511Rc9j+-53YZq~o4{Zni9i{RBK2;pQwx!? z{yEN(xewCpuQ2qZ5{O~!LiIn7AmYKP7^F#|;L*=`l~q|Db0Sa7G70f!Oz=<5llEdk zZ9*nO+$)Q&GbOypGXAZJJUp(<&==kdMjgyO82v*^F=-G|WN=xFt>Zk}Af0>O*6OWA z97_@*`QpNp50SbE^!GpvsSlDK8Ib(vb1~HW_x=n~=-l*VVK>XV2@#sh7kGs&bmA878L)z&>|q70^sSpUM?ae0I>o;E-22%3K#o6;&_%>0J@2r4=I zQb9ubM#OheEqyJVI9(cV)t(y=W*nz4%zEkaU^|)wu3>-yVr>+u3q7(Z5@suPe9D2o2l}cye}Bejd1%HiegqJ00#B zZhbq)qAeFBwe&7Z%`|CrjV8VAFboqWr2Qj-Mm3Gm#~Z#XrZI?H@rh(!tvlw}Z7XsV z&YR@_+p{1M&)UA)uGc(3-q0sq0B>>4O^nMdElk#w8P@WbJ?zyf-mx4e3Ev1!yvV4G zO9N=A2=Hh$2k6Ex~{?#YD>3rt>%jM~K9ej}}$>J+Kg)8!IDb#rOjYQI(+s z#S*#}MTb^>o{Nz=#(Ut#Xrlg5Dn`E{y3KyF@eoH!szR&I%1lN1Fc?ZVt!D&$>s8OKfhTP?pGf{$cM}*YIhA!!K9R2F^P>&X>|=sQX|yU5 z&)0MCgBVVju!e@jED|yO;}c^3Pz7d;5D~&CytU1FMsOftJl6)azh1>7v(Q2t0m z*wmU{UUjHg471iTna_(^F%4sWpaV<26uhE!aja&-8g3!}Bx`_VWG5;nZ~G;-mQrCl zZgiKnD_+C6Gi89vCG|_&j)*7!S=Jrpr^L!f{6z*1C-yqCKdJ>^hjjW*Zvw-S5Z0XZzT#>#yA3DxiHLC1U5zgJFa4Z@N1JP}q9 zluYa-fy$~@T5e3oQsq-7eBV3Ax+Kr9ZCYj#HYwx|SE@oQ)A+JFx^yUG@m4Q*;}GX! zoN?Z)NKNrVeJ^U%UcF|k=$FA8KSQy}-Qu~-M#_F74L^;4h4-!ptYe7p<>E70)_QEt z3-*YeEh#4OFf3O7%-OACGvQoou*;$3uG`f*EsPD6gp%8&k)yL;I;Ecz(^HU@W+6Q@ z-bf}TKz8L%c78EC1AHp%@lU;uO9O`=x<|z{E3F^P1f|);zC=Nsiz|wL$rW>&(k7LX zRdr5tv>H%rs;OU%I7MP8%<|o6s3!L{%odD=es?q-x$A`k=aVkCv6!P7M$dhkW9u|p z!B(2$iscTUlGH91DvU@lS6UhuQ>1NWq7)Cc+vzJ~kNvQ_#xO`(-`HyBi|2^#iB<>? zlM!}Vzx5Y)lic6s95$;2y!RRePN`hj%&Y%LA&s4bJs|tW9vo=K-`9js>Q~?SGxZc* z#m@;d03P_>O8*4BjS2dvqv45n8yxKus_tXr$ZmU9-xEje4Kv$v-qLKFoKI zxl#EGy-*p*FJ)wF(N5kMa^UmYT4%C=IbK}1KR^j^M^ni9F%t@ zEUk+k`qux_wi@+X!OSVYqtZehJy^{!>;ptZK91QEFgz?@OY^8LP&tww^6YNm5n$++ zvvZV@Z754Pa4CL`eE9|FsUU+8U>1HslIBD}T!He5^g*S-yCIw|2A0H0Er= z{UyJHvA{-cC+{53}a7w{U!VwK(4Si0=C>}B$hP92f{X7CE zrF@cxBI-wDA~ehsTIpSkF9@^;PB%PG;m)P;He+dH=4kVk4-WXIASEJgn7zQ{GoA!d zmD(^!+y)FJIkleJGYPdpqGEo-3l|(IyGntLDyVfu4Q05*i!eg|cC4C+uKGk6` ze=MrmWcXL-7+U@dO82U}Q}cunbN(#PB+HF7UknWyG~L{d8gT3G%UQ!JLfU-)clusJ zVFk+@0g3fT+ENA%lDDsW+JPBI_)YCVa?~x9F`4;Im(c%98fFU45EvVG(2mMW$bhbb zjJ2B4jYdh$7oLSU=Of3%jlI2nRVvpB^O9`N*!^3m1LvU^Jf4Z-v}Q!170Pt!Pttroc8Oye8e zDO+S`u4q4zMlm}c9P8^wfyqoDf6H{)u4LwI!HAwW+SNj4EW08t-DwcFx7LT4w7_Ku zt|PzvN9DCQb_jjv%udVXY(cv(dvxZL*9w65m&5ml-a7~`N!d^>irLZpj753=O+Cn% zf>THT9H3BK+@kI``Z`eHy#S8qScxO{ttfp9)s+dSk1523~a|ingk$N0FeH z+f{>3OQ<~lWDLOH$uAoG3q=NLzQr~_^}bc(+o8Ywr@2?Vwm5-T)TaaC&!mGCUX0h# z!dE8C7G)ciHA~(dRwjI|R?eBY1$}B{X%xQ@8PN$B&3(%oK85FU?pGFA$y^j~?Cp%F zptcr=nsIfWm0AtQ6V=}gRc95k5-)>Fgd!9Ce<>^}iYiNx(hgZ;Z$Y(Pis$6^J?Z#u z+i#$4oIknr_0zB2$cEMsZWNh)!t$><`4!x`Hf-@Y-FDmZN4A{&_9dJ!5|Wq*AYGr* ztiskDpxrg^F;!<9$fI~}E6{?*RhYZ$D>fEWD3 z`S;w4b{=jA!|@rp2xOXrV$64K%3**7L~1XN!8nD5R^-us49amEe<*_}Ym zwMR;JL0hU1yQZ)(;x`=_uwx7zAo{juznH}XRQrl#kW{fQ2oD~l_G+~F zkGK*^5O!i?NpF>Q8`tay6XEtL&WJFXD*hK==hU7F7cAJ=wryK)Y$qMtwr$(CJGO1x zb~U-{L)J;&V-j%9^Q%PQ(RzMPV3)tzF(G4M z-4Q+|@eTNph@uEL9IIqi6Ce4}i|m}HqJyE~z`Bz#5FN`U8<12C0?!MZ(>){~C?^BltX!}l2Qd_OP*c?VZp=7HiqOkCi5R+YBhu?MaW)lmE2skB&NR)YU$kd zewj0oh3VijWgSVe6GEdg1p^XccGuap#%HVswQyKa^US4~Gjz|I*aP2&!=&=IrWF!3 zWJCbRZ%l?U5qN@tM4(3zwL!_~+#@CHzZf3ut5Ywgm=kg{7uLzhRjcfAR`l7gb6>) zq%N6dK^xyMhKpgAj&vfoqWLBJIfk=Fm|8$We3N&$xlQ7kT{AQ_BrFQo8_SM4t};%4 zAQ;yA&H@)Kq3sny*)Vm=s+NTjDpq@Rpigf7h8QQi`>zj=0u7B7zV8La>p)62&4`M7 zPe4JzaW)SRO^B6Y!AUsSDt%RSdqH7CObmk>V|+1SThPac`{#T*R4#qw~V;)__2DQ2+U3d**S z=zx?-$U6h??2T31Jj%n#6IyBqw7X<{q4n~CbYDwSKB4nA(xTg?ZrXKZXNM5m)aZ@1 z1pJ#Khq~(6HPamh^+A2`t8~@Z=`yZx0*cHtlvh7^eqyfCkPZwxW^_oWCiu^Th6v9r z0|uHa02lL+;6UYKgic3E;5~y_rf`A?bT&r^_E5ktP{I1P5P<;sEO984(g{!zNn1RuBFH$inCOr7#$DaV zW3WElVd7PbY@bQ;DLb@XUhHmAN!U*&s57a7gZUxyV3NHgs8B9jTaXL*SGXX6b|%IvQmK?*kR768qK6({ zy&jmxbVU&Y+tvO}2<^7;;C`oD&wf7vxjVi5$=|(Jx9$-glW>3@a37wXN&7t|P7T^+ zA??|uAzLmQ(^dG^o)ZX6yNAt7OdDH|%iMDa=AP21wn1B1>q;#NpE}dVp?u!}oGn_+ zKHB|N)s_`jy`LTV0HV2+Yr$=*QzP|WFGS*D18a?`6 zu$I4drNNf}U{;!vMM_O$<9W3b?D#q@)|Oq0w{?vSZ37PGH>M==PpKsc{iYDmb1YFm zU$LZMoyj5^EwpkeacFv03-N~DYKa)_H8_bjKs`JRl3*Q4rK4gQq15#e(axD&wJfS? z=D6`8-`ZpSa%d*TG^+lAqZfyUOfQHf&qRC5OKmizwyY|a_G>Urc=_2kn{vi1l1^P| zlit);?AmJSHC1U(2FEia@aSEG@~4Q}`Rc7WbMai~Pp(WZJ*~IgrT&S+g5jn*m1f9h zxpXxhQ*T=B$=i-TjdK00J$qxr#qnmR&xdo4o^KylTT3$u8=~RN7$unc!{{gBmScdI zL)dN?S|x)O*X)oG0|To@IK%L5yPmby8@P!0Q`q#QqiUb4-FiD`Sy#3E6!qFvso9mk zft=(}I)2`krag5|YL2o#2E*J=X(3BD&Z`X{00WB>_26J2jq1)%IRz!nWNZK~59^;a~Z1EJ+ zDq#&*qcV12BwLGgCOm(`l!e=3Mvc>Ld~$(ouR`xuhhf;d9&|D4gNuqrWq9Z&$xoO< z7(C@nPaOr@^JDt+^_7g#n8p~ho_uIu;c;x8Q<8qUaVR|IcT3q~1ut?`hAy12n!1WxDo(&oziy37VpnU%{YDtwPxtbExLPexB!m^^w>R#yxBYjBI!kA1GC&jV! zy(PI?j?3`)!~foq>icSVMZPvyg43U1JSg)B5#Q(}=f{tl!_|H~<;d3EPkxjkBSN@R zU`;i=W4i%7z2J7=~i8T(Nz^fc2jqG5CFp}>R**o_xy>-n&E-u4Ch;`m6^Of{c z<Iy$-2H_|{&(!F$vradgvi(oh89eXEwXnbsE-YfTg zkRW?P0H(H^2@w{^2AlkEWOytO%SCv)xr6#{0w|vn4cB0IntAts!#U{}O&!aOaq&?b zU#eUW8IeVC|2D-&!F;%LpkD&XJoGzOg2vOnMtYw?D@?cj8&#(95UltRNhnqcbT}+^ zqb(tgW+t<)=hk3K`7)8RR&X&!-sxg80&^>_P95+U+S=*4Nma>P@{c*(UVUi9{jLiN z=fY5JJ@HXEY;#zA(QK*;y&;0EM698Rl0ha9wBwOT5u&1T`p2QFy&=g&uq7~MOTt6d z=tjXK|rYtpcT;!Tgcten?I*ITJ-p)K<=4a=TGYzu)7-Hr^;b%z?Oq=s+s#xPvf z@6aR2dbioWgkxEODqT*Qe}XCmPaMa%5Snfi&yhbNe2scqHY)VKZ975nusvXAO)ucA z`_bDacj;th?OM)t5MwYm9*O_XT)ga+qe>0g-b12*Ft&kUg3g`#nY?sZp*H1wsg9p8 z3L=tchla1XJi+@LuGxmbYFldZOjvhQmgjoz#s{Qh9gRlpCX#grtqL=0rqH_UdOmq; zjZL=*AM{&<@eD*&KA8Nire?CVFu#8>-=$jpT^3rmsZv>NChnI7NS8poiwfnFWgE@1 zZNlQUwZA75wpZj42gL25k~Ag>f6I&o5z$ z*OU(dGwEs%|K%hfkw9SUJwQZXOqIX>|2c`pKVrG`_3kM=X9;-9=mm_)^&hdU!0x8s z1L}i!U7)yv!@&@~#Gxse#>v5KjUKj*VNom$UmG-==*^*IGyn`{=8Kdda{7P(Ufdnl=A)^HRLgHYsN3|JxRx`zHx!}WGYIAN z5IJ+%{YTYN%zxOb58Mf+(RPgKdc-c6P}|`3X0OZEgW^Ml9kgXT z(6eM+^hSN%JYm;({zgVkct7KC0!G&~v#L^71pDn&BRo2wR$=^?W|hufhelm=7j_h- zSw&Mt8ae<&*$#gy1NE*^@*AP?f(Uq4&7h%PtxV%{as?LkAZX3*z>v;xP` zFM{lvKQ@~uLwm5{gH`_4ptbPcjGMb}1QYqVGkggA4;BH&4Y}AM7&Y7PSG-k)Q|d8+ zZL5;ZyjNt?Z>;;)P0`{Sz2SyDLo;&Pm+=&l&r<=d_(`HFO0Y>OHvcgSO zbrMYLU2?tGU1n$ovla3_GTh+pnD$ly{=3j=#0-6R*EBlNXlGRCX#Dfn>JKono5_S?cIo6Y2nqWPU0 zI%XRnOyNzcKx{}Yn{@QqS($8n&I)nxiRQ;A#UK;gf++=GT^ZzehS;?EVW);AJgQhr zya!5_!?j9*fT;$`vVAM7>e#GJ7Q&rKELY}Fgr zjo++HI7&>S=%p%@ms6C&z!8po?8vjuSj93 zWnlgEiF5eiSo59)P{y7)(254eE}Gp^(RSh6(q-gqER|@$o{m0qfPL(yV=rEq^_6Qo zD;>avlvVUl%8v#hiLe*}n^hx3N|Kb!{eM=Cf1jk?r%E

HMO9D|9ZmEAsF)cUBTw zI8&>u8H57p;g1u7{akD$Ye4d=esehKSR0!7Q1c@{>a~o^lCB$XObq5%>!iU}cR1)g znSKB#030YErv&6%%QfF!Z8gVna9Vz|NfIJTjA!8%Uv-;P{a)EA3U=+{eY1H9BDl(3 z{75+ar^juAyx&%q0=s};20%yHO! z=>W`5bmyT6AL)p%NHil&K=t$U{Cha_x`4p8Yru)ni7`t5J)C&|m(LsrQ#%(+SKI&n z%_;ahF`W31%o|6~!WV=P5n&ZoKy%msG2$E;>WS$hZ@kVTCy{QkJjRfc%US6^7h`K; z#KWSxv$#%)YL;%z(e}Q%f?=UeKo^7oiHE3txMexyVBsKjstYQj5WPnMN*qmMKTLk5 zI#9Amd|8BC60XeQ3P-Eh)e(LitCmHlP zYx>)L+r7m$ya_GbKjh*2EWkM5F1->#TeiY6`0ot{!3}<*UnjhGsRJneDcwL~qB-TR zuzg3av(XBOus}UvjfXP!(S13DO`z>$<0c35pHAi|3f}?tzmGGQGRET?ds%y){HcUKsU*oe+VcATGG&rLjM@eFrB6 zko-GvkUD+(3VCc9WDO@U^HLu-V23X@QUb-7@1HBwE+FzKdxAe+^-p3ceH%L%65W(0 z;M+Z!#gj{vm(i!q7;<33LIDUqzG7+&;Zs#rv`cFObDVK=n(7Rv7NQtBg9GsxbbN)< zgF|~^KhBLOxq*}zdJF85>OnCU^O)jHNCVz{x7Df-2d@3nw?&R!z+*@_gT~r#tNRTT z?kg$+Hw1dHX=2QUzI_(uDljT>G-okW`-VBR`}$d+j;DP@xPyysR_@e(dLGR*uZP|6g&${88uPZi+bM za=2#k&oPXB*k*Z-{kNn$l9HpzceLQY_qM%&hOJt<4i?iFGYmY>ccJ#@pnCL4M&s%- zM-xVahbL1=?U(R=e7wE<^qoyqSpiM!xJTGhq~SXJfJybYH?gqLPl zC#xaskMR0pg?K&4XKkOID74BElGG^X;I3uv2(Qv6uvC3)NL~NAhdH>xmYf)Dgui!i z)wM@;^P@t1*veL#hmEY;{6oIp73L!K*K31Z1fSV0VeLpSOl$Zg@Q*<5GBMtkk0&SO zEOR$SI-R51x5;rL`$LIDaSG?CZZLbbwnsOl?M>U1Q%jMM0<>bn&3kX(f9500fzfDBEh`55~&Bq!)0pvhTN$hBs}SgUqY6HPOhc5aG2p^cwy+x8?Dw zSLrp2l$2>S*7k~s{2@;4p_pQjW7AGBI>r)Zu^>i2e)NJMp)5)`kWk69T0IkkwmL$0 zd@bX4N1^4yI*F#ayq{lhU1cV%@Tya*?j7d5qUS0k`@}0IMQbp1(`}KpxX`OwG3l1q z+BASM@|}%4;o!D&wR245H%r_oq*lCwEHJ{nhgQRT-RSubY| zGot5YaMfa%)Hk&-dwFdOS6dQ$W%S!8Es3}$Ica=MZ@Q=JEK_d)V&@-C89*NC_W1xR z_J~}MGW>w+jHXV^9WSULgNmY)k#yU)y8h|jfTJZDZb4=RO8)Hql}5b?-h~9#03?Gt z?{X!`8+Jx&K;8;)=bNdF3@$2#6B>e5fC_qiMZ%04P_A9NVsRIh#}ET_C>)t7SI8 z7x#=vXz?1KcXz5;A0w?eV1$^8J%vBnLj0adCR|wMfJ6|7L-(SeW@~@5W6prqvzXyM z{&7?$Sg5y(*?}P&?D*{Zn9~1CUNL0gnc{O(!x9`nBQdSw??@e}k5O<{wC&4;#xBqf znH?mx8X=-FwJ52^T!1P~LAg>Lz(63Nk@QsLbutHbKBCy*c5;DX?iNILj9M~Z*{1WR zIK3UltlDGCzq&$pUyk1^(_x6GV}p$&y_2pS--SYPn8SE19I#?16KOYQTvJ`KksYGX zPRPoDIX?m$Q01&{E8UF;GUDCrwcVe#t+Heh-;>9#MYv$RyN8SfOQjJWI-wfV%>WXA zQI_3OuV?cSlF_+NdOCXPrEdl5=QyJp4PE7GSf9drmofEDQwLYO+U;d2E>*cKB^R6F z1L?7zXzgnLew&3&ckZche1Gm+I65HzpabwH4M-OiLxh30kK0nUX5Z^K<~N@?ec|)Jf=9 zBDE7cpBt_yewB}G@x_C{%E0w+fX){R{5(&GsEGW2L><w6__#Gx z@Rm5l`goLKQT@p_fyV_!iMyh8&?OV+G{Y}i?ASbFRl_w7yY54SGj`9~0w&4$zm;|J zJ(kysCJkht+gjc5C5$J7!`F?4uQTj^7;b-9`v0Q!eGvWaqJ*zPZ>mLHcU!vBhC!}T z$6BijjAN+WW^YkLH?_kqXSA&zf+wb)a7^%leHI;Az?qwE0wPD>WiMk9mvT(-n?tvH zrnULQ?>79C<&s^`w||W8v;vymCgz{kR06CzW$brL@%(O-bn__Iz~HnCUEn&d(2mms zvb@dhX@D6?Vla^6ZbaKS>@X%}_O~V$S2DB$+ zo!(PR<))Hdbn;UF@cC#r?bh7&lWBpj)9>qOx?RDz#2p+G%d4oAXULHN`Dcw%I_Zlw zBf7F&s*PDmZYnq}P<2{!4UL;dW&&J4d%1^`p-~IGPfsO138wfFezNcFhb8=H%V!cl z7_5^YnMc#$SVY=0X%eZ#Bdeql9Qo!;^Q4uI+UhO->@D8nE$&ihj8Ay0fEla6KVQ$7 z$F6TRJ7ezK@-0^2<1%B(c#&`TQ^Fbhv^X>l)aBE3B3 zpRlIam$1gKf$g2DEP`aYA7iUqNNhxXoJam~b;+OK*UVerFS=urJ{_{rh#`wCOwo&B zxc(woD;zF{xQUQp^w=W$P2h*pTt|PV^tp9Pn#;ON#rAdzhM`F#oK)~ew4Vbm{N4%< zyr>l(B~ndzQrDirE^z}_yj7QACH_dE;smE7RZ#Ul>(up2rQYAV32pjlsh?rvVQH)$ z*rT=*RA2TGr%Bd`8Sv*Lnbm4j$25;M2HTpYl~k1eFpW+I2g}wy%NeCZzBR1Mm^WGR zGQcf9xOjwFw8$lm4{adjW|;&V<5yTng9u#uf*yV^lrLKPhG@RtR9jY$J-kjnuJu}$ zbu~P$aqwsD*7an6%$1E$mNn0yUyS?m^X6Z7vgG)D~-(D}<@~LCol*s&6Zu9&>F~8di`5MY{>VQ2w_sDJsp6HKt6d)4v zaukZ_%XR=PeCV0)RLg`8?N2T_BQ6P_dPua?A%u%6WbP{>k9fm=)B?T=V)yG*3RqH; zR#f0xId!r$`gAelvk_1ZMqj(w=^a%j!iAQu6mHJj_6e~wG|$14qM zxxA}FN~o2~+h`+O;f(ehw=Zb882xYfUW}l#n8NGi?&1!fSYeAAwP0|ebYIRpVkEBC zh`~JQti=yXvJK_fjyIK~Mzn8gOv1IxCfr1+4vIekck0TDo(OGk3}y*%4Tjmv?&L7T z967kW1p-mQ1Z^6J3NrMIZ7ijHI`^%lr0o`)tiGtyI7RhcqT~0Lc0=$3+rT3eTYo(U zg6bA(TVeNuUzs8O;z!Vtp~dugoDE?;T+txhhm)To{wyouy3f1R4j92oW=xzWw}JX4 z&iqc=e9y;BNX0AFr)^EDTlp9ZPr@qvtkfNrZQxEl>8uwVj z0cP36-rBrVw-EW&x?kvEy^hmbJ;4qGs&9uCDY^MzjNGX4IFGb)NV2ymm2pM>9W-Ns zVBF08s-Xv$^6i7hy+OfIt9ppjBEzzfZx;IxmeUlLMidyG9qd(u8humRYFJc;Ho?M{eZ zV3l_*JJaKZs%%oZrrT~K#ZQUC_>v>rpcJMX%CW*DN(`eZWo-;?iIbZz2onF5VK4P8 zUQU;b)<5VF;R~ywW?5lQ_N))ku22xx8Da!=bYF)R=qh=cInoO?RJg+?M?eobRSzt< z-MuN3O1DE6C&+kck*6<$rJ0?V-4Z@g1M^!6NUq6x8G| zJ~^;tGLlkB^utx9jif1IQtk|>gKVqB#1HO39R9b5Gp2~&l0j9R=u%Sf{XHn*3#11YloHjy6^oayc%xsl23poBG zOzwrEukj$unIi(q?~|4ceVKWCt&=SLgS&fKCl^hnuj$jgwn`fTU*g~b3Dy_4r^1iC zKbBn$@DSLCzSsSW1LX%xZOV;bGwZzZB*0wd-ubS4S94qLyz2qwJxQ-X|-k#7GTza&6Mnx^)jt_dekI{%$;$`2H2&wY*p zPpSy+zrGu2{}P?LWRWa!3Il&ONh(f8BTGvyl;h)N2G(SL1_|$5N}&X3w>ot1mUf!E z&5YNQ1I&5vfb8h^42gihC%YaDXYrTsc?0|Sh<$aDT$A8xUO)-_`A6vlV2BmBUH%l> zKR$y!#SBxqZTo}45BIW>Zwvoa*krRoNmWQo3r8i~5wGli9iFec-dY7(X0=s@< zea6BH3W1mE@ZRU5O3X8ZjRJw@gb>+)a?Mmu#+FTb2ZS^bxjVl-jK4b(P~$T6ec59d z;A}c+a^E|geKK5JM2vQ$EntC+=6rgkzYcQ2hYuc{O)J_g}uK{u|z{cS84x z+pL8;PJJ<{UON(YA?tvEHcZ%(119zT#u1Wek8Qv>sbC}~vIX3<10gV7v@>mk+%V=i z=rX5ppO2k!En-5u$i4l{U|2t!#a3RJD%X{Ms)+oVe4YZuO^PmqT25f#h#Cc{L5#75 zkL00gAz#u`u9VH@L>WRbC$iDz=nkzD1xz)&QU+(xeRr!d4UY;=>2KQ_qMIofZ|Kv* z0_5kD(aVP~y<#=MX2e4$>)JdkT{#PzTzR<{Y?vv8YdNf_9GHX8XrN>X=1~m*?r3e( z4dCCh8+4El^}*>P1M(4*~^}9$kkx?avK< zn*>E{M7YnAbB3UV+pjydS^h+{UqK9fe_?~Yb_c;9h5DxuJJka-gIC;hzCn@*7`)={ z3T&th1W45X$q3;}Ks|n@K{+#=Ql$a|hxFKT##C7_OdL^s4eYcGhMTce5L{5+g!7MR zO`$hgs?l-`);mi)WGy9~SG4hRG_Z)2(TmH$rSl@8*rNlX9-L{v26hJF%g)M1wwCg* zvw8!rNTFEnvtz;UDWTPur>L&JL|5)}igZ5ucj(M9y?7t~l-H@q!SqA?osHN*2(P@L z)VNw2)jSTHa7pCvkG7ungMr|qe?{F7l-#8@!-0bE1^3W@WHMK$OLAs1q4UU($&vIe z+H9Q3o}?ZiT(S8^|2Avt+z0UbH;i~AK$9_%00h4lpq%r-V@fNB0atiV&Z-^z&lq{} zZu7@^;STJhfh*mzk&ndgEP zdm*leP)Rd(TTx&l9__`^D(x=D$JXws&8gXx2RnP#8I=|F5m7u|MPx;!nbrk2uaD!En8So<(IWrA7rRh|L`JOmjJPN9kAt7zSJDw)BC3(>EBp zpb!Z`u4$(4*ba1rWx^8U(ZsQ`3hSeE-3RIU4=~WRWD&0|hUAm7hVGfQ>0!dN3uLhr z+#j(pE7}q~(|bEghfdSLB)7bGMuVU$mP~E#QsF8KK1Kx?eGZa)iv0sbiNH!A#Pz^I z?S(vUDEoFf|7~YyeEL3rPk3x8ne*h3=IPFsW^Q_TxA5xukK+Aa$@c@iLf!uHFnIO` z9cSF4G@o9Tk}-r{2d}$^79r5#v(~#?qE}XRXnI6e5fd-A#O+d%jFipN=@stvU*&ya zOh4w!x84uB6$jLUT`Fi4$&Q}sf4)}|))n!t#2?69$ivLDN%ONN$TKeP$@0lP!6l5) zcSPZuuPh*;4Z8st4>s4r&te%a#$XXC_p+X3RDXYk1e2k4Gx-wd*sy7wSqzWId1XW>gESN2%naudzDUvBxGUID;&<{i#KZ(%; z-6FC=c%ZGegQd}`*UrKmj za#xpLhLnVU*Ce@ItC~O%ns^vIt$mR8GSB8i7JX9{9lzlM+4+Y0q$RNniblMvz0TN! ze|xd~tp(a?aA8NnGkB-qw}6=$q!fc+NO=kvEaoSmtAf$F>F1c|u5WySXyYR2vUmM( zDBjT*S{w*mi^90y9r^)>Tqk@&G&+Iq6#;*$5H5NNgLet~Mq#YS!FahFg`1fB+5TG( z>GO_%_$mL|aS)ru_$ADSkLag5pdtZS$9TDQ?G8`(=XwFlG)}!RwG8d<(=$G_aKklE zKE_B)Ta^n(D9IlLX;69v=0> zII<0h9@EAHI{`wXm7vaK98Hkt zX4dc5{bZn{07!xd*XJBV-`#v~^XoKm1=4o8JdLKf-VH{E2)5mMHkmD5F2nkh{g3R{ zM(ra84Pb-#yClO4_{UN0>W-Z(^JC_|nJs40ym=D9J(CQ@2L3MGIlL>!ZG<~ zIkl>-PX$Laa3^Fav2WzTA=_GhQFHQ0>j_M^Q{AclEg8w#4XcLj9Goab49?KQgZ%A0 z-4&2e`;GWtaX0&)#Bcnc#LvebKJ@=l+;#uQ3|m+_{BLo$2vgAizcI6O5t#o(er&9) zVh@UHFY}ytm)ZSPwrf*3Qez9I=|LLXI{{orM|OI;CumHYXD!iq&dSbd4$kiWw+Q4J zS?AL-7!<{JQ;j!)1@=WdNURIt&>sjcBuiBfr)|(&eqv^H8d9%Ck(!ZE^YIh!{ysf2 zF3${uda*d_Q~5J@k6(R;VeidjT&sF@9+byzL%6~cJAeM#Yt$qQSj_qMn|6M{vu?5n zf@1jfAkVI$NI97qvsp)T{q#Qb#Nj8}2!_k+42LzqRc|!)*eB{(WMU6gIezoH)9)9w zpq0a+N~fY1lPX%G*2s~kDxqtk2@G0#qI_AoHOhy1|CNji`JN|f)QcBZqgrq~S@?~0 z+mf_mireQp*L!mIT+ye!oes4k@cQ$0@lWQrE5%59D{dC<*0pfBIgQW^Cx96a+O3?X z-sP^x@Tk)vxBkZTY}6h=6S$*_$R>nQ8J<$$Swv!C*&|&c$cy2RmL`bnLv_cI8K|8X z5BiXFPe`05vIKv)Vyy_@lrf8T`!lG>-81@=^U@rF7&D&NIeqO_M zMRzJW81X%)j9Kq1((Qjlvy^mHkn{5$uj5n z!ht(w1KK4VyniULrs7y?I%wzaK$_RNm;FJHzcZ!~q!nXYw;U7rbhdo!T%R64LLzl8zecwvGlUZev+6xSwjD z_hWayx`}K_VypPmUaGnp#+8o_^ZZ_VWMrqS5Z&nBvOB9wVgOjMU+a0*71d83$r8o!5I@GDWT zmkMxCt{SbWB?NvaXBQp1UVc9V)w42gCKs=wlpV&DyfwyZ1QKMW-4MpywV;3yp1MRE z;bEr*W1MGTW|6?bL6LA|X!U?WvLvvG|CVux74x1*Rsnjojtn^AKP)RIpiZkHrC!Ga z;UbpZzk)QhyDn`${jVgMxtcMOfHU`~nT`a>vhqP(QH`wlIgV3#zJ(EV!{$9CjqVaE}*n~dWg9ClO{nS@~ zWZ_@qkgpup>hE(vz8pk;36can zT|U1h@y$m=zW0SRPJsX2M_;?y#Li(>zQ5OLH40k)H^^{d0dg13?&3nzXE>kzZp0b3 zO7~iL#AnPi#$UVrb<{bZU}pV6hPSNTX`GNZNk{K+pD0AjPYA6gLUd562VgK{2-pXX zJgTH4mER*JV#ls(pW1$TS&@1B%oM*A(Bx*o&^U>x+2FQ&I7m}8r=BPiTw;|`B~r>X znR|IqK6?qM2g=#kYVM`8Tn%Wrr67$6shZC~=1@%8U7M6YfI3`ONnKrp{}(P@W!9-o zELJhCt{7DG-xu1^G^cD8s(pxKLMw#Ea)h;Hu|k<#X^!+;mmn~}P>qp)VtL+{QqN!M z=yll<0!fQ}Lm1WlW#<`G@KLpQ=Z4Mw{mx&v6%7-qljuF32QR}|uo?U!i(Vi3JFrN- z@2Uz+j=IK#12{i{^4Q!6yL30ourJqeqM;L=5z@&dF}lYDbjqQ^3gykg5P4i9mas;S zaboIA%&g)Pamwb|lwgVf&Tbn+eoD4CHNTaureTZvnXE;@HEq>A|KE+67I}w$lI#2P zs%S$0;)}KSVlW;FbVWi78a&~0gdL-6%QUOENEVf-3YA*M_ZC)q??yGr&Vk9?u_zz| zbv-dQx8M%joBG+pC+_@ohzk=bSl=ui3aNe5Ll563*29NK4R}2up@|ymb$MoAR*=aS ztzrbOK1>{b?Aa!@O+61N+HTMl&dkbZ(HJw5ms>_JaGUD=;!mmmwPK6EF+dH8ZW7n^ zF8an_l-vM9K=}3Je4y61$7+ZyvD7NO4gj zW(yh;F$ez}2|9heXh_Q-U02-a0ctP!xVwc<|Ad-x9wR+Z2rNuOH%7v=(@7}lZ3BZt zXfWfOg>r64W*wS#9YQ=n@u*RsXI)Q;EUfRIAl53Zn;egt~(jlT9 z-qAb*S{76mOdQAt!ZRVo-CJysWS^UZ)#*5A)bZKn97+G+;;$Da!nr&l1aumW=fN8l zChciTTSDw5e!=*>gEaeGoZ~tSfMzMgFF2X47MM7FoyUhvmPaaBDrC6d^5)KOClLZ8 zOfOBAQ;&FM@CoF!%$J9N=u>q*^l)J|e1oD}6t@o;8PR6-7KD~P4oY@47xMKAG54+2 zEwdIM!#Wr8Y0x;z+3Yh+q-30JT=t&{(~KN#?p8k8XM@Pj1#S%dH`WtMt{>wh<*0nB z@$Fd4<=-8-3vov+Xe9=AKt74yGuz>4=e3b9KBRs`O!!?NsI*A9rF?q&RDaqN17lw* z@zUiv?bWAWhJ0nzrTjguiV?fB z)RtxHIk}bZl6XU97T$pAS+h<=s-xLdG4PZ6wU5r$GkslC@7y=Mj8mt7uhgoR{Odt|%4Gn- zWS#{55dNfTHyanjWqRM>C|#Ofah=^yhm!)68RxTmJzhUr&O&sAyT4-@aw@Z?-_jwZ zFIOs%Cbz^yIIdq?kcbWgA{Agv`m2gSae5QyE&%ZaWW zv+j#@xn8O-a-)^BzP)Dq1Q3ye&2PJ6=b3dj*;STK+dhR+|!cNVF? zRV*vi7LgFc2)qaJ$dts@tZN7X%d&)CSw zz%-!~8iM-k+U~0}4&d*i~c~wSqSL8`*Ip#^#ab>D_6lXJ+`pr(mjR6g`a5Mrc z1Okz~F&7kE6iV=M5cwcT;t0x&WVZWVGZ2`OByOx%JTc^6O%2z6hF664?5#xp8RXM= zrU;v+5naG}Y^wPw$NEZ?i<)W`OdGlZ!6lJRZVr15%$Yo|q!895#;w7SKkn?2O$pfj zHW4~ydVEGy5V&LSTMeSYN(8u8Fb|Xt`0;0+ETSPW2gYZ8v`;D3XS^Hu_0w5;QzyCL zjr1p$V7{mAtKscEPevXEvy<$vsD&80SC)$5*cuZ!ph*Z5^KEBCX;8D30@}I^IP^P; zVyuyOlI#?Pz^c&Og3Ctg7jBc57bc(H^{nk}t5_mRIHlH<8Q>~D{tzUll`18qz@mX_ zoaBdfEJ2U96WLyf%FG%zfy=rnZsv`Vz$1kN!EX@Qnwx>0`U{55`J!34MjB|kq=f2w zqzbGT{AaONCo_#Z=DR~nVP|%~86F8Z#Pf8OY9UK|am7-!cwLA-Uhp3`s6dh5gG&eZ1XnmyxpUho2sfi7Nw?jjPc*@RMWG)f)2OpcADDahu9bDTG zd6GsW3-hidz9z{MJNyip1gjW=UOysJw+lPS{VS$C?03z!&+qwv0++Sh=&jFGJsu1% zw>14Coz*3gqBUkVOFs36eMWiFF~+jnc&!K`7H+}WSLtMp*%`u)Em<|WpN5=qhn?g= zKJoT6W=*B}q;+;!nONIeaLXs!tb?oD!EjDT$Bd~9H6={|8FU{>@F}7+071jsnE<^4JGB9hVIL1xS zB$ewHZjV89!67LdlOPQM2IYi98`KTg_z&`{F~ZIeks6xKKFt+3{%A3IV6Hi6$V_)s zUdQrW-Q+&rs2qyTErlc!@+7mQ!BHiwc#__v$sygPHLD}M(w6jH6iev`)81PM_$Dnb z!7r^VK_r{QXmqEf4@@7+DZ|^ygFh@V zv)((NN!B12dd4iiF%{@QZBHZ{5ngc)w zwti582qho-1d}r*3BN2i4(3Xx(72=4mxZ4;RBAjvs~s9W;$&KVOlH><(LouN+9U-M zWilgLfhulID4)t|aQQ+gO(eYLTkcKy6wH`7`rFNpT>`wG!}{;ERDZA+WL{(tCthhWiq2HJMp zwr$(CZQHhO`)u2`ZJ%x1wt3I@SG~@wdz3`Zgl`%NJTD#d5ovg8dCdv;1?)ZFq3hXi~nwuHqwTM_gF`111o}5gLq# zu<#D6k5>a))f3*GBaQX~_43PuGuG&EL0PWiNr95|_V7p`Qf@UKIf1X;l0WHJLQzSA zyX*6d)=!l}{_F0bzn-jx)uPI)aKcNq>jIV52{3Mz7B@9jZ>B?*ESE^x-sN(r>=*6Hi zi>$nZ4~=(-Y9-;5n*xZAg{m*=h`ITPS{Vf`G;OK|*64V&RN26SZ?Fis;02p{4jB4I zZFh-Iwks?^3&Gs_ zr=Qb$L1xSxR(UIwAW8mDA&I4Xl>~Tzinhf1bgW)z(p`}xPmwhI;7#EefB6QzKM=>x z(Hp06mV4H|;a`7z_O@{MEWhFFmO>dJdjmD?RFa0^ti%vrQh)<>;11exxYi~x*vok% zo%o9v1grl0M=}RmjN!0E80Ntf)BcN!MzzokNufNV0m%4{ku>wJu-1Ps0<2vH;2YEV z5BSR-#m#MTI>Up1LnNHSu@YRt85qN)o&q4_5GU+%5SytyfxMvbD~YXSVw8g0*m=zb zQ%JC!2lC6RL8by;IyTK=dG*>U$t5c`E=bLM^8>Vlg%4a2Q1I-EG-_80uoA#Vxe=(} z#jKyJynQVbAeJmHFh(5|sbmRDWqy#Sx3y=x3lI7s^Tk1~F8j>O;MnFdugl94LSl%Q z2rrrEDEJU6By?3jn##$JI=Nn0*w%n0w*I|xf8Ld@es;oVvf?J_q7DU>$fq>x9F>AW zH%i8e4Vh**XTElw5TZ`GbR5&pK$=u8Sxp%YyDxV|G)rPWFsw&0bb3BGhqWW!7Wik; zgLe>Va$q_p6E}BrDw`}ivFh*qr{h)r`V<6ITl?j5p+Rkv?h0vGvB)vw8Ityt(QiHn zsx`zrRl7v0y44Z-E;Z6KaS;mPw5X z4A18mjDigU#otCqg$mLjl(Csy0#`W_M+~JCxhQA!;LiKe<7Q%)jN%$S&~mnZhW7Z0 zH?%rqXU6ghfoWY-IC9E)rFDY`8%D`;0dY7Eb`xv80L2EV1j8bKxL=XLAU^*vmM?0i zB{U*Gm6(iw{PkDai}X$K zz;$#g#j0H<{r;P>Sr1sZt)c6o#T@4)?x_Mi04b_$OdU_9-@Hq!vt%K!n?vK-9Ou>j z&VO6@I7{IQwvP&Vlh%>D|1l2mig#C=W_XSuaWK1@LlI7M)$d;aX{7#0-J)Tx13DY>=Kc6W6`0=@uGS$CkMJ*syt^QfXqs^ zfXEBzEypm}6xDFgiMkJTNu z;J;JdkNAVGG=BK6j9zDbv)OvuBRtB^V66TZ^jahQ=kb*f*gRUl@U$iNrgY=Y09apJ zOARo+h#I6sE}q_Px7X%~pz_AoPSe_m)ShJY{6f;xrN@(C5^dqYLN06T-I4eC3e6!3)%#gpwH^ zu9@A8M4~>KM%3Ho!J?zq*!p2Aeh^fsJ!^ER&Ql2@6uQ?oQdoAqD2BzBxjWQlBYRS3 zwQ*6amS%nn@Fp&Eu&$5`i{I#rlSvrnr0lcGqIr=@aDFHwHPyre%GNtNIj}H;VM)5c z{vgUw^7F5idD^$-Ge{kSHEwln{H$wa+l^F?tv4>P5ev--8J!_CD3_3ldtgO4%2E-* zHy)My7l)5jMA2jndCwpY{8JStA??WFSmGRGio`MBd(s?s2ECiTUB#7<;d|(Rz7D=6 z^ikk!R~}V}G0A?Bn?D;u@SgKklrysFQcaS*Wa=QrWL&20G_?hCe}3gISVLb~LpRJZ z)@K~65KWYBCELZ z*}My*-uUtwmpHvgZ?CQ%5I1x!?6+QJfKqp%neVB)6 z+TX5~tDvX9u$dk1#rP!^yeue8$I3NPKNy(FT{)9rQUmS$<|2P$ITL&Dwed!y zg{UYdln^hZNHW8%TAVV5a6J$2*ru{%o`1ygqufxOBCiFRj^}Bkci-KTFrrZSV_C zlwC(!5ycztH6CXBvq0IKNV`DsP4qk_%669KqPYDNHexkbdJSnU6mOx|epkAK^cRYI z@OjE8tCh4Sinqb5IJI#zpXb4(%4ZWPDpP^3nCfBm=ylbEJ|U`I%P**4LFk|GqGs`5 z{X#}G%nZg8`JC#yFCh#UT_@Y(7%j}sf7j-waAd@D# zB}6iIfwYG@@UqAHs)ibCdi*31j#s%t;o4_Xo?LxJJJo!?=F%yz$UE?`FByNLB%DG} zgHk*-f|)~)Sjx&+R?L!jdS;jN$@6Z#b7$N-L~dw*K+eFsp}-1QKhrp=_z*u(vdN_? z%8z{bpJ|lD4eRi-X%Y^vZ_=U7(=FZ)T`G9ZICGcMeue$6U1XGRrv1KMENzoK@?k_) zh6AXibA}0)ZT$NUC-n;A;3A`~Vxn&B=7W&OOv}QB^Mx~WUrD=RF}#vbgr&bG6~?qh z6V7cIJ!D&0v0YANOxzS9keY;pTQtyj*t8s9Eka<4mG5osVyw9Kqzv!X&W;bO&cV@< z{hhDW*;F0F_MA{>kZ5vk#qC}j3-&(~z*GlGq%Oox2Qy<|#OZd>)XYq)Tyd>;=yz}x zk)ngU<3-q65yB|hUMV?g9@oX~*F?A~0L|r|tF6{r{@mi|XU~6bH7jRPzjLu~6Jxkd zr9&Fkd%uV|T;ZlWa3>?BQ-clmzr+E%xX8_o7CE1>L#9H^xs9hKuO;T7cs60K@z|>= z(mt;V3o$)^%+0T7$0zLk zFJNzCkU+N~=PT=0JChy5Yc5%E#Pk3()~;oxwkN+>)o`$41nwKK>Fd~+b#p)!`Q}O~ z7mzcqB|I`kWj_w4Ff$!h@7k)jr`IGJoP#aPc-uknz}g((Np%t%W+_CRNA2GE&w@pW6JweS*bKEAJzA`g$&@c#3Y7D| z=!RH1xbOOoOLFNGxx<^oF*l^*`vx->k$X(=GSPSd5cKK@SpB}wg~=I-8@zS zD)C@+9R4sb7Sy<<&S#0m!;`&MFUv)&F-h+_lK#o+r&l92hGY15uYU~)vII<^TqcS6 z|G3rvuRcYAKlOi{$e8;DxeE)^i-G7(@ZKGQ)Sa+?KsoV%(n{e<$>v}bSw!bD*h*@- zg7}UtWJ?Y9-Mxe*hs^XZ**iWZfvDYrz(G* zW#-hfN)w=AK5ZnJTwXzitc*PbkiMG`$Z1r;8edx$kgTsX^B4hKyiBD;u^cBy9U!dD z=?pCX1*M-WLd!HUey*zD_g9uV<^%53_7gpzK|6*t5D+eDPaAW!#|M(TN--atblM*K zc3waWAm7HI?_%!r#2>Oi9QbcBBpV>46?1-X@wXHg3VEIUJim(n>6y1CKsex#r?5K$ zu^y~wuYi8dSHEotrGVE*zsO(RzxS^%YXCf0!9>1c9NYqYiU3XB!2JM4JFK~@7 z->1)UffdPn*U)}@0pNIBGHa9Uo#LNmuTMMmU{i<2z)J(+ZK$)k`RoyDGzqCow-tPO z|J-Is6M}zM(83YriwZU2a5MnY8$8@3ZK&PS>_NK?Ou^*_x7(R$#?OL@g`6>9Xo4mI z*cdnUizsNoBc!#jDe|2%KmbjLTK2RP)E~9=+k$uS@6h*3UeyjJ%+9o~?d~AK2Ce!p z8ztJ7m|G`8K?-2L;rp>>69yJL_W*828Cn@gGTRvtD$?H3wgGm%%3LftxbIOE87M&L z2aho%B{P{8TMRnp&f^xA^G)Np1JXNuihlBuW7aP)mdy2ar}E9#;qE$UyZ;C^VMvPN zbZzC{;QJFmpl$5^1il?_93H~O$)ADNpApmoK;goIdI5t*F#*b65%|RwYM66qoG?&; znWZT9smGPIyVTV5T=X+zlq0*Hxj3lS=^*&SW5BN*0G^UP%ljI9gT$lv#Yczr=!#aw z;$(26C=~E&ljZ^GG_NpdEY@ay18r?$s=7cLa0669dqctYe}~(KW`L^3w-`kVse}F` z3?d_cx#S8fI2TWYaY;$_M&W+_Y?e%B> zTr(7j@Ka1anWPwZx^+;@2QGvMXy{5HU3m^fw}7FQt26m8-=8!>a4ClDavE=a4vt}T zzk0Z^@&bry3a%&ZE?k<$NiY#Z^sJgQ1uW%##%OaJleRRyGnAyROG!w^qWcHBL$?ZL zGFw5@!>Lldy{F+(MOpyl0*%@Qh{^ST6U2UM17|)*-yzOQ@B2=Pr2u*`gA{70`8ip^ zWodA2iUsX~=F;4g{oCoFW#s?~w!Xl?fDjAIw)I!}rP={t-yfVvPMRE11b&WF&xI4C67&k6f|a__ zPR=!tt0@wdzsQ15^5HuLVHJi}YG@9jM8jp`= zs7ffo1ZKf#BwL`0;3aq!CK<8|Zj5`{_Keo!tUbt@H(ydFZ(V+o-Oyev z?HB%_MeB1h_`YMN9b69^;|m$qlG4%~zRmJKACGW50co39xQoz|3gK53DxnZN zv7u-eD!60n38`ELxS9v#vHl7MgLOA*O&^^ja15lr`vl93sIryI5ru?)((DGIBrQR} zAgbuXK#YsXByHW=vR1mtMky+EKTL~JPD@L=_e{E_#pb-nme|4omOK*H8>mLvD5Lgq zK#5Hqr3~7wn;Itw8u_D1l_$%VM3p?=VsQR{KvndM^SxzRZxV~)R+ynR&oa5Svk3Lj z%Vy7qR~WE%i9^QZZ<0CPQ}lrCbwnrB`UoRkmohibRnPsG;u=?%y{_izbc@P_WtG$Y zmAKbWy&l@*+Us{3SS~;PZuu;=$~#gnp@+*Oml2InM3)L7g_EV=?qx{79j>DbEnPGh zU$gT10G;fi{dTypb>vz`B9*?$&Z6`)xu{@EdH5EUEjk-J10~G-Jix5(;3G19MBlFc zhzi$mRb@xU<+nB5zFz?G9WHp)}z#1;KBuG2;%D&xM&%marNI z5HJH|HQw2>G@;p%V}$&u!>H1Gf=geU$Ml}$DzrF>mrjtvlsJ}B$z6>O>J%j9Q7&?d zM3k=|Ap>bkw%NzqtO`*NZ`PIF)GVcH+g`ReJqI>?3U8#nelt1`$C}T6mAcva&JX?U zo>5I+TANY}>FUr;{CjfeS4q6-^}ma~Q4M|D_%0y*=Dbl6UB`pG7miisN}1efOTGy1cvze(sP z5(h{Hl;!8OU8!o(tHSpCzSxWxP{R2x{t9p9;1F)I zk53E>$U8j)Uw$_R9Gs~)0&-h@={sKY&haXRLq@l)IurU6(Afyp3(HG7M;r7o zs&kjGxpIo}!2RGjVLagqlorOTW%wJH@Ft z>skj0mPb+7UHD#y6iip2xq<>~=&^d8YwCX;XX+}*Xrc#wE;f_e!05k(;Nh1TxV2)f zzuTs1rQCaxHJAgkTuwDnLnjMnYN)SY_0xYeM?99G4px~Ese?5slK1034))0jp0y;Y zgEEP$dvK>byn^53q^l^T)2KngDGEACclCP`CzrQAF8u{V@>SU96iuOqY_&d$ynUp;$jTSmLtZF~8-8Fi0VPr60wp_`)hcv&hr^fm*eBg_` z$Athn6-7$KX*TX09LC|~;cdoTvcEt8_-dSKt>ODdJSFR@YTfC2`OP`KUSvF~^=+Fk&>sk{Ovq7+ z5BX58wnjG0aE33E_S#snGq$z-ab0CEf{ueQ%YtNh(%yXI8nj7jn>g!_i2yRKz1QG{ z*kXZkpn+i=1d;|+qF{laJ%7}OPlQX9&sk$c_YiA1x;!t%eLtK3ND*5OeYZt)D3AWq zldg@}=Sa?|45&3}>Dk^$T8q_07koG9u-uha>F_&Y77>PC>~VoYErzn-m&Bj5JAJd@ zrA?tYx+W|a@sKnKZ|Pm>xAxl_rCu_Qw%&l<{An>OMD!Z+2ZVo5|3;r}wAF5k82s?; zT7;*B7#?}Hv#lz+%^0|?(Q;a3yL1TAC#iMmcL1Fnu3!Kp`Nlv^2b9D_hx_??C2&nB zH>zXR%Ds!Ji>qDPCuU_NcWq5kCooQHN>r_gUE<|5*!ST54tI>=95 z3}i*&_V73uo7FRx!?i58fo^BgOen5sFP=omNlk)7v&6@qJ;TjoFQCJ-rw^rCoWc+5HTEJeu zB7s)Csl@Y?PIUS7<$Luo04ex8NhjUs1ax(LWEVMN=%ne6vz{XX{;kN#YvE?E=3a@y zbc`Ef=2k@)?Ta?q(=h-L(7*V$e8^=t$weaJZU&6HG-rq%6+i2q>Fvq)G%`j$ ze&rJKl36xsB98Ieq$gyNEdDv4+H?=k3hMcWaB96 z>5JjTwXMB*J+s*dD>Ug}CY0&>>KPOsON2WDPdo_1S{W2cS_5{|MV|Vpy^(Ai9bvVK z`Z05~fB*OW1*lKmU}MQ8-B3c&Y)lgsBu$b6%|b#c#vASm?8vbU<1yL8;RTTss~=h} zeESes_`j1Qn`!ZdLT{#ElEUk`ZQCJzHvlS$mBw^nrTgYeMi#j+uaWq#BuQe&zNZud zm2_VF-y)MY5?e~%09k1F20dt76@M@J3{BB4C$t`PrmsWMkD{z5{O}N>)n_(RzSM^K zKHxz`8_cd}u>AM2SPx1&Ln8ys2H!Yf!LPK1 z731wzo*&qGrZw};FQ_zS%C-@jt`w4Kp-~8$L2uqZ<)hgZ!Gjjsx*jW6PiR8!7xRYG zp8Lbv?lRRasMs1ZncmL2@GLEPv#T!&Ot}RFz|FvdPB{*j1xm8!64A%zcEv1j$x4xu zb+H}7%f0{{uW-uf4Of?B;0cK1 zc#(*}QPBL5^rnUA&HR?V!6!7{|^~*u4L^xTd@Pq7vU_;m<(wH$3rPff-+b{tdd=uib zJKYNarun**fJ3!5g^=R^;2a8q z!_jqLHzk0Lj%a*qut_tbT|#m|ld<}3tSH8wfe!VIsGsZW9l;70${<%4QPoI7Hm=vR zVRtlCII>W~zbvu5k?>pWW30*{Fvw1iAee%t@>|E!ykqs#9MN$R$K0F>6eTjJp%Q7##UCz_ zIpz!?ABsRK&9a{jRO48t_C(TqxDm40w(4lcy-!hiSAP@RjAkA%w;Mw}5-CtvRE z8iu;M^y&!8)b~nHPvJrC`D~)97mI6ai^(P<&k8ZF7u`*H?XuYp+GN6jXR}Jm-9**1 zyc0KxG3nJC_l;kIq)OL&Pq^9ppqo6ucFi7Gzo~>_>48~k*_K2s>3(>08z7lPU!69} zfgH_##lZ=8!g8Ky65R&W@^fu(xZOX7naF7i9~qK$K%#fU@d&Tu^dMn72A?PkC&_)6 zx_552Vg`7ZTCq=aUzIUbj60RQ>ndnn3DCIz1QXc2x=d#gVh)8>uy>)D|Jf{mO*I!t z{hVCPhx$JDB*4OZnBZ}ApvcsbQut6r7*k6LDXm-7KCeA0E0uxKvRBAp7#5OYiMQ=5 zlW37KN4aatAB6o9aKd_@D)FHZArq24{U(cuL*YXJmH6E1KmAHZ^vfT&%GP@jg}<#G z1BWNOHaOp^V>gsYY+$b?bP=j0GCKB`i5Qe&b~&^f2S*Lx z`QJpsDI6-n<-cacFsT;OL<~t9e|fhpP4*a8}n|aRP{4%~CB3V^zaz2{vdg zsYpFP{dzG>vP{FtL}bvXhe{T3W6e6u`%^=?I;o-o$O1`|^XCq1JIaWdHzef&Apyis z2(Phw>F_=UC3IfB#4pG$^zQQU?^*;{Y*)ZVs`WnfQHyW36js~>dK2w`h)cAtF)2jo znsnJsk{Ft(pKbXyfrt|>{~EP1mZpRYkkgz^1V7=DDCSihPMJz4(a{B4ad7K0mw!|* zmtiSVyp=VM0TwG=hXP`PK#_$^P%W1yovjd$<8Lp(eQ?39KkE_&wF)fr54W4+@KG5ra{C!u*g_1}yAch*Sj{E2FZ$5*3PS$Q!|_6sdD z%=u0SmVgt&()mKlAu-$79eSUohzn47Q~QS^IWO$^i6$S>p_}WKxQ*iEw-F`9fNl6u z>a8bM@sxvDLeDY(;K0t)_KZBSlqVL}M?tKEz=EejA`YpTr$0>;N{H?oR#BBk(+i7> z8J+9H;i~~53gV4=(*-gLeAx%Y4Nr~79>+RCq~?rTYmjPl`C4dCf@$yYHlkZFj+`+~ z*C#X<>g%8}?~$7*qsD&4KvbChp+);QCD|BbpfS4FI`cyzqbSYlh%85J3}$Akj1CD` zDkH~MYzd-9QbK+5Q%aQ45vz(2tf_9)eAv{4I2lq4fhhN!R%$|Z&<$ubJY<33cg7SG zi||QG_DA)2;C{H9F!a>}45$M?s@LDgysZsQ%N7*KY25D`i~W$I(nIlh&;aJ08(gIG zm)+R;J(gu+E${d%Nu06n&oy6*r!usT?8EmA|6rE^9yN?I1&IgOigYrF=a=`1IC81fOn` zD#hgNL@~vTB-u>H+^e#z9~K+4f#=XP8iGm6`L5)0fUQDz?zHgD;xq!pAyT2nN+v;NkcDe&a-($c#MQ zpsjG8L9`EQ>lwo3s=a3teaRs~LcK%$4MrKf*OJd6noiY?&_@;<@38AhIg(=4f-CA` zQtv{t!VYyrNF?HG8{oyPPVG}@s`=HkrOuidgGm;jrK%^%d6#MNuzTXRh*ixrY`vxuEkmG|{ct+q~)bU4m@_{5r9J5VEAA`EkyHju23XU=tH$iqP9tW;(ofRyLva zq`7+j%m%Zb7)pr)A~(=yVXQsa@7oy;^YZvZUKDpMN(Z)c8LaGRflu7{lEZ8Ow~dgy zTkT%iv`m{8vN7sG;QfsY2z9Gz+|%P8d@aWIhd0eyeJsza#HZ zZ(lp3lESpOeuhRWqH&7oUCzREBFtZ+9S|y|?C(@B;tEGI@jGlaCsMKK_jx|`Qlgi#$%5si z;RcGxKuR&G3I{6YQn3q<6H+Xeh|~7hpanq7wHmdVMt8aEZ^AT9YN;{=r($1hzumt& z7G+$huzu`Kx$6yXm(?J2^Jz|79PSbXx3yu8caK?$_d^+vNjl6pKKnYcEn-0lfcH%Q z!4{~rFZbzFxH-o4s0I!kz@NUCx@}jWMpIxs@CJ}PSOw*wJBfMHeqyMY-!<62{{a_K zA3k?>0|gJnlR((LDk%X)v5l5yjDesrSq2Y}5DMA6AUO-seAm#*HG;t^+}|A#$1`(P zi4Stj`RdYME8L%sj^iZ1Q@>@@XmywHhdOEZNT+P&@Eril8ay1>E%P2jCt_#$0 zY9N}pQy5q9XWqhh%PSdUSVl;Il*y0)1uU(rd3;v8+cyETkqm@n1kqUolF2_1@8KTT<>Sb z-S-0J!t98DBlsg_AJ;>NH}C$j7K^zxn+v2pL%qulebaQFV)ZRi$@5E4qM%I_WOM7+?NW@uWbZA-HDsi1RUjDB+UWa?!)E(mxu= zv_hL*3{jPF@lp~0;$3)fv7W}e`h_eKJ}LDo>*5BWX`!>DB?-cLH^ z;k535oAQdI?K{%>0;p` z+R7wdHQ~LJubT+-7ATEs3nrar0Q8V!Hh8-o%9yxCQXn-9g)$(ZKVeHs@Oi`nODy}; zo{}prz2~e_kmnEC+utV78C8*eFkB0v&L%M`dJOi^1b`_J;mAo zo}wgy^mYHPWYTL}JEsNCb6%)N+TF^Sh$>CAu`RL*_^hP?dcuvv1|xQd5jWIN{}RdA z%|>>lH_wao-xt!u99+GC^H>T8FV^qKIb$(uJ4+tJ80n>g#E2VUU@ATZQ*H#A>brX~ zG<^2YKYSvcZlvDoG6YWyygO2lAE>U%iInX=#Y(3U3O~X=H=n21A=D9qVFeR-zvV>+ z;7SSJ6jQYlyG@=i{SpJOUcy5rTm{Tm1@$&BT^F)0yvVwY*Ss36t&7Be2d2LhA4Lv( zw4Dy@@tE{Nl!>Z|{VT6F6j974XHJVbmOy2HA5lZ5+pX5K$LuPGJ@T37_DUtu&)<}u zO}|z>u%1185bfph8C2N`1ryM)G{_PdQqdiUW>6nz0ZO^sM#qtUkL-@hVeoH=WiH?{ z)N%^k?Wzx{YPR61B7FYy0IE*E;*9o(Tov&;0n9zA=$=)9;(}B;cPe<&2~^;b*UvNX zar9Nh_)CVlYMO(yVoqTh)eo~;jA1*$4T6!KaPQ88!q2XpG> zj`kmCFb4$k3qhdqASCgBqYVDTFzzw;{)b^qZ^{4?m7(?pGr-BG>>j#n?1@H4Y-hNG=&jB8Coju8A<7aMDBVC zg~dya`>ZtoFJ&F*+Axzx(XnkI?8&?6DbvUl0WqSW2ou*QuziTOe@)mwA|R_Buw@e{;6;E0N!4bD6j%^Ka0O5Y#($xz7QC1E z=%4u{|F;4s|I`=-C7=Xcun-*o)&TNv|5q9ob2H{!p+rqlrV0zgU5 zIMXu|sk3$~Unr`UL^RjW=KQfVAY2%Uq>DS>E`szY;ct*E>h` z%OAO$YY)$i3t_LsyfCccW$?Twl0C+-U%HxFqhY`3>e84FhZ__nQdw&VKyIQi>*LJrc$!68J#?d7#Q z*r|N7_T_eQbhc)cr!8H{p& z+ZD{|y7P-~ZVdz;BGGRDuAAE-vWtnr_rm3S$dZ6gaYw&@$#%OAZxe*AtM?ibvPX*D zeQoEcH!At(dUOf|w{KRy$#(nez-K$f~nLsiU z-ygp2=GmLqNI=+o@eTg*cIW5_H(q~_ya7a%JOsrJ3-d_|0;8BD>n$ud$w(k2+s2t9 z8>FC=#L@mi<1>P_=Vbp0QYNIJ_6Bh6>Gt6vR{Wy_q&FPn53dg!Z*JfRCLX^zIeyh2 ze@i$e)v1;%BasnbUD`ZYI~{9^5;qAd`a5jrap9_BS;LYb*Vvwj*!@r36$BGSwYcRN zQA`~U&KX$P~%)5mU7x!kHC=I034 zfeg1!o<@>8(`3pR=xq8+)T6^0_vMzB*3Ol?7nrssG(?U0VhIG(bt&mxEbck(YyMXX z0OeVl^m?@w98FS5S^boh;hDYE`NU3E=02;x`{z4HyY-SRgm@m}pR+6ALg82T7yIa6 z+`8&>Urk8xKBz}`>n;7%e;){|lkoLdg1A1JICgeu?+OKz<5Q>{#I>50I7K$9GuLEEJ3|-7UWvS zB0F@oNops(P|f0CG8J5m3?bn8gm#1njC-+5io+tZ8vYsdNMKYcz{YKKBC-p^Ao+tSRk{*+||AqRvfQQk3 zw}^P5qlPk>3kC(miLEpfX z@S!LWHSS>NitKD`ZA`ZtBe>c%ChxhEUdJHh%}pzmtCQFmT|{S7h$plzj#-L;QTHSY z&J+F;ydv}0{@k`j>yc(rAH)dWD_2;{M&* zJrtrgwp|+@Jp$5zbF{DN+OnUPF<}wbG{$MFA_H5UUUFOq2F5qqx!x>6valun?ikBs z8l&vPql?>tkMl~87d!mhRWcgs^2%bjbA>yAp^Ny=W|II*8XyLkYFUOy#x#>0wipRc zr5{Hz@1d4u5s~fB#xg#~wJ?0(K&=j-VxrVvL^A;3K|YKYNP045y)vCF5yWZ@ zn!wrV=^8lDVEwlat9&V-NWstcia;YmD)+^r0lgXieTQo0SqkHc-{3X)G24B*o=tH!;lCOUY+P? zBvG3J`6EG;ZOK;cqP1zL4~D&#L&V&Z0TR+NOA`$FkQZy1oPe2Jx6mPM4t2U;9LR({oI(ZwZ08A#- zu?&>C$qanT)*~AikFaA){CiO+3(FNuQ`XA{YFHpYh;Co z*Q-KARfLCoK|kr+yPJ?b0J#Je#ru%bfV`1>OoIl)P0anrMlq=9vJP1mLVO(51@@?YxR}P;t99 z;z>k3R?x`Ozay1&)xt5Bxwx3a&apwRavM8Q{`S($CcjsSU0+Ky7fI zAerDYPBPBb4ygmK4oDqvo-dj2GDkAU)d{H!t}aMj;7i&7J{dd^(xjJOP9Bk|m2Y_> zXRIvGqydKvyJ@#+(>mpj-M%T?yuET0P@i&Qr~R?mP#cMYJc1{yEKD7^bPc*#0aeT8 zQYln6n}d~50bC|jOa*fOw*tzE%ehi0eKva|p+vZhshASwe5wM9jmxQ0C~`JCGoc{3 zjHsA`5mDYn@g#Ayp2U=Wzi zzBr=m@!HEYkOO~;Xe9Ejk^_E8{8&nI=EHP zOmMqjYmd7fS_j+~Xa=}7&@6C!PV0=j6B;`bR%)pl#Sw*AjKvsDQ-CwwNXyj#*nnAl zz*Z@8F#~;mcBFpB2H1p|39u0}1K7;5Dh_RtgRuo)_Wbi@`q5K3Xg?gcOo_?wqp?YF4RCkcWWrVH6+*{L+vgye6ARy zZEymF9n&xPDR31m0k87FFAOCnNxPO+OrjSmXCB*ATFH-VIZ6qqvv$jCL4eX)jXmoGX+o|bOmxQl@U~`eciK?9IkP%!n4BzYC^35nwOhd z2y>%Qb2H$kN(F_T{mPO;JTrv|Bj{-bY+`1SQ>r2$^b|#hbwHgMuDfzBbgBxuO6s!Z) zu6(>|^kGg>B&(mV9W>iolDvh%!s&zR!1YB#zgQfu4irtbmjTmmunetG*Rla-;AyMG z)7OQiF95^(YVWA%G1~78W&FK&U;Vvz5+&yskncv>LcFwteK6fnH`LvrU1DLvP&kvP zVV4@GjUaxIX{vt&F<>2Z&)|lt-3$n$%yU_=P^~-a!SBI`u6nE^E@3(~;yFbqU|cwJ z>dtj#bThm)sFrrCOk3jB!ODQ)D$S^W1NvO6D!0U|pFsXi&LMho-5)%CMZ!v)bVCZc zqaIi9vAKc->zIj8(W%3Uvb?{ngb2I^tIIm~D|6oZ7AaTB3ptx)mLxyTyy zmMR|QVMJ5PN6cVRFmQj=1*f7heJVx`l)ySJab|-Jq&69!^#zZyc}k$+Q}!;>Fl#2E z>lZ4vd(Jwfdd0a^hnDQx$!Kur4d5Sj10A~W3WjfDqhr({jS-L12p=&+QcOLUQZfn6 zoj}Maz5>!#<9G67+Pcm-Jif9Y7q+W~NhV#l_ZEl1h6tQL1V1a_M`8F86sH46Hr{js zHgBh|mdXLum$QF(tUt5H1m;twKK$_!o|f3pr;UI)XN@0q$#s#(42$_&cDVQbKE5Ak z5O7W6Fx&zVLz=P(AHG>-sMDLUo`s2Sfs+nal1JTE?q=Mgbx)awuXc>E(Z7t$hC_&M^#XFw0%K$Fa!O9|2QDH4yf@$$^RBVU8*eCT1ohAcg8W9r0(zS+-0ZaBwSZ#@_P0ozpf%?Y*;4VTdm z5$s&EJlkbwn=khBBnVP{i8T1no~-9%=d0(`S?2!w zKDIQ#dL}-|V}HRuTzmDWC*|H| z(|ptaMQ!m&K1CzfrE|_hd@SeW+&^!X&!=tkx&ELV>GCG}J+tcNAI1833BVI|9Flnx zo2+GHr(5bbz55}!fx9G14}MO+`dZ>sJm{qacN{1R>vI5&OCBLBUc53fFyIDOX0p5%l!knZ_{;0MWz9pRX+=7^kM zSM)_*ZNmQuci824^CZsJ(3p?=1TlU0kivTMp85PvsMb%ufII9C+DE>-(*1(2^v8{2 zB~X7Y{qAUFdD46T2p~>QsT|!(+%d`T`JD=_Rc4l|tzcTnbggxY8C}J!2TL*qSyu_n zvVCKmjyW2bnExB%XjIg;t4B;8I4J3B-;o0%;feLJwtqrpC15z>7;en+#!Vj~m~SmP zpAXz*HACY6u6o)fjN8?FD!;~{wddk+Ssz(SAsQj`a3n*}l%U2XJ-&(JQ5Y6M5 zibeF{L&54un(};~bz}R70?tWP zhMB!}Wfo*yARk+n%z^Dpjs91xnTb@YmG4{hiJw(ed*Q;t{Mf7eV~h%Pg9_k~Tn={N zS>{>mLD5REv=*SoHc1{Lt;G;o7v!VH#oA`Xsiewu8mb?7T~P+w>M6h3IfiRb-sG)t7Jlossigg2cCowfZpx&Iuhp9g~sJQaX7e9`I*>o4QF{V@g+4=PEd3 zg*2^sUv|cjkb=kVMOE9_k<*R+Buhc) znDs(nRDRo37(=Ndl$ce~p(7(;auruqK=FzD8&kfhZ|Tjz2c)z7+Tp7Fz9yUhaym@m z=>SR6A#zz7%GUh%qzszo(%z@@bj|ayYHpU9hMvhBdvb=q2bcrPj&}jf$2fZA-N&A+89H5m9`mKg=Su+F z|F4qqAf|&kcX$`QoKm?5e*ROx>_URqP#b^uee|=E5VoZ{tQFq%=+$^n-ZfIrvk2UE2gip&FC<#%*Fg?^IdGwPZ2Hl^d(~?l%k$4znxkLPK}uCg!WN`0@#=*0QCS>K z25P07F@~Wko>0h7dvYc;ixpw>RrX{fZC2{Gvvr#~!W#aAtUhvyiA|*wWLf%G z!M<>BLeQ2M90xpJ6&K{LR>ISy*VxTux z539TkE_ZvS!&PtzddG$xVAZSu@1g;;h-y48;_0FUgd1rEX||(kw^g;9b>%oW*N4Ne zp1tP$&Dd_sd+qQ*oFrF&h`BZdkeq%+)Si){_&U!l#A-WT$VqDbL?(V3yUz-6tSh+R z(`0Yc4_BT^bCo_*a~VWNt45hpx*_{YO-XVL`fpWS{MSif-py-_*9U9{`;>8op1K=KloRg()DbW_N@W#jv(Ef7u8@{`R!}^(@6Pfsp`_oNPMnB8O2yXk{2gRXLM4O&P7A>9DIbl z`m2S>EF22qk$~LqX!|hEX;|*MA=_Eh(|<~%qmfR?yb%rfalbS&bz0CUAe(M#Oh(-6 z#vXaROi25DfxR_;<;;7qM)rS3_RU7c$=s+E3uWCW#z2SA?ie#;5EsHulN;+4K&mX1 zz9eyGNGv z{*cJWT;%HG-&}0+(dU-#7Y<(@=2g0GoCqWqBmkxsCIF}wC;&9LQexN8{>D`v z;brcelxu*MLBjwdz&+N2no^-khvJdGBkA7ga|Z!B`=?5ZHSga}__cz_8^*NF2PpJ0 z(+Z}EGOjgFHuC;S)@aLzMPmR%@?8?1Qcf?K#D7k^kl1=pWeHh9^MDWX%rO8W`KB$I z?jZ=VRZj<)>?fGzHqPw79D{IxiMbpWJkt-&aZ43t4VghFW?tvK*oKc+da9cDK>sXH zDW@Y!r(}6e{adCV1h{E5zot=!(lqb*lgvLg=xWzH7l)<0-`NDkTnfoDWpwZ^eV`kA z2pilDP=0eZrP7Y1N=mo>PM&o}bc?z*A%NO~#)zWny)msX8b=rF4vVFqbaYSeg*9RL zHIE(ZjZ$c2W3&3owt6m~8E9gbx<}13%38`=4i<^^YT+Hz=&8;<5tvtE)JiwjSzBvt@J{?J4S$X(v*SfNv|?ljcUg>c5gg~ zqgmkx>2>?0jU815EUOyLiZ|XiX*yT#&>1TIf$K|44C;|5y|}Eim(v%Asnph($9Mji z{Ea|>qQ)+iCjtWt{hI&;x7`3BnwH1HfD-@-V{mmZV{mmYXbJ-Yn9F=EmB!Nn%wqWs zKm|lHGez=OcK?@ZyYO|jwOd1UM$Z;9M>cm`0mxHiXIM8L_EyrQApo_D!%_wld_M5; zH_OaOSiA=|cYYd3#FgJK!!2ip<>B$G{1cqa7A|u6c41U}H-~@y|D|`;wP%^#igK%; z=<_f5H3P4zyO|Ze&3#-J)r08Zr7Pw4t86^t_Gn3Lj6jd&38uK_S!aFByUF7E;wpx`)|hT_gGNK&*Hs+Um6 zd|5#5pi$s(QnVG1hUTE)1qx`k@OA)#6RVt_AeQ`wmF*r75Wixdl`p?}hqZ8LQm+M0 z3bjcK>3+7p?FjL(;igahXKV{`=!Ba#n-0X-a{K z!Y?8_wkp84ut0M#M75YI%9UmltVEQogyQb>lWT+6dz7w$Rn6Yvg^7ha`EXvjZ!=nVLo+g(5VhywF;IUSDK~- z>;jf24C2^P<|}a_Z@y)h7eIm)p|3$+ zD4`=RWD6Af`fVH5ZCRp%SUUQGxe;#3tqK)tC59x@D+F#m$(w-DMn-f%&!7j5H|lRx zo{Qqd1WVpR?@E;>l@Sd*Qy`tc&#w1!m8U1%#HD$;2;uC(gR8F=6|R1N9$ve))tT(D zOaAs=A4wmqjFn3|0*Zq?9ZYFg_=GB77Co{YK| z%>=g@mdSXyQv?ZdE!Ai;%ZhoF$dWuxpP<%@#+!BkWpXV$pp0gkN6|v*-@wMZK$Q016<0WG? z!zF_^X^=0aHPT=Z`jV}eZTVJivWL;y5Utad!z*0g+uZRBK&wXSfXFPAHzYIVBwj0f zQ6aYa>PWRer@HJd+kWUhN~*r!YPC0}8o(N`@~NW?h_(zGv^EsRjovQ;sN(kZVi8cZ0{@l|0Bqk9^b^~x3{I~OR2%I*k)KKQ_99Y;KEN*zfe?z+&^QstLeVp8zy+mYY7SgUs&I3)fo|UI$A_-1*U_%mt zF>Ma(^4wlI#>0tPL}z7=@u^C@JO3A4^?vNW=rB(cIvFr^^4l%m;82aX;J!9h@Ee=5 z7rzl^AT?)1OEwIDWSQvmgZ7^EeCvLZliErMR!IBvu@5A+(5!HSAI{d&QIUcl1L`K& z5?K5Hv*_?vtu;&PwCM|3f%(Mpu_%%)JSMPE7u|F=TL^%sC)T@~riD$QoD|g|^TXRq|whL5I0%@Y=JlP8Sh(*@JLk zAXPo!w)ocCwMawEPD&IoXi7a?CJ#AorY@`rE8~hvC5jZT5c_Cy6cY7C*o;l7{VEKU zzw1ZmwVt9ymdL)9Z|Rp7XeII~nO|h6z$`rAO3_Du zrykh?EFpF=A?%Lo6l)a2i9dA6hkp9n>`F5h1IWb~@#sa4zKM>`w0KU%^6+U{mC<@) zeGhpwD)@Kt3OQ%@u*mdf602hNBj`<=oU}^D?wsgCV^iox)QV1`z`DnOtKAtAr9Qkw z&e@riOs$o8xp8)3SV>?Vf_P{&kVqkPx6nbTG@A2F7y7PUkyBXMc8$Tx`FmX0BUUP# zGMB_btH`C&oE<81!({P6sc=@A#eESEamWr-CMrJ)^$=(Ev=78Q>hVq)(bIDZzCBop z*~N1X*ZQrU??^@yCmFE6%ZH*nPf|HGQ8GHf-Wy}-J>5N5@LuV~Pnxp$kh-g4hvR;+oqmgiIkln>_^Pxz>^zQFsQXtj2< zzRl-Wbl6l#&dM?+rjTJY) z2?y{*AzxCoXNbAkQrUNTdz48$`W;mLI5Z>zjQ+DPNv+2%L-3;moi`HMrm3IK_*U7b z6ARlk`EC}tX{=}Rz7@D>gu?d?K3j#kjWx{vSHir;m`pFsY4Y4HhXJC&oIJC@aT=I! z8Z4TZ4LoLgHwsm!qHt3`M&LrBze3;Eo(55@l3`-jl5Q$rZ7^|2FTo^-1>G=t7y5_= z)@ucv-&KUpX-=taT*Zdv7MA2`Ei|jcTlVgomQ7p+OGd9&9)9dSdrtb|+O{_rd-OYv zeFIv@+FZDh_z$?|Dgi|&DeS9I9-Aj5^A&94Ye?cSpfW`xr^Dq~>ITg$h6=(%JkB;K zJaP=~Eu502T`z?7wjFSBWoKRmN-iqcbz~Y+eiy-K!%4--d^p1O=N-a%H$#kEYxccZ z{)08#Zt8F*K1a`KWw>HsQl|$@x{7X8#?^Z9bg*H`I7-j1^H~^QA;2v1D3nbKPexH? z=9E3DBM;=$0~>=^@b$xu{^MXhzYYU`nsp&I%p9b-F1aOvvtZmSo3<3a^hf2t$J%fw zvVr;s9)jSCBNT&oxNpo|l9()9CbEeF7tEYOfPs5NO zFSre{(DVu7At!WYb*5Wf_=FDX(jGlC{Tw9@%S79GgVyw*^)CEot0#6Cy#RY(q?{)+ zQ!ZrK`{-_r^K2r5Ea)mZsGcp}hs`7BVvHLBbt>*@KJ38u?9)c!^8e>QJy?_m{l$7L z%FFd9m|&hH2=h|sE;28Y-D85O{|0g`%+{C{rBh=y7^%FJ5Iq4nK&K(dl3^4+jwc*AN#&IaFr#Kh#cHQK11f_a3roJX)7aD#b5|is2Wtr;7TGzLkl)dH1rqq zUOGx8%sn;a^BGK2z;@8*zfw^wJ?Bf{BYtUciR3kIn6hf&F@V+QG0JZ?llPeBHA77e zbK2C3WHHESWW|$21~3{$`$KIF`Gx~=4g^IdRYJqcISMWGjy=3T3*7jXvqWx|&ExL; z9aY~}OrpV0ce;9n_q?5~$;TgzE}FAQEuvW?@s3at0cY#p@J`Cepvxy3^rD)@$}_}F zxanxdKJ4=p3~g(SO%$?}Ceg>BUMn);N%^+VAh8RFlnE*FU`sfRx`VWp_>(N#^wpEQ zMHnaBH?W9sY{>|R40=uOH#C~~Oo05%rosHYEm@c5^LwQ!8dzwq%jpk&nTqrI%UB$S z>0=SOt0ouGpv;dw%7@Rzi(OgB2q;ghjM4gpo0(-X(dO}{Cw7fP`i(8npi9Z)LL6E& z*yhxV>ofS}9%J=lap3D&5%@+AoCPhs6=lF>PC0RktsOKB36DZNH>b411WqMe&EDkGE!b=8H&-#(g z99-cgPWNfL1E-&>c9++1ZLagr<<@3T9m=EO`1YE1k;pvj`emrjqZ>i1htN^*WpO^sReK!>4ag?`oJ$NnakDQ;wgWq{<|iUNKO^}7L%8Olo~io> z>#m~`S{0yBpp{yjoQ1-%j^T1h5)YgN{@rbd=KBF7g&$$VDId;!VQ$k7cSElC>UxYB z?H{JZBIl4U4ROKAp14Q=)OLg()h=hU#f`WUhF(GUU!fY~-(oTdJaqW+t+xa;aBq%g zCnrpv&RnCPHLnI}F>+WDZKeb{Xid6Mz!{4`Xn3FJo|ZUvyz&Y-KKE3IhT%4A)bzsM7(+Lf;QS2tzY7L-L1K z_LnmJ9ORxBNy;=xB!X94dpX8uUU?&&`MEo#%a=4g({9&>9Bp$&=D#%$`>KzsLAF<#IFm@%DH( zT$1#oBhNN(mE4!y8IH{-mg#&JVxzpo73BbPixB zK<|LQ_#OZl80et^givr3u!V>QCJvE+$0{xW+!MVprPc_%1YkmiZ!jA!2}yuk&`h|Y z5QYv1I1>QplrS>M)qgqpU&)lLU+eIFzCRa`n(x0dTR!FDuI@Xz2Y{=@Vz%k6m%Tj> z?_O?M&(7~pz>IdB{+$`Kb$xd2^#-OmhwNfiVhJy*Kmdo44gB9+cvK^5B zE^b@|IOzK-6UCaTOn@BVzm@KSR1mKY=Hr}aqXJ}voFMZyLY5(zWPr7cCjUk}dQ8<9ofw4wo{^H}e%6^c$2qW6@CkgT@QGx&a}gF!(QZ6?qG1=Hedx=~7R_lLZ#y}) zlX-w$M@XQ+>)<92Q-iPooH~40@p9ni&UemmqsN)*c<1WSXKRlCu^Rtx=EJsiUjJDE z-W}pCwcVp>sWNDLZC&@=)Xn!dA%GsvAM%ez(ru{-o}+6!cv2p# z9XL`rxNz}Y-%+-Y!{9in3DF_<5f%v#xQMVwdQG<-cdGNylD5&;_i&Wt?&!Mq$Z+kZ zryEA)X&|zMo(pGLE`l`549NRC5jCm&u%Q`-BEi2-#D*$gKvAcC5sexYB0*GV^1Hyy zZ#X@teG!Pw*7#Fb9t4q}$sROK@Po$zggf?=(O~4mcQ({|Ozn_mx*X+uYOzkt-%Gvb z(~5Riz4%Kg^V(G*oAUR&^6gb1-uy4Ss6|8nzY7P*CCBb%!DlB+gipt9d{1)`QQ5O- z>@)7iq;0evC~g9GkpQs-ID8z08fNXtdS84Rs=Xc&xb}`2fExov`Uym2#cCkTKR|LB z0oeg^17r=Zgvmr!BryucAt6wZ#61GBA&6En2#UmpAy~b|cdG|3_Ux0e1Q!W1zXk{g(!%9Ry4eyxz!u_1it8Sm_fwTR!#s6m>mb{M99`soPk5)PN> zDz2zc{MiM}CX-NcDKuMjffJ!NKxBavp*BEdffJ$oSP8(rTgNlnOy6^onC#9D zCAbo*n(YaRx;{T|4-etR?Bn;z{r!8qUXAL^o-i+i>6BuY#v_!s1hQJ)XnuqosgNR5 zBBa;F6;#MUDUl_u_h&rL`qHWp79VAmW*$J`)%&IR=X1ySy9w@jDy0qr!~3$ZqI_Vf zD%sqD&DaCdKypCmrbY}xFuD#3wdG_L&IS(7FL_qKQFYV!g3eICDN|F?p2 zO0>z^jYhikFTA}qiZh??V#V?NeY@rC!n)`IdQJ{x1UA-{D?tolwlEm;wVejcfim=u zbRY%kFZ_{a-p%t<0Yt>D!`RMm#pTg3-hxTu+4AY2_Pj6_M>7m9cL9@JTk`%<3^7)r zHL57oVUXVZ$xYf#)0OO%c`fZ%_EzamrGrrq@l~8aH6cSW1XcadWNOTqLUQ z@&t$74_N`p0!En}F~|-M2ZT$|GODDs9RzSZ22iT1QZ}nPqLE#KMpo^dP97 z27*^fJL4@t%&L^Q)oQq}<|j0SOD$3wmr}ND0z#cG0S$zeFgW!+@3G0X<*dYFPo!mw znkFOG_+o~w=*q+#d1ZPH6|VcMQC^jR0G&NnxLLkiCH|_GvPn8~lDjS$TSi=95r@Xx zv-VboV@)r#E@FIaWsjVaxU`wmXaM#~4{KRvr$7o;N$D^(3pH5#&VXaNCbCXm11`T! zQHgC(NN4st3)gk^otbaT_%rO%a_wGRf??o;M)xMOE>X~!OgseKfw8=~s6h%SBs}R# zzVK~Sx!yoMp)Q&bqKXL&ic<%Bn_HJv2qom{K_QW;rCLeUNid?%o9!8!8Gz4}3_WY5 zj1Org)-tOl*grn_Iy?qtY`b=poln_PPMx_hb~tcKxP06<7P=aUq&*brXxD8p0pT+g z6?yly%zUGnHAYy|UZoN&N zm0+cNvkh_BIH>I6YWHXxp;(nyX%knwP~8kX9_C%IgWWSi6%kb!ZCEq|&N8BhV1*Ym z1kCH94LFd;k-L_#0=1}&>K=XYhB`b{wKQEo#<{Y=TH8G(4v<0y37N!O5GxP_L6bs< zUkHt>x{LwaHXNj8Ho-B9d*y}?s{)T&`c0Ac8V0E0koylpez;HT!_K8+< z?W4-FTN3IPt6ShK-@tq6ku%_$Qs+214UE%=x(8aNV`{dm1n|_R1%`T84At=Br$Bk$ z>b1&v0n<#T4;TM*pT$Q$cUe&B>kb%RFd%V008z{lbHY_tm#-LH?ETZK0 z>eOsJxJ^Ruzw-R2sDzoby zw>&RCwHo6+&)P*&5#1g1xAW>-An zF%`FX+Qb2+qQ0+K!gGYyVqSHq?yQ}-M?c`EYmk;j5$H27xSXQOD7HVPxI5gHX9=rz zl5yV)pt!8FGz}`;&+S5~bzyCOXkoNpH0;4TkeztVqI#ZEjFtA4JSg+i-Yqg6IEoUy zr1u3wBDG&@BUe|oxrCFz*j~5*bJk~r8*^#xsy9L+)vmA5oJCgp7NY^3un`uwL!zCI z(Oc+oZJZsp7&`V=4i4`!k^cHtR@%^=o>w_*i&3a+**w3vT3*#cw-HOcOVw#2R0)XK z>xZI~c_EL>U?R|oR+W>$y#si(+$sdo#AytQb`A(k40qBX8;QHo;$HvehG{|D8|X&e-9|ttZpZfe0V>hK__G{KwMt zbPONh-Ygv4xA~lt(fND){9C@g@4k{=-akjbcY;rUrEMQyPKRr8Joh~?w(V-Dv_A;X zM7m$12{(eoN33e1vV zrxgKRWG5{F+cPJ5(IoqeZ1jBPvJ@=IX9;mm6V^g9*ozi)vih$X*&IHS`ej;f|Le<8 zHkvkWUrbp+Mgn?H|I7mjy3-Mn4C(kXogZ^Kw%WX1h;K#~c^YsOp?MHe~ zsP>{xWvClQLUOEs5yWX~44k!Z5cQs|*wGl)3dP+SOiryp-$Wk02!WK&l&1$`*?C=u-voAlnR_?j8$rElel=l z3s!$awCS@<^djX!1AsYb9UbFHcMc94Mj^8oM5fx_3v9A04Iy|?uF7z^XM>1o3~Yr? zaC~=&M70|ZcT9xiY|2aVMHQ~OSjv0IPS0IvNX~>7QzRQ|yBh`JX5~j&G>VUfbS9oW z-?4OX^09>DA#;Po>DADoMN1e_ijEN0!k}$q4lzOwlYm!3y%j8BVktAtZ6Lm#@_9MI zuxy)3Z}@&yf!E&$tg#ghN^ur5h_0|b17>*&ghTp9KI(Rw*Be|m&laA^558dK6J~yw z8HjZVUBUqhH286TZQj*E1(rAAx;RRA=ds!iZbB45-uM?OW>4(afWUokr&+b~V1Vd* z*!Lv@0}G`F1eFjVc&J=^fD-@-V{mmZcsMpLXbJ-Ymyc7W_2bh4%d;T^Fmy9BGxT6} z|L_~Z)ffmHwg@zm*`Ux%gttpY!s%wVe>+VB4mP8VNAU@%@V1M+-zlLfZ@a+5Z2qpvvFdH_Zeav-v4m-6l8cve{RvZM_F9>PXz8$ zF9U~SS(H6_*47)#=WuC*{zV(GF(yW`z#s9kp|V0!3?g~49R6BR*Mx0X4=y$VrIX&- zMWNK(4<4@p4$NVJ_e+J89_kU$68j^LGtb2}zS6F^6a@uMbb3jWY9OIa89_?k!PnG3 zJnybXQ0R#S_yB-C1%3o@mh^f63cD^D(ONJ|su58K#RJuDb$*Nj>0qTU6czztsB(k5 zd8}u#r{~0e;2;wT$C;>j9G=xU@IAt#LhP;&a+jlLli_V$Trq6hLo0nb6%_9LProOo@?Qe%i&p_`0G`LtsJUAKeBd0-$NPQpip<8k@OSr$ z)W-X~aO4%g?}j{|oOo95#gJU{xyb(HaoSEelWcOFt7Uds%WF1UxvDycOrUf*6jXmq zt^P7$@(L9c(BkbwTe)t|{2id5R;&)7ZHoYjd79tEVRd+QCI2Ei7*>Z^7-%iFD;B9D z29zvH@q63Fkdi9ik5EEgmJAa$c!N6Fgru3^S*4X|#{C=WP_dYofyl=*R>u=KG0c6N>*{7Z z{q=`=?RuwL0bqq#9Fg?*Cu8lhE!S==%jkll7RYG~D@YPw!fRDm1dRXx&=a*}KEeQX zh6rQo9$_uF92-dDna@J;Rv^Q!DSyMEv#K$ratoFk^9WL;R;t11Em3yaDC1p1o>AX8;mPJj~t3}bM0FL*dMb7f~PV+sQT zSER_c%HPug$gl?`KnFuJGel1oc5ig*uJ}1~D_|8qNhci6#`Es%1n$5-07(Rp2`Q)H&g$LX?^&6xB29}HEO=~Kv0#oudXh7^(&~3b2xWq@rfMPy8fyl)#<5rNz!S?38$Q>J3 z@?iZK0cE?mb2SfY7})S2d{(lILyHK&f-wQ#xH=r!b<7gbZwDYskP_bk>jUx;MnIB) zPMj#lI0U!AS&$>nU?2cOj2G-3)+}%SAXHtw$}z)6S>PKVkV~wi(Divgl<&HDhlp0a zza=etI{u#{G-*}Xqf=p@;^=nZL|mAH1D@7EgR~M~=W7Sh1QZzB*XH6i!sNm_LKn${!Z~fkPqf;JaCs4$ugJIky*!!JXkaW+tkr`CfGrbx{MXo}R3QG|AAiT%)N*?)_-u4dtYwH%Vn8q8V0qjnCOHW`# z-a!c%^CoG)6a&$SgvI$W+aCW7-?Zb#Vc9=WLPW8g*C~cQC`dk&M6Diii7jzr5sT9B zIvlp17w`&3xzQqz0G{7xj~H3in~reVx&+Ie*9oHlzb82O@N;G4Y(2i1Se6k5udUh5 z^W5g;0kBf)btsr6-?i{0Jm&%FZlzU1jhL~7p1E}O5JGQ8l3XA(3g*`T03u@{hHLNJzxKtHY~1DM z3F6`or~>^ipS^1i96)RW(7Xn*7U;+=bkW$zfkFeVH#ivk*qj$PaMIZePyq;0=MyJH zcw^Lmvs{zV<*blq{9+*nfyY3GabCb(fFd8#hu9>5Kw^%v1TC+aB^9 z!Vn!2tYxmdwO}xt9tSGQ)mTxeSON0o=VMihNK`4#9JtBCqJRiZBo(Kn+tw~z$YMRg zL5UVgZ!i!SGi!|l5gNQE%zz+X5uJpwYn*fBz6s)o`>5qW}*zr zPNC#(t$*9y!|eC&duv1ha1rcZU?Z!%Cenet?^gtTt{zd*pfu7=B84g|d1pTf^D{j# zU;^gm$%Q?r?`ukd3~HbBbQ;6nds$CoWb}fk(DV|P8^0-R#ohHW)$r8nW`YT;$5dUC zdQ3m4!l^={P%PdNE^ZFuFaL0t1&eA2}=$#X?!=yCJq9S25O&%L^1vXcDq6& z6hXX?YE|S!j~NtPJ~7E-S5nUmX(z{3YU8+j(kPO6 zY7oP&*L(hG{$P~c>CN)fCACKb1o23aE~l*Y@xBGCMJ1;w#50}ym{`fv1bc$%+!4)= zsXZf^CLxIMQ&CrD5QI3}ps0yyx3kk;W{9aA3%bN?#EV%L-LT5O$!^vXL!B zP%+ec1v-)BfC2{$Y-?TnV+H13dziWK>uex6Lk;vUHU~NDM1?`eOtVYa5sT^p)EQ6r zwU32&OVnZ*97Wco z72pC~+#9xQD&LY(6=Sktw@PC>l%LSqCx~47Qe1S^r9V(k%vBnxD;=gu;$};$1hKct zcHhyW&=ql9&heM8i}QLYN(i#nFZvLX#f)bHAn6wg&MTVq>va%dXN zy~>TnZgAjjL?Ir8KHEKBpHxIMaEkSsHTecK`$3zM#vE9D;Js*9fevu!u7*rPJ(!wd zF$SeDUJE+L|GmCxo@5FQlqnZB5y4RAPk4&<6Ey=Ku@;6(y{>E-l1$u5fPg=SQIV)| zDns%qB81k0lLj9xHgmG~E8-H#2Y`ZsB~Q+??&FIjA6YmQ4@$IeR*>B#sXFP^CjMW6 zl_pP*vY5!W>i*Q{tMdx$j&gfhPUEE}QdvvMK z)uxmlF4{PX8OGc%oGa1T*6;Qm78_8>su515a77SNOe!Dm-02qDWeCr0QC(F_*({Ms z(=|+&;3I>RW1T8Bim2WzqjlOk9-yiK4^S$gqdsOskFg{wE3H#1hNLQ=XRF zYYk@nEw#}UEk0t;m);4Cp2^V|g*5Xqj2JC2<~@?<9)ieQbLLDht+OEy^(+M(t6Zlb zTWdD^f?Qz+rF2_0Q{s8le$awZ`n1$A!cH4%xk0kpAxvjjMJ;BQphqxtf|Qe{jD@`n zbRQ@{6Dru&vv)Ervr#nben8Q6uL(%ny4GBhYs|T}?Z*cPG+~(c!@K={8=o!f2_TBN z|Him?uHoSYH`#0drg~?8Hia6h6tcD$TQABd8 z_mPYY;qRGlN}K9OmC}J4mw#+Mn^Ojt);yJhzkXLLyJ)mBLZ=KhE`r5kB<|MLO3;8N zOBTERS>@*JQk894R5+*fNNve$hhk`03khx{^ zkZzaE!{HkL*Dg1##4cjd4L>}=j3wA0<$8@GS>0q zNT0k8E&i6lZuKYy8p^n!B<}FdGg?u>{ax~axRFV)h&Ufd z^NgUOhle<`+Jy8u3a9z)ZBp5fXj3qXVQ54IDgl^k#jF?@2Px{iK?Q+@D25r}uU+J| ztg8m4vtLoTdW;BNN)_x`Q3`tMTt(E}^A^lE21YA%*N=)ZBGCNTGf2=+@6Jeq65~gs z19$Ahv3F=ve(V|MfM8$7ouM%6cL?VTW-a~1Hruk6U2xe%(q%-0WxH}IesM@AXAT^O zVHJMB;z?nZ9V%qoR+`FnY1zrFbWEmJznqo~TH3e#O;`H4ijh0VOnlpEG&nXC?o z?5LH@j4hqvx^YS)98=!iaU+#g#V`#`Sl}>ETTCgB{pC^{v`|vxdJ$TP z=7`EdXsd7;3y5R_s!78mr17UIb{j$3ls)XsL<3Yujmm1lxJx#Z>IodQ`Y&{qlOMFa z#W8KHngA58@b*p=oze&v zx3E=sG9YV8)_K4AmxLoWiMn0^`3#G|rQQU61-b?PHHC2*+fUbT$Am_&Fxr^xM&Elp zgmb@x?4&WI^wBw_x5CACaY<>TObL=r)P|_}>(yxRjcrl64cc4eF5dt^_9n>u*F?JQ zJmNkLU_FY`Ri!200G z{b5s_10E0jg~z)3&p(tXs`AwbuNxGiyRV$KHiV9C%xoIjMA;D{#oy9@q%>hG4%ve2 zRdAS%%OESID1LTbW?9+9LXX8j*+hdZ*(z}x-7c0sj~gUrLZ%uSWg5$?8vbEh2O!S| zSdsf->p69hlN&WRdvSN(r-{+-nrp9DnZ`uOl%F2aH{avKe{neYjrtVD4* zxI4o%5LcSJT#g!{1EZ^Kt_T3XmRfeqpriC2=+0v?HN5nH1voiM$+qd-xxXZ?#~dd=H`rms`9%OI69$+Hnn>gC ztED(DSsjt{1N}0av7slOZj7BdVTxR~!C#Tv#yF7s&>qQiyf9+7Rx4{?P@5p-OnZN% zVK!cf7K^4qeLcD|SPNq-ooBvGx}UP%Ai_MZ^W*Aw>Tz=dR4d;Af(6)yU}dgEc_tyj z=uc}HPhBgARMNM5ch$mFY~|H34GDT{ecz;t1%Q+!$vLHt_2XIPvw=xA9uhXSt^Z6b z78*g>-hE+BiM4)3F@S#`iM$#l#j-6qa?O5v($66Bwg#B;dJ&Lc!#o)h{fN z@LdU&yQn`Tm0D3sibwACATQn*ZH;30HmFp>xX`Q`Or@CLoBvWRqG}kDkflqu4W=g) z;WC9P-Y0GzZDO|`Sr|%cU}f;lBc7FBvDmr|Nly$uAB|1$^iZ%PJl9O%Wtupy>6kac ziB=?Va?r+?KTXR*AC~upzvxwGn24(E zKvx(SF=z(LNFF>IOGv9r^`GD?oQd^mOEP4$CfO+tY0e$mn2%cym?oqQ!w!9=MCu^`sN>*vf&>;D-^JJ% zn{?(kjwGKnPSi<~cD^|ohaDKzzW%SOwUIeF&i_=LNH|I@36iFUwJ^R$OCyDw7DmZ( zCn~XmQcxX`jZ^VyF;&!QK3e;&ualoMkR()2D~-jqRL&;s_IQrTkAeW zx|b?3wB7T#2lt${AarXG0GXo~wUs%~M%znj-shO2H%f%rz?MzBzI<|8_2<&{l{CNk zjR$@Q1a-SzZoJ^DuJOFy8Vt;&5Pe%g%}U8(aUgy{S=p1ur9z~zo~cYk)>^%OJmN8c_fr6foKxo@d-4Ahf;*YF;Tx06Zq8Qp{~71W9qb<{&>s4RL9oBncfDa zmDaIKi29`gtG9Ct-7UIrBkR-mq4>Wx+Mi?Vo?IcGcdcbQ6}HGD*Tf|{aGt{N;&y;B zdW(wGv=$56W%}9BbJGSGW%LlwUBa0v_Ut0UXW8>*cyncjNwm-&YQoVc&LbTb+5qKK zGK(2oPLnyEvaLp}i&_wpHb6z}0Er#CPw#nZs#8j18ab+6koxl6Mg2QB3A%tkuz?2) zEb|MwD~0*R|5`BLp2GHlYUt~PI(>mtMjFqU!V4y`%O}96eu*O$nipF$nJ=j6{T%ger@o?y$Uz-HcL*^a)bpd@Q>K@WDi&}{WZ{7 z%uqCAl~+Mzqq0k+QWFQtU+9lmPQ03=w06|+D8M~alJ$~WVj!;*8lxvxt?zuyZFJWr z^M;Ktz~GSdAfJ5AL+MoMBk%(CHOO=vDOMck-x}!xEkyYQ^q@fz#p45|;EJ}N8)uBI z+VDKe$f&9TpPCNMQ2TgWlrfDq11(g=&lDaVpurAN<-408Ypg8H*YnotH0{~ZQCXC~ zta?kRdek;bcUN7idkPF*2CJQFQ7*tML@S;C29db7U`T%*mSQVbXEeq+YWy>A)|2e%M1Hnk8owzUxXy+uuhE6oERtmRh= zP;^Gj<^mk81$i8JP* zM!g^J&qAsB2Vfx^X`@wa51GP|hrsuEIkMdgnn?oQF45`zH}sHb1`bDSt@<#~a2YzR z!C=hk*}3}}A+osHmDYsAp>aI-pWpZB4LQR1B-5iY)=1QH;>cz9D8u(=V#X+s%iROi z7~7u3Q)*?uKHOe&^b0}AGB5+cqU$CU%@e$0a1>Ux?av{;3rCecyj63zH;>k05s(feh0AVuGqD)8G|5kKw;C6zGlB zB$Ja>QO?c8t0f4Re0UfL{SRojt#L3!vF^0t92BwR6A{%O7QA$`NtIx^(~~8pmm^p` zn^=@Qn^;QMKxN{`^)AoyV<(RVFJk0hl{q&q2wflKY&-+k5^wby!?df2e36Pbb&VOe z$s5%shjQH+e0keRjlow4Or&gUM9g%QLea-A(@`pRO!i_{9u{wgCjq=qfvGscE=nxn zrX*1$L8QR5%`N6WGD;;axu`2s%HmbLC-uZTZaMclWSOjQ%*fkQ&UQ|9H{g_7yx7Ug zE%lGWE?TNnnB_fRo`yNIcadu;wqD8NQ5eI~@@t>#87?i(L4ye}nwk7Pgv%sA7>MX=>^)iiLqvZ4G<`*Us zjnC2_awIM0n`-%y8ng|ZXGT$rWP9>hl09evBn;YMk@5B#N%v*s{13(&MWaqJTx)SYO*?=$jTRNYO+ zdmttVWxc9aa!PRB9zRqsM%5tYw_+>T0`I2xyQmcegSES(C1B16`pc^-5HAbkV7?We z*VMV~{Q33SxVtn5C8D5DaX7D0>>@`wPk2za$TrpUOc-VMU6$#hQ=i2O30KE*EqWeV z)$Hza+V1_dBbY)pVEK?~89J0A`&GX;1#u(O;kW*cZ<_AQaqlqwb4oLssJ_5rm_84+ z!Edq-`JUWRopsJ}HhIYb^2-yrU7j>;F->$8@go@$IxJ8CG&e-J88xFnN=;+Z=3 zvUc5%h9gV00FsGM*6+R-@-E!*Hi^9h3?to}$L>q_d)BYD&x4q@Uf+6u-gJ|}cQBrk z=Ve$23&hD&nGIi!5adF{SBrm;zwoN3Eecgmlk6}eYV>a3yr z3TK*oS~=Jwyo4>qKchNr7Rs}fk+!z##LRA1W5IBSKV!_t{fWQg;~BDbyDLc+U2sS? zxH|=Y;^JlZCUom2y+0gYosmg;-iXaZSl_T=86UY9=UwC8rGh(o=9P=GI8T8MNvx@&Ts#pP@`(o0$qe{N*s{?Y29-j#c7b_H&&y7I#DI?<-e$yk0o>tii_vx=GNoJld!-lPXNPqQ;)c)Q0IX0II z8DrM>^l2Cc81F?>Yv!Ck9b8HO(wKK<7@p7M|C36+Q^hxCTIOLn^B%M=@fT?8Y)xy{ z1f7jw;2}biPi9=^2|wTu2Ufn3xMFW)8`&miGX^fT2AkX9cdBfT%wSeWVm)^+i7CxH zYFBcZ#k(xL^D#q|XZ^=<1?1h&_04bvRIZvP!_A9b7vt9Kp))&r<}&5CjtNmbUBf8u z%0M?sM?-&0Z(4El%uMk!DDK(Q(9slGSw(3QL^Rp-!7?Bp!E})&yrvFk2pTj~c$WMx zvpB7q@Lm+|X?-2q&^rS2rIXRy@l0@{ElN2jxm#SxHDrX*XWb(#ODV%PE`u+%A_b=XQ(^ zpNvN^)l<7GMtEr~*x$C%sZbaSbtRzW^W}vkTRlIAQ>P(?1wwy}DI^}tlz8ys;)(_s z&V@4*f-N_R@C&$M|KtSMg+CynAtaYgehMT3Qgt{@eq#jI{`_{4O8H{1p;LnVDVP|c zw6Eb~9!xugi{v8x^}4YGE7s_CTsW=GiA*>xUN<*!BI*;Hs*P<&nm2SLco$jGDV<`FZ4cz@$|nmpUaOW2kN?)mpr7G6(CNT z-N&JoFHlNE94$YVv}HUY1vKZg-wuJ%WbVW65wpdx?^-uO2(na1C(Xu^807o zW<8=t)k7YBaMql3yVVj|`ZgW*87IqE`E55RU^8A!BwMaG(kz=ohLw-CZWdCf47oUM zCKRUKcI%HFoBY{Oa22Or@8BKQY*xfvROmib&k09=Yu^X{q_%27yLgZuPCmifVOLQT-LC+$mkGz)ENgwCr5BJ zNeyE`ucP|kHyW<#=u1c)_xI=$y00s1g&Eq+#c#nE z33ng5Cr3{<{OK^NmxnD?CsiFYN|JwzZClFH42oAlQ&8ztCp}6hEuJ9BpOP(h@klFg zNUfjV!-3y|nDGBP_3F1dIQkiLSc(tN=eJM@ZN_wD0@YW}Z#D`O3^p1Ql(N~$q6@#{ zjFDW;AZFS_x$~Q>i9fw;8l7yC9bG0nO>*A4`s5^+#7e5tjd5W0z(Q6uWjm6jS$Q(0 ze2{eybeL8mx26&)@#@t!q-balf#N5>b8FJn%0fJt{{aTo zpe7yXq1;TlAHJ5>H*_U4s_RIQR@)kDps_jJMQPu?w8~r~at`0v3UqlP2(s2uHapkP zz930go6*`C*)rU{@GiTw9XQLpYq{!bFJ2M^kj5d9p!ltvx&i`81R?O<=5hLe>Zblv zi`Y^?qRFNFTQ~J?4#)s1#Kf-xA~Rp)#z*SpTjd7}O5b1lI;W5;K4-m7CO(EG%SN_I zN$;aG%H?~2L~$^3Q!<91&GRtnemOE~w|jF<1DZk>e4oInVhhp{p1p#EDPS>I*=$a} z{z_Ia^IPxBN1@Du36QoJRPjbn%5>;X;vA{>Q<5ys#-e7CDs^npux&!`{xX6$vt6hjFn=D9vNBt#F+Xl}DtDhAD zXer-kc+@H_@}*2mh$~;LV(`;@?X1AWYAIKM0xftw! zre{hW?00&YS@>B^bf0JG15znqSnIjV+FXSYhbUBKGMv=#dXLufJ326ASPl)^a9~Sp zHjJ`wT9tSq`4SaKNj4q)d^EomMdz6zr?X83XkVATkW--~a#xT}pg3xCARgU^1_D|> z20Tm3?ws{{>@PW5f+mmAxq@yTer})fTP_i~1|J5=UmU)-*T4I;`vSF%zR3Wgb{w8Q zg$W+snZP?3pAuHSIL+S=4sF+_EO&GtYp!4aZcdLx3Ym0i4`MidiQBVVkj`!F?+X+P zKsd$km&~_y{lp@Zz|{Vkd%FkJ17-nm5s1-83(|wv-#3hr%4gpp(aF&(~Cv6V9RejE1rT6q`8`1IYVHVd!TQ!&%ANJaO2&}db# zb|JlWLOx^&gy+=t%q}$07$BhL=Gu$L<2(tttf(12dh&dZa%^d4e zLFi}fYhT_=*UPAfwli0&U#qU~NVKbvw`xYibEpNyA`#iD&`a2m+<9Dw&xg$J0|g8nD#b68j<}$ZW@>%187Q^ zN_xTlSwIIKw13X($$m$U9%^azlbx!@Y7O`oh)#8IrK3r#!zQrqD7F)&hjoHW{-jFW zn(2>F3beviZd;b-c7GvtK*w<|tI#~iM9;=JDsV&NJRz$qjj0+7ua zEYIjK^8Wc1!iODpkq~fE?^ER3JPys0U^HO_rxm^Al3uofa{Q=fPrHcHky9BmJ98!_ z30fNF-mYbpM~+q?wr49x@%0*+kBjX5g=h-j9i4F;N<>pt<~&*l&I@Imw1%9FFW|Ag z8729`7fc}>DWwuD9)QkW7F_-EO=PN1BKILKi%W>izfg&Dl$T*q>MLdlqYb*F`qdBb z=B(RGDwuaQ;Q=#>S&u&Wwo9`8UOtEau4>0hzk@aJg|2R4DvUxN%E1QO5MyoiIXiBX zNf1hjOyp&6tX=ti(OKO117Map5&jpwPkr2)9^BUf6z? zP*G|8KsMa$AA$v5;#Wpu`k<2a+$zQ3Mmwjhs?s=b4=7Gu;SMD6$waS)qGHn=@%Wme zy3lD4#E3AjB5C4vyBh%9Ckt9xml3E!vHY`u8bKqhw7Kjs9@>)#IgTgehYe3nAVpZ4 z_(WK;0`ynf=LATk1BuhUw?TMZ82l6Rk5qOt0m2EwVJvSHc?~s$oYzkOK~2c}T9TdY zx~p2)7r}#~2i} zBe&?n^gdFK`FrV6WYBYN*VckY~7l?8?H9X@|(;y^4znM6{b-XNdYgHDkh3m=_rZRX}4OuGuvE_6_)2= z`H^N7tLMETQ9_d2Dk#QnYF2~oWhmt-J|vOII$CT7I*E~tN2I`BD__eBIyh=qmuC(0 z(EE36QJ^Xzd5Z7?tz%0Sv1TlO2lf|Y2zN{TbTY+Slv2I&Y=r1Kr6@?#C%ZMs&6z{(vUnMn z-2zs2;icW;O%#yU>2bB>0L&G52dIC;k^gTv%IOCn=+@{O{S8O3|6hri&W6|@P9Z%_v1-(V!i3aV?GYda82fPw8VhA%1>Z8Yakagc^Fx~cytQL8uGZ(g{* znl8;_PgcAt9f`W|hHWwY9YL5JV4bgbzFubGY~Q zV`Nv*C8dHsLfw^F!&f1$IKP^tJ)GG;J~X8;>5lL2Ra&9_oa8>)U=Wf-DLMy828E-K zbk}+@Ws(}B;naFle*TJRl8^gKhImn`Qa9!2!=|deO-aaiLAxiknj&IpVXqQ#(9=>9 z-X(&FQ3uwX+NcW@4#d>@jUy;SLhb-?bxsCJb&Bpe=iKkkpPu8&&&d*-ihMv+_wmo=m^xm?K@cVf@`FvV+TE3pS$X8{$Bj96-{*eZb$3PU-6 zBp~AH%-dX=JjdZu=E!3lS2OyYe+;O`JyJccn-gQ(89u$}45nyt&(Y(O7*pKH3f1_j z{T_Y0H->%rgvO*euRJxgu_+vR98x%M;Ir*P;klQ6Kx5pcA73K=C6V({XrnIKUm$%g z3I&f$nBQZ?N!9tQ#F)lp9M$sLXmQ#Kbp3RjOv~*|UV0 zB1#>#7u`bW@gT=hV}NYKJIJLjCT(IEhxm4pChYN4q2qk=ENhfMhu+{H_u|-vSnZc#XruKuLJYFtQ_rr<&>yOs4*wC^i zxECt&35s6HFqQ|?`fA!}5;k6i9Md<4oec{=uOe}TB9`IZpbl_oO#cH&cX`)KyI7uz z>{#fl7wZAK-w^ea&WH4lL}zn-S1)Sc1#=zw&e(-wiKPDeH_s8du{I2LVAUZS6CXSN zo5Xg_jZku;f;r+i3qg7JvCd!K&zFZP@O~g8t3twTct?@l>7KTfl<8p?g1*wrf0-i< z`TVl;e3Ftkl{17p(X)^cOe4Hg>je4Q+%9jvE70 zEQN+qt`;n!t)y<>cV3vDJ}*rruXyQAPrlr@ufpnTsr_8CbbqEh(>fn9A~t@y9oteE zxsDyH6`jXVv;r^Urd!8Wu(RxutI4_c$hGL4du3a3F1)gA+m`RxwjF5~dTiQ;_jX!v zHmq_Ftmml4~U_3X@AEEJ%WL#mx(oQzgtv zl4B*z3X?;*W_4q`4*uYn7F6CkXGS;pEn9F+fvbleFyI&$RMt8tM%Vi-OLC2Yt3w+`Yr-#`L*i3@+b-*K_)6n{H9^xio{KS2md_>l zRgNbMX@WR_^4TK>6LK2aw-@g8zuncH`#{9ZE+g3n(IwUD4&#N~g1;VJ^$0>sWY%%V z)$_t%#nKwsAsu4q0VO}uxtQ6-JrqAgrjxE>p#;bZBr{->}d>H=|lF)E((H%M7q`OD1EyF^tRqv-B2pB@@c((s^Je;IAA~NKdWi@sO9l7+^%JbD2s;(xr>~_e!y&V7JG|-K|lDVZZBN4 zV?btDiW_pm+BE*Pjlj>`sDvScM?Kj*67N5>9Xdfou_>FOkYiOn522ER>L|{|`3gIX zFMoCc52ac78Z7S15Sqv3+?(i~MyU}->A4r+r8>?{k0>(AwKR3M8U$;?15^Xg$i?1lW$uY$@(Z^r6;I-xXbZ_B1 zzBN_#^b~+r1I=JXCi4$FAEM=LN*FE9EOt&{C=QWSMA=E4;`8Sys^I-RoHDZfO=)K2 z?32a2H3xMW)l-)JA!p!$zTwXBTYFsRt4^9uX#L9{;nSh|HGs!GUfU#Bu6=H?c;ZEese|%;7tdHd)?A|Lf{<_i6SOAcnL|_6UHiemAM~eJ^IZ_96 zC$s;$((g7Z-|PGZz_9~22nLAXwqZHe5Zets_P$vZDAFyqIrhp^S`2-f2G|gpYV=;n zffh58dd=Ju(tIhQ>ur3ueJ#p19Gj6NEE{#J6kA_Pk?0;EMd6%71s%9gwVy!P;sc4o z30fja5jQcSuV&iK-P1#c-|C2jWUY)Uf$3_JoCtNN5)>y+N; z+dGv)`#i3`9XRx+VQR_fV_|PPcGH}870!`T7xH> zcS4~1Ed+-^9L97G=^NjKQ1Ks>}0tm=?tjVK5ElJlzC9_iWTI->)J?DXb83p(5f9wf#j8J&o1{%34u9UEM!Q1a+i@^qb;iK z*T@u_T@m+|(c@8rQjteWhM!1=%oj*i&#{sw6`e*>CuU~3T5co^q(Sn?bpES0J22EU zMOU85oG?J4zZ@Vz!!Rc@d1O3uCuh9=AVIoiW@;VP86&SVVkzVdo5_XVkY^-mvK2|7 z@2H9-{VqzoEj=9qU;AlWITaB{E#zgl4iBEdoHvRXEtbOGmm7U}8(Z~JR|FZqeTk@% zgDj#9e+`Ek*Jz@{EsHnFi_$s?>q$743ZG<$3deZqW!Nl`z{%kIrHVPppUg{Zr{hW> z1M(`v|7UPP{l%phBj6Tg=p7dn3)X9odbs&ko8V1zt7vIU;_!)`#w?`QqGoRLCyNy8A+MZgAqXR z8TT3m-rFE7b~|`+^5C`kZoid~ap>p#SH%r-NyP(LE~1=D_1`NI%{~?<%~it8h>>w< z=X|mNq0!q%HsoV{JKBgCRb)Y8Ec%74DB#H>yNw=KQC?n7>U)0b(Zb!DCCaBdjNKhc zaAb;2EqkbP*}D94uMz&W zybD=*Yptu_jwpXH{L>+WURvXU>tTQmhC8~OZC!l%)bsvR=DK55<~RJQcaZ+#3wBV0 zvMp7|3xaVCJw@svL)fAo+MweXQY>jrD?5r z^bdalCYnBuLZL`PBq>M*7!`*rk}UpX`UZw2ZrfV~<2_Fo64*ku2jc zstTYt91l_6FQ!v7jX}3G`W+yU4`? zJ*Lm_WJl@sm&=^l=nx3={|Q(r%DM0_|7$G3g*{cCA-D{xDzhcuU#C$YEi*~JBFnPk)RtYB6plW;L{F{XxjLow|PV7@Ff))Q;voD?!>;i_`yglee7 z;oz(N16;1NphRW*aj`#M6my^7QUiWZN|JBQkX@OFJGeS@+-L=uWB${ta+c49x9|y#L+;4{O&dE%gyAb9Vy|%p?dpJh{TX% zlC#Vv`fc`jjyr&5o4F3s^@;fCVY%)qxN&=X-0FD3&f3{ZB~-!{hS#sQZe80%Fz=e> z%QH*AYHyhz@ISpEmNwO1?o|(7WC_A_uDWXq`0vgP55jx1-gr)=q;x#iRJOEEvLkh& zUL?>`d?$=AXMa?R&@!2>2N3R>ch(3FD8~eY_qy;jJU@;U5~k{o9`b%cnx{IfQXER5J&v{4LTogrp7vr$4f2lUex}wW&=g_aI1EcG^$B6Uztq3ENL2Xi zKnz34MS;h>EFBLl#(jlI*2oI1e-aFcwlMkRTi{^!x3}jLzi*6)gJRTyv<56u+Y4lV zZpAm$0$CgO^nS`BZ2k~=TMSk-1qDyD?N>5&dauu&y#;i`HyPyikLV%^UyzUJM-TlX z3{&0K7-=FaJ4|f>_aZ^&XqTuuz~$z2dYrH6zX?1q+t-lOdhr_B7TT$~uz#W`IH&%^ zP<>hYjhN>Mw{zk95*BQUb|&`-JdyKXf1qlERro{VDfV^LN`+3c?MW!*Dz1 z(U3+&#Fm#r7vU{nEh8@x0irKN5{ZlSC`=_`G|Hs7JVi2ed)=1+4fJQUlw&HFv5*jj zMkTkqUnLootMNJ}CU*Pmm)H&>LDr8!^iCrCE5J#W;Bl0_79Wp-l>}QHvE!r2A8liS z!YyYs;(qN{k(=4I=wED}HUGIJJ4@#n_QCW|g%;4%p`CJ$Re)4J?OZ__4#i2HqL(5~ zZj0#`v7841fGiIJ5a48W2K*uxl>ZB{IN4g88~zuvKy7C~hh+Y$WH=lH{pWO1=uuwf zrA#-(b?}e>IV1?70#t!M-C~(anJ%WaiZF;@9hn*BY*G1E&y5xx#~QU~-2~ayhRqZo zf*`@RbIV8o=R@jSRt+;AKg{ic+BVx=WBRdMj~n3(^t$kiFwsU^jBZmgFVEDeE$=0o z0iD4GJ46#VT(&Eq&PvSC6THFRx$>%HGP;XRt8G$Hq&l;KfY5r7>F6W+?QUbR0UdtQ zLOa<}JnrEpk}8Y6HMU5-w4sUB+(h>cM0M!%M;?5gqRl~b#Zm^w`o^>3>-n^@SakYf>a_!h3Cr% zDSXHb_s>$&Ez|b`n!!LPQZe*jfay24SB9m5Pu#m$FT7aWbh&;da>grme8_fNxbU89jYRAZ>7DToJ-hOhsI|XdAR+1Gq`A_~zH+|to z5VYp+=GeI5VQumiiRbQ;?StIf23}hJ%hGKY$1cy+e1CyCaLOEct>ep3x!1CR zgNG@fk3W?D3c&uYm_L*{fA5?DN>9s3s^}_yGjKv(nw(h@_}85l=#UNv{Rqk~k?9ae zr@%97s9Nf?B74$ctu^_NEX{Sd*WZaqQMxzh9voS^iQlJY6%kAZbeRk>ZuX;n_Q{dX zE#26s&kw*YpttKknUPEokV!NG+CM5b|8Hi*!0>-EBMhK9|6LnnVHm$_gOr(G6-@Vo zc=zB{-DAtp;<#Ep+2yY((Tm^M_C|%p`N@Lm? z(DUotHsGJL>1{iHki$R%1b&hbe;vP3{CfBeUv4^_6UBG#CYB9)@+|+EzXH5$Hl|@t z7_A-)S?n3@SN^D$c|umB4j;YwvE8r$+)n2?PJIDDSa{_aHCxi1&HjE-L?CI4UIZ46 z0-5ANF$ya7RrxgxC|q$W0}vKeX#{T`3C%U!tdz5eCl6AGr@tN}UcKpWP}TGL3H`gu z;=ji)7a=QFU_J8j$o+#N*%V?G?1Q7KYh(@#x@57V6Ol0&$%yt#^y>{WGovU3t&b|& zzBHms4vk*Ki^2f48^4uqwBxCXtEV=bk7;!g=oTRkzg=D%)t3qf#d5PfhR#N=prJo= zL3a=;Fh%^OlvEf2eS0*{%-$zha zz(~PM=s)_lR~(Vi|Hs{i0Dv6a0T38mNM-#0?8)5ezrMDDJMVw&$>kWB;6ItRM?I5| z*`AR71wpAiEBh-bP5lUco4&GU(pEOsrD(Rp*>Mj@9MYjjpFO9{1P9?Q8!?J0m)X`H zUsWI(2OS5mkNJ7m2i}SJ>l;q@?c}*B;6EMdx2CL94MES{7j$c8G#gHI+WRMl(CDeg z7D{$RM;sGH6;1IE$QE6W%3eeq#5YPT8H8Xet5@5wro3aC*jeSRHB$xjpBA30WlvPEZ^bph+Mnfj_x2BqFN}XrZi$%t z!~S)db#kcC@&)Yl34*acvIGt^_J~lHKgyBF)I0p18mR527y~}su{K+@dRKK5Y!pMrnZ6s>`B&hlXX(s4Z4>r z##8f<7Q&v*3wc7-Zu@9<(nH079+^C*dP6toi`;bj#k0eM$qUGDdmsgHb-yI%<7GsY z7i_*{*J5Pe;-^R|O1vU~7r~hn<;0#~^VAaHA*EJa0msY0TxW}(U|QN9?T9do*nB=Yf2qcM!S2QYO%`mMM5wzD5}gMQ|u zCP^_oODGfFRo$!f2&;02+{Arpo0YKnj(4udSXdU>%62 zk?|$tMZxZFuK%*P=9ny1RZY=Wu{6h=VrYQlkLLevEg>K}*`w518t%_x>Jr*a(F=bq zg)-JI^;bv0U06ux1smzbWx3aE7?FcW`ME+B)Ng@FyMLHU-Su z#zxm*oj`WsNV976iREaOXgTCk>wT0jcsy;X{fWP)t(5pki!2I5Id3(&ZbD8x-zqX1 zcIY?4oXekHqLtM2TLLDrawIksw`0n~umhW8B(Z+X*t1KS5|PVBWb}cNU-+3gPUe|g z3Yl`>*{?nli2YCW}(NqgiadE%HY6#pYPc4^cBmewa0%LAyFcn`cbI2$rH~bIu517 z78}-rI&3MBLVG4|dahW1(!Be^f_j7+t1F+VtW`8nEUF$AY_i0A#Y^xFv) z8N|LfpIqXs%y{rK?7Zw8gV*%wHql5?`<2Ex`)K`HM-QHFt>Uu2_D>7Cgzc)8-x}@> z`mM?QIws9jfm5W_(%^;pL&JbcQl{ip+y?_qN_Mzaz1O)MAB)FRoFg%AF*Qv^r&K5n zsa7146$lpe#rN~lao%B?2|gJN1pqQg*KermfHODfnRTq35^i8r}`2*nKqki;r-aJ#Q%1LGBuaHu( zHdl8fqC)Z9CC~je_Q@2gyg}`@GU@W!b1Hb+oavoos5Zba*fP^->(**GTog&SCdzt< zJb?6n<{m2Ogo`i1v#L34gj)JWtOM=Na9=**wN*b~fXBCIXvjNuH1@n1Vm@%S7pfM{ z0y%bcoW--H?3WwOXuqmiES^+V$_)&rFByJKGBF$gRVa; z*COW?ZU1YL(|!oQXG8x3Tq?HjyT=&^m3h(vXUtb=Zk?7F7jdVhIsEJMF|J+&k$%7 zAVtX_EO~|RU!&9M7EpO!tzGi5f;^WgLvsi_;F2P5ygrZeO zq3}5R!!pCpun(LJwo6{fQ!bcLVU7}`l@Efpul7MX6%3z@M5qU*uqxqBt1U3hB_T~# zg(kzsMABs^#r4hTKFB(#1-oJYf=%fV#Cq-mlm~?oXN@JOn@Kj~Vjso2GJlyR>y=4~ zj}BfbujBIcQAKFp_|WC2_YQ5LAfCG9w_J$4wguarlBR{D9(Cqw60*`zK3r^cz8*TBAY9fJ*(e>Bgde&T=OcuLD_q-V{TN z@sVtFyg+`-s>8Xh#N%;cGq+>cRM#)VNHtgkp_H=Wrn8X>Tzs_#lbwJbl~7?%Z5OZd z2}!bZ*Uvb(SR$zWz!n^h&A81Dvf9U`|67ZW&;1T*B?LbY2md|GGW870Y;AHkr(rpB znKlkfloe{79)S0qGySwlGszq+Vo~v*F=YX=6P%VCUW>i?-_VCJv?V($Aze?c-Hb8mSK>+#9R0UmhA#tOuW|G) zf0N7_G|Kvj`1k^1&#Y`Ma57gru435|^sjY4NjirP|UW`q=@P4Mu@sQ)?IlvM) zJaLo)S{!VUF*r}=t)zX+%B4%}Yc0uEoG>`GK9>Wg<&!Q+U|)KJST~f`j+UC`(h0eK zBuE~1uIN%9ZZ3LYYf2m?YdLT4pt!50d8qOak+9?q{27=78|%|89A63uh1>teK@QiVyWQl%fq;yF?_upX^MfO5w2a#9u3O- zFF8D1Xbw|gQ|-ws8>Y<1KK*cDW`Z6x%uhe|_XQ%R_tRupIn%{asaq-O@?oi#gh5KI z!_;4U8KWYT$(ro3LS()RMVkzvz9AWPW^2YQ{_FE>Fx&V%^Nli<%zpGv0Q0+Vt4u#1 zFw16H%+%=JxfuyjIrSahn8xh(GF(bc3rCwME3i@D3Z%Q%V$h20WjZ`?j-pIE!Gg@P zB;FEMQWeqeI0xJ`_gu&9K)Ux%A!$V?6xT#lxFG&0>h8^Ce8PtYh{!$KeB z+1G-)X(g{-4Kke}7F}<~HT3TO`ooGloZ+Ip@RjoA^L}+-^!1f#-1^2F>wo@h+AvG$ z*3U99Ytc3`y$f(Pq+Sd6=x-t|i2wk3>jEGETt}g1M~IH0}3uM*0<kcICp`aSh+8|VOL#VY1yy8~h@n!wk2cXBOwdJEg{1F?&@ zt(?oQaS^<)hDRL}2|MN0hSC!m2|Es$fa!!WV+!4zyT*#pgFe6c6;vco71YK}T?BD| zh(gqxA}mJ&vN9oIoQz_y2=h6B@oe~75GFn%-5MAxHz7PK&h<#)q^U6Lh65}#cNf{^ z2e7>eBN^A@gRVtD3XgRzmwZT3kZEpr`poc2oe6JiB9>8OGkD)u@?7E&ZPkjW5i>7V z1tA$@yF@>YFo_uoXVFX}e8~1g0h+q-O%!oby`_FqNKLJ%2;oZOB^{dZI6FP7Z7TZ0 zK$xLdDw?JQYp*egK&$(tA2^S>()w%)bZ5RC5+l$Sbp6KQqMo&2uic49jhgN7whM9% z<}m&!2%gGHi%e~l5xa2-_z`#760K%Ddn;yCn4(cJ9izOsJgNl4(?SgPkB2ql(-!V) z0rHEw=&c~ZLCHeeGq5Q9#C~3aW=a-AYIsC&S7!MMHJvV++C^~YnJJtScx)CP8PDK! zT_uxAJn#%==E^JNawieE4q#otuS`~2??I(l81KucZQI$~LLSTV?cZ?xDlMb<*ga*O zFO#?NM?CvuN;%v1;0JvT_Zq;~+#ZSHvK5R9Tl(& zZ(^EqIM5%R!x=)mUe~ODM&RNA`vv&HK2PyLiSdYtx`smCar};@tHyv9NY!E^uCT?E zi*!IJh?zBrTMUSzmSGcJw9O&X%+IJIweYjx86kuS;?WAB+!1X}k5wX++5=14F8MW~j6Kt2!%cw-m&{}WL#b8!79t?+2g*DdzV15OPo z1CqNkGxMu~>b+z4E~}Arv&lNTW}$@=!YC_iA%jx>5FEal!?I>LC~%CvrrM~^oMeTq zCcRmLv60RL?Ts7pSmS7WnX_dOcwHfWe%?*B0d9DEr{k9>gD6RW)Y%O9lWGx6So|pU z=TAU0laip(a2j~H1C?rcy-hhn#UxG=0vgSSlhHMgImA7ZBpJ_J>uom>oq*Y8eV(bb zE(2;PB6uVSG70~^&?FX#^Rb@6tkVXF<{>Gw9nYOnBGBVb(})YO7Pflcp_#WNT;A=g zJXUgSv)!lOMy)Idr^FaeRZO~rX73d8P!CzHWV(T&F-!qkh#^E1F>&n2Gx=eU$=)!2 z6lj9}(;R3#lf<_`GD|dxNr5R03QYk`+KtCe=Dq?$@6sZ4BNMva?4$ry)beIqca+BY z+P$po`}?N0mX(`39J%+7J9V3$Z*1-Cz{A5Cur!jF9sDpDEsw z?Y}g`^GAq_{_?1%A=01(O#kW|-zlg)X{zRhBa>RsWh*w$%_*@R8C$WlE|n3N7H8fy zm}2RIx~Nd1ij-h`Hkf~Grg0h|DeA%&=cswus!hXG=0-js&bp6x0$}41)K2Pd(_KJc zq5+~oyp9}FiTZ(heQUq-2eB#2#X)~4w;{UMLf84!3cW+r27S}OJQXJu5gz*^*H7F& z*{k-rf2xZMS|HJE)jVGBt|)o~36{wPgQLGhfC0J23 z>LTm+2do53$2vg6*j_T~6x4XriiRuO%?)(N6r;xUWAWsF&dPeN=Eqp2O)ak?F%NB;-i`eZ9kgo2f z-9?ZLzvxiHh>Sk@_-XjX&o-oF_E%JE?G_~U9}PAGhuHoQ!|dkO3klx>v=vB(oK4Ez z&R(u-ssFbdB;WYHmq5;7^c;Lhv@_rQ~aslihMhSd50aq~~g)5C7;IK8G8EBXv-nuhppyuc{(kz8CqqfPn-_SOVhRfp2} zL6Uj)O;xRn@D|LxRHj)yc54dj7U~kkw!WWaIY`lwC6X#lbd~2Nkq;Tk{h$L;)_%=x z-F{nit|i0k#++AKad>FsX~4f2*M;ji%`lyP-`L--PG*F({rJOUA3NpNMXJfE-gw0t z!^WpKwC_?E(X6}fTYh2ilXU;$uhN1V)y|d)?UL3EbPi6>B{U@O(%AW(j=}5zs!osf zx^vDzK9vDx;E$LuhQasqGU1h#&xd0SJ6VAjeK$zvprQ(9Nu1WsIpz4~LMH!Gix}e# zu>FfC0n&a#*8Zl`7y12kKIT>~PZZS3jYeJGpIkAwH#%IjT@eR>%P9q?gG6*anq9>4 z_5#%&TR{!xR%>}M*9>jB!`4@Xe zA9n#;tz=UGsaGkqty(8kRztR zZn?0otki=Vh3au5-r8sKJfzB6S(A{KknVAcVb?|Ttht?J7TXkc1KiEOk>ria7`9`d zbjc-Sv$u{ptlp^nTRFP@QkpYnF@FW~Kl!=j86HdG?4w^r56_NXE{qQ@FcwMZ9u&GC zZnByATa#Os&~3G81S8L)@z-EfGWc>v$tKi=H7ksjKvy^`_ZFw?Uw~wPz1=yBqsm1r zwskYk+$aTDP~i~#_E5&edI}gcBmGJ>`jF|%F}Zi$FZXk-wipX>mba9inx)P}-9}H} zn$f+woh_ydi`1FP!E~kV!n1C@-fy723MZR@rR9GGdUW>|w;DY8oSFRC#=wp%Yz6O$ zYHeMeI&`CW9)jjm>hu)~(2Hx~3H=mLQLRZ|WKV%#9{y4+#h>ujt|(BOVP7oaZWe^aq>dRK~op7!XAfcKb3vlWFQ` zYx|zu!NW_3D83|7Z?09MibkCt?Qo^56)M$nIQ5UhRC%$b(P8(@T$8XeV-r|9VVR%; zXz0{SI-yZep%y34hK+tBEYmJ|)Fv+ze@L1^Ow#!Tjr&^VWzDBjCO*FgE8d|>7!j$4 zc47h>VbTfpCJFOC?|XL=gmank;9Xn4FQs*4Qq=J=-elu-$PBY%Y0DOv5V4tVnws3L4Nx%`oOH(H+V+2sh|) zhN`$^i500R;%6h>9x}y?Rg?&eH4-K6QS?HFNSF^=*S+~qUkLDJSkVP{g|UWsBx<2J zE8$CapACCIMZb5JUH+0N2#=!0JR)1x_ZDsqCu(?T#)tgA_Mberf9yN8tPy-dZ;jB! z=X-cPKrsXk7Wp>-^k&`_B>;EHv%^vH7@xtTQ@uRz=$N{Kjq(O;Y>4^0t4ZHT2MaGU zQjgEW;=zuWWAMhb(7~f=nqajDTBb1X-!8rw@rvL@XR7*Bc?Zla<_bMmrsIv0Ysr-WjeUdF`F%We}`M%OzbUSeEWY#X?gS!8&!_(`|tDXz%ExcL>&_ zGJJ-o3&GR@&d3ML-AcrZc~VCNYvD3>_BvNY35y(vyD5Ze|L! zDIw(cG5zFub{JGgHhSwY)-4&liWGK=kqB z0xx`X8GnQC$Ya6Zl+T2}Dw_mDIk=&)BuuL`4Gd*+X_iT*ExXK^nO)e41(POj zr!dKwB!z|2b84~d$YzpBJ3T_|D8_Q)o#ji^?LpGL{&12k>)S2}l;qn)QUD)d5VFlC zW@Oo5U&npu-NJzVfDK9fy7=$<09MM<)w9o4P4fHJx~MbFyet<8NJie)BrqV-S1}G^ z!LCqT*`Pi63nC7zs>&;mcy^%OxkEF`tZL@Wm=La{PA<1)$w53j-}me{)ajKs@7ciZ z1Q^by21y6McIT?e>!R&&zLNX*m)w!;xC@DEJghoSM3~NO**=NE>IS~uWx@%L>haa- zyc0>~b;(2cerVm>-;;H(@X7%-cmbd;4*>L~Nhi=JW=RV-77H;kqWTzxWx!|yT~T(A zQEpqp&%A}sg1Zj;;i2=fxhTpXeDr%waJeWdR&e=KMQKDfL3vV&6RJ>YVVyo?fl{D1 zp%f=f$sA0{0!+ygOvwsN$q1A6It#jnu4-cp&3NEiKftx(f~&=XtEGUerGl%a!IY!X zx`mTFt*I~FH?*-^8{_z^AZ=4%%~-VW)t0JL)0{Hy3el%vGgn-G9k0<2$hFYfdUqOP z1p5P(TCxuaB$}xjxWzkaAtf-01mVN@AKf)-hGSP{lQff?4Dwz}Z@+V^%8cWn^d)(S z1gh&)nX&&YJwMpme;?j27c_cFP87X_WIiS~#($6K98c=?+>08Z8oY6hyG^_^B=T^E zr0v+hv9NzXIY-6~rv3ziOQTEdVUPdnBQzYA#hoc|#?*9AP^9&*QD7 z-M_st)xyStqu7af4Rv2luRHR|WsU)-LiA?~*w zm!YRZaOvQlN2d_JDq1KLVIqPgNsq9ZvbLRpJq6g`_SxAxG*NDWUVz_j(k%2A-Fjov zJS#d~M`WKSec+*TORi>hhyiC~e6_~vy~+qG`~qT`*E8R6rcrF{Lq5{|Pfsw4I8Ej{J1*12kJ?b$*azRs1H5#DjCz*g|!XpDfq~| za#wbcsnrStRp(j|#$F;Zk=Ko5Q~t5P$PgE75;eJHfN^vL#6yHUJtEuG?R?~@TN{`c z?2CcA-8nw6e6@*jr`Rq_PQ(11EcqFH+o&zoy0liI>PmUX$sdb(sAMhvN#BmDEB7OK zQVO-LeXxh_>CcT~66nHP0OttTx|qCu3tFjH`O92{MP&@7B32cQJDs7apR{uiAk(2u zG*>=%dI5(8JH|BMp|%PP@_|o~EaV*U9cl>wz13xD{|}IY?g<|Fm$^SCvIt1X5)sR8#FgD!=tYZKmMzQ;L0y52j7=7LYkr-0 zTGCDy3tl1+Zj_sVnd|QEk_cPA_<}>-TSm48@giau-8x4D^!uqZ)6L854KXb~D{!{s zJCh2v-Ptct^$E}FgCHw0)qPL9#oDS3?G-wJ8VR;z8TZA3f`v#iyXGH8?${P7RY-86 zrb7&e=JwV${0SH_UgQ0zUDq7+7B%`2iGX+962x>cO2HMP#YY%hjJ6I}0bA87(TNvl zz)!%3EmA%OBq=U^>rM)tLGMozuZ8E_7gg?@1taf#?-($vg!IM1D-z9=4eS^Xsad>8 z{ou%!rwzI=e2P~-3d#*A83=90pI=!pCHYXh^75HzRbnh~N@1#|AX-5wBc$eAAZ#{k z`aX>+4kNqLnj*^nIwxfcHU&&DTfa@HGwXYVA#SCyn^ux59|2dRVQz+Uc@1M>7Q8;R z^!$1#gCPgNPG70*R@kXU$GngGmmr5r`h~eQQ0-rX7eT;s#)_trdQO!DcmhJk{z5rz z-)Q~TG5`VO1f0@;LOE8hwhsS9!($HJKhZE%%mVUnBVNGl%?9+Ht1wVFXg$P9({v4j zp}|}fotGF*&lq5!F*Zw%$N}BZ_G?rQWh18eMeML)ycom2m%5KF4yAif#`4n4JXUnB-lsET1o*_2@oX3Ed3{x2B1oX!0zxWpNUK! zkvLvVMycT3Gw=DW2Dy_3kE+bG5EEDNO5nXb3VcCiQfxoBoY%K~R1$qOhfUnOTEXoz zTFYylVJXcc1l2HL};wxJgx+u7;9WFlD$y3_X5tD@^JpQc`iJ?%n|SyoEm3*~{r=xHa)u(I#} zpdX#&yD&TUuDc|HKYKEM#&ss$m^GNlo(|QD(uowHFP|F@`t2fnS4)d8^$>|NXw$!S zXJ6@b^x&W<$F|@jv@lI(%u!9Mu!~qe>$A9y0)Juk#iOAlV}s-`wD2D7fc>z^W5GVj-V&4wC1uVY zbuLYi2DLFMQA$ivG43)Z-$S!ji$M*e``GD0tp!>{*kN&c_1Am4!yR6s&@kBE-C;+` zFc>WjmI6x<`PiRwdS9ZzQ2u3HUBa&!QVk!4yMR6@o~#p;3Yi-{a#ec7#i=KMP@NyG zESxw~+z>nJWL3cMB6D_$YVC@!_)57rr+Sn2upoc&ApdiLSgqV#lLDUR^VcSd2mz0j z8^$U`2qE`vH%5!`@DReEnE@-tNI^HG1W%Ru&=mg7wBx4Zi-zYH7sW^zA;D+{becq1 zI;g`x4gq8awj%hvAmqIWUNugQxntrHAyjj&HE51%(~5d%f*rr?1MzT z+?UJ1Y4I*JP2F;|TAwAjO9v*}tD*Hf7vaO0YL*)qFS;>*9>|4*?@?*{hAOOKk-iLd`g%cPoz;O29DsQ#BR@6%-R1pLro!igr%J zPqTL7>IcH!^;}})@9e3Pr>353mS4yK%8`=h_k>bw;yva|P#;hGKrB?R zRBTe&YD#ZA3rBre)KX%A?*6AWm;(TknhZqHATaFopUKA7()r&q`wvjQ^vBA#z7uZ& z+&{i}EO+K+&vX;l!Qpn|gB)2VDLYo|BxjkDBX{NdCs_#_-HwK)XqhAG!H80=^z44u z0P+HSAV35!NQxcTn#&Du6RAXkvznopM zE80M1(*EE&V?n2X46V_RT_-R?2H%W!x1XS6%d`J*##HrLJ&COh=`Hcazd#E>nw`UL zeqcGM+owx2nbD+Ohx7It*wA}GQ34pdbo)8ZM!#Nb1^s{$_Yh1^ zzp>_^H>8NmX^4Mi1Q$rXSJo)mIU02?rqSq(?1>N17+1gT_V;>uxuNs9;822tK5PdR z0rw#^OqeVJ>B1hJ!zc!674RZ@4TgScz zj6%0*fJW8jQxH&_%uLLw=Ln(qRL`M}yPD^eXEXOrI1C+Ek0Mw*O>dd&l$Oy|t+=cb zwl%%ir2-T$10!f(1r`k$=mEoi2}pJ5`rx?T-CSSq107$dFRw0jur+zPd^KPb+QFz@ zj7){X_1g8b{8*-EzzE1+&I7IlgCAii`HcnvO*OyD=pli`mIzEM;g!wjf^5V8`xA@> zly8IqfVhj*{S(TBp5^fpTwPdW^|S?dH6QW|3g-)z*XRLKDiySb)a$g0MgO3O7Z+#~ zK4w4AYUOG1?NarfsiQlEe3HL$_^P&7Ke4uExic-o4o0TV-%a|9n)7HwQeqtR-Q@H^1B>B?xAK!_b+6F|=u07juLVBbS^ z<3cb%UpX3&(Yf-};RV#FOGnH+Fi%bxoC))1GN!7#Xlwnb-ZVk`v2W9OeD-L(+v!zt zXHW#?4j6(V_oN>1Xd1$xh9(`5aMk$X)*OQg4hL@S+$WY5MoEo|GAjjPm_2VM96HeI z1MD@Q*J%hXn~v5qrVSlSAtS+sBD!Vobjpx&V<-%$?qU)T4UTh=-OIHo4QqHAdJ`I= z>N|ltuIco`D1c(NMU)#aYA;yO{_vk`z1i6{N0wcBqQpJhrlxKgFZD;5vuG2=(QtA5 zVJ7E!z^>!4?V)e03fnJp+JFfuCsQz6p4|+;AvY1-@tJjW92kgYKI!UpB{GObUS~Z> zbOUH%_ADJVDz9Kg^zJQ*6V=MK7vnaL@u zDDJF@891P)A>V9a)eHqbvSn|D*zAf;GFpit2-t4E1Up$e_pyK-a7Ntfl%~b{qTBL1 zS-`q{-ZRgf+*bH5*U3_sn#DF1DAiXi4Jty}HG=Kub70k|KNqr+i;;%!_(35{9}07 z96sYq8YG$LpI)x>lmBZ!7bJU^Jov5Mx>9lH>*yM_OFR3y?`;hhj`+l(9V%?UyEvKM zbPIuSfwAM4AEMB6rMA#X8Mzva+Cy*(7Sit^{*x2wnKTvp`4j0!xE_VxNAF(27|DS$ zsr)P0&PVEArlXui$!Iyt>8g;G6$C5G)JA-s?W^5;r)@_%&! zXr>3U$n9Tr@AK=P0n+fN)$rw-)40hivD5<K`PW0kPBE0iVm~P%7w340!N) zVe)>7Ir$QzKXpE0<2&p^zk;{rb$q2oe2PjYSKFSpab3qxwC^I*juMZ&Y?l3iSjd&m zXS=2MZz!WxbN@6F@1pFW;M%v1Fm4h?C(U!E_; zp{O9~%1Mm$D3DfN-DUvL9=rAet?sP)(fX(=ID$lcrJyk7o8mWn5<;n{2WfoS;1 zuDp>%x;)$<%Z0x!DSjrCl-J!N=UklsxN?w?XfxAZHEf`p6Qo!qAg{lD;RY~ug~}YM z>smTIf}>n|gcr)uZljT%shj)*aXs6}8t})hd+6S7w1-`TZp#I&ehU`9i45}!*P=8& zR9fCik#dr-A+=h2)+eAQ5kX;X$+i#Q zL8p$>1Dm1;?=1n__vwe37Bo`AzI1s?@I#+(AGmlhjxY5}1x%G$U z5D^n32!8$(fh4UFm@64UB&`rcQq3WdcFM#zg>$2o0DIh(=huY(QHp88KR>WqgJ&T~ z8@4RRQv86pP8ow$gzFfYkQRg>Ni`$L+$J!iV^kn~v@|`(TlRum-DT4YZncRE=eTE{lM(Z)fxA9L8_8bsr?DRZ;26Nz1pr?XHHqOv6TN%sVbTuDVoac_l--WOh6O(yS1C z^Wm zM=X;(64Pgl&$)CYo;$AN_>o{>{C79Nln z4%sl%p9)G1p1yr*ZRW2ah$evfIJcCqUX`7%Pb0b;*uBJ!w^3cypo=7)3tTLOA2o{T zhPO@hgZkZ@9Cpc@?7h4b$-{%QKImyvn68(1{pG3H%fa(Kk+W-BoY3n|e9GoRc^cPd zcF}r5O|qFfllm;9k@vD0MP@l`86X^dt|so*#JN=Nrw@D78F@f%D^2DV#6gnq6je*R zu7%R#o9Ht>q%;TOhx-7%C-4F&3jw;64HdJ>Q+!(vKWCiMb&%13YIW5EE`Cfcux9A{ z$8sPA?I~Bs+HtC8n5kgpT zJZi>52?0&K$HJ3uf&nz$|x#|R>%SwaOALl%wl*#2 zFRaVPRzeT9Y|wOcLn|S3+%}N(dy1g zNjk?MI2_O=#L*=l{M4WwQ$Rsc?%LPnYm)>ZWItZ}3w@z#W0z03nr+;^RR!ITMy_LT z9ES%nbce4+Jd+>b`z9RZj*v$*5~)u~Aw@nxjH3#q61K2u<1dGA=6w`HL}ZE^A+ny5s-C$8L<@aVC!=5C|0+}$oSWr>T$sPKy-`4`pHdk0gh;;S3C5|6t zCX$?p)hbo)} z$IMKE$48zyJi~ECaUf#&9vsUn{h&BJM7dAZORdAdj`3+*IorRqyfTxmmbe=_=v2K@n->MqrRmaubk9S-xKiMiS#!_MIv?~v_9xFF4h;(<# z9xX3<8>Nv7dZuU9aE*S2U~V1oA7;L5cVMq)a@Uy8gp1qVPa6n0NI_D7|jt~v70o4Hey_&9U1qXjhBQ?b3SzE?xg*lMS^OU=Ysc|vn z!!>y2>Aa#QR}`e6UN<|_*ASq95uY3sKN`pkn2yOpX2C3s3+aL`Ob#*y=5RL&A+Kmz zfd8VWJr3KB~C_(R6%@JF`}CGYFb4h}6K1R$U#gajmXIwAvPptBHJAPenG zxPS|tgUAj^;-KQu{Cq~%Uezj6g{|mQ&*HS@OC|SuO6&w`9*hr+)hKvBK0sZ(5919q zB=}&)J2Kl)LIwd%heLw|(u2N7^Gea4M*45JA#g(Anm-N>aA*M`00B)QB#8k>@0?&AXX&v96R?tl~N-F;Y% zq%1v!&m^kTtk9&iN`G~-sxe{mU3b^W*+IuPrBC_KjjdjVs}LIvMvrM(inp zkw8jfB+@G_zt6obmb{nL%AShHu77AGB-gj54OE!fQ78q_F6|uDjvA?(2>iPBH9k-0 zLNK_|Oyft1*i}Fnji0{k?cX06#9L) zG=3qp*zhS68xuZ;KQlh-V>l}=s5L9rsgYsnCV9~smicpvZR>q#9gH1brEv9%8I5x2iTm(6!B7scAX`4HI+v0%6;Wl;T(B~K? zyF^)zvZXahW5RTFls*N;3?=M|THl*&iYcZd&FfT)UfO_c`i1wJRuXzmM`sN~Ayee> z(O~oUHPp?HB&oU6i?=?N-$Im=lZK&$$@WC8S&`;7syiGy;Osk&26(1}ll9psU?^m_ zZ(e?j1Bsx&rd%&xK;B*n%Kvg0Hh@9KxCz2giUz)O&Hvyq{LMAS|JBLy(E2yiOvtZ% z??NI>fBSl`=)KSNUWz9EfQn62y=N9n`7_^6urcKp3vOgHCC}lU#hR8bvPf)~P<NB77JXuKL9he`2|vR>x#F$a@~0u;TM%z)s>v z-Gyh0JVaE&)*!cu2sY2TOGL2Elb4DJwiNIR5y3V~o+TjI{*>2<2u`urc$l@E%@oV6 zf0`(E?Yn)v5cdD1#6W4eo_Na_iD@4`V3Wd|?hw%ybwy%RV~a9W6=REX{5u5x9TNTy z1*&59gJ`BQ6CE0VzD7`KQm%tT=n6vdvFA6a@>EF`v1S($Hw0Lza&qPQvQvJA-_Ea6K19-1J(_R8_)RY81Y?V zL<|U`b`2R3@7~z+x-EP=qMyVA0Wc2R&F5Z?Ht#86gwzQ_|&4=gx%CP zC@NbkP{V{qzNsnHAB?f=I-1XJ1ioRtyi6G7>&zmIP>^O%IT2 zM1Zpx-JtAhRK$4Zvs{}d@iSM%cus#}R~KhRP2g>By+aL3L7M6?7iEPuu__K zbi2}H7TDOjvaakmN1o5(~F{IDe%>`kQ0!6*_k5~ z<}{P3>Q#-Xk!TUw`(JuA`^9m$8jrHB?|RwulKiLGl^gb zg6M*+Mkwpko1yPiY?a(uB`2cDf&oZc+cK)#>)y`? z&1tf|6aqX_&_8iy6V_aM0|Dq>yvQBtl31+fq1PtLWC&^~JM<%Mno>wrZ)8Om0H?D+ z3@qQ%JoK&llRgeWFpm1O;CrIc{<8*iFf_LQXQqXqO8+gvRQiAj%>I(Q6jZNgw!wW9 z!!YEaO;1W)Om~>V9PDg&$WEn%w8_k7TA3k9$;Gm+DP^1v8aiy8S{vD+8GcU#hC)-@ zI(+s>5$R*=mu5;9XMVsjvEpAbA0PzeiNyUT2pw@TCyRrS+&^58Yiv1|SKaQkqZ!LQ zSTJmAQP7Yq^gZsoco7=PhcBGQV5e zszsNaoDieNY_jHN*K=8U>>g7alFbX>x*i`dBU+Wp;BK!nTWhzKqq1}LjYev9zSHkq zQPK8X_{7|JO2;d5HUr!7=Xv+fs$f6xgnHt*Dr>e>=rPrKzQcM&7wDw>rH*I7rfbg3 z4{M3IyYv-^+LR8Mva~a79d21|$tssX8V5d{pu#WBAu^4GK6?@TZM;)sU%6^*gcrS1 zx6|e-;ew??;lt4sP|&246-ty+8v-R@<&+urNeNYU3AC;wqjFRDbCo8Xvw^W6EPBY~ zr7fz!U?}vrYCl6vpxf%3cwaZN5LQs%p@3AF;m&C&mmw9Y`tS|$uwRJ|r#PNEm=w14 zd>Ls-UzJg|V}?wTo8_Xi35aP}>x+^@k4jbOdytX*0mI@<(qM=6K=AGy6;fhUetis7 zKnl!)9xj5P_}6Fc!4Kp7K9JEM9qGf6`@NRpsD_hKwsS2(NewhM#2P3XVgnQnaUEPh^W=zj z<2Om91}f49Dt279Vc06@@ZxaOQwVNMJRBcQw>VX{xvV3G7|P}$#1c04Ids4}s32QX z7US~X)tpOB9-fHqng*qo^H{{RO3@xCH)913!7_(sd#8s2`p`S z#wRb}x=(^{&1%&K=|Z_m4y$6}=$FBFW8qgmrV0})1{PK-Ywjd@=&Cy{8^A|12}n~{ zt*TrtN%)PH9?vsCK>~J~P4wshN)9wL)%0W^%&S*_ijoc(DE-cVgCAjrQ$~ZUYj(YG zQfzn52&Y<i2(ja0yk7G3(x>5r9{iJ1UweGqN*W5j